diff --git a/modules/base/pymod/table.py b/modules/base/pymod/table.py
index 87a425ebcf9e61852e8709ca26ab6bee526b0ce7..8258ad31685fa817326a89bf0243e9fef3b22b58 100644
--- a/modules/base/pymod/table.py
+++ b/modules/base/pymod/table.py
@@ -926,7 +926,10 @@ class Table:
           vals1.append(v1)
           vals2.append(v2)
       try:
-        return scipy.stats.mstats.spearmanr(vals1, vals2)[0]
+        correl = scipy.stats.mstats.spearmanr(vals1, vals2)[0]
+        if scipy.isnan(correl):
+          return None
+        return correl
       except:
         return None
 
@@ -1252,6 +1255,11 @@ class Table:
             fp += 1
     x.append(fp)
     y.append(tp)
+    
+    # if no false positives or false negatives values are found return None
+    if x[-1]==0 or y[-1]==0:
+      return None
+    
     x = [float(v)/x[-1] for v in x]
     y = [float(v)/y[-1] for v in y]
     return x,y
@@ -1265,10 +1273,12 @@ class Table:
     try:
       import numpy as np
 
-      rocx, rocy = self.ComputeROC(score_col, class_col, score_dir,
-                                   class_dir, class_cutoff)
+      roc = self.ComputeROC(score_col, class_col, score_dir,
+                            class_dir, class_cutoff)
 
-      return np.trapz(rocy, rocx)
+      if not roc:
+        return None
+      return np.trapz(roc[1], roc[0])
     except ImportError:
       LogError("Function needs numpy, but I could not import it.")
       raise
@@ -1284,8 +1294,13 @@ class Table:
     try:
       import matplotlib.pyplot as plt
 
-      enrx, enry = self.ComputeROC(score_col, class_col, score_dir,
+      roc = self.ComputeROC(score_col, class_col, score_dir,
                                    class_dir, class_cutoff)
+      
+      if not roc:
+        return None
+
+      enrx, enry = roc
 
       if not title:
         title = 'ROC of %s'%score_col
diff --git a/modules/base/src/string_ref.hh b/modules/base/src/string_ref.hh
index 48ab841055192522f2068cc91a4df79c97ac20c1..802dd594069257ba17213a02d73144018e635b32 100644
--- a/modules/base/src/string_ref.hh
+++ b/modules/base/src/string_ref.hh
@@ -28,7 +28,6 @@
 #include <ost/base.hh>
 #include <string.h>
 #include <vector>
-#include <ost/message.hh>
 #include <ost/module_config.hh>
 
 
@@ -60,8 +59,9 @@ public:
     assert(!this->empty());
     return *begin_; 
   }
- /// \brief find character in StringRef
- /// \return iterator position when found, else iterator pointing to the end 
+  
+  /// \brief find character in StringRef
+  /// \return iterator position when found, else iterator pointing to the end 
   const_iterator find(char p) const {
     const char* s=begin_;
     while (s!=end_) {
@@ -72,7 +72,7 @@ public:
     }
     return s;
   }
-  
+
   /// \brief returns a substring of the string
   ///
   /// \param pos the starting position of the substring
diff --git a/modules/base/tests/test_table.py b/modules/base/tests/test_table.py
index 4220de12fd65d5caa7d83b7d8a9973916dee24b4..e2a3060c62ae341f9f822a6d76403bd29e0cf8e5 100644
--- a/modules/base/tests/test_table.py
+++ b/modules/base/tests/test_table.py
@@ -985,7 +985,15 @@ class TestTable(unittest.TestCase):
     img1 = Image.open(os.path.join("testfiles","roc-out.png"))
     img2 = Image.open(os.path.join("testfiles","roc.png"))
     self.CompareImages(img1, img2)
-    #pl.show()
+
+    # no true positives
+    tab = Table(['classific', 'score'], 'bf',
+                classific=[False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False],
+                score=[0.9, 0.8, 0.7, 0.6, 0.55, 0.54, 0.53, 0.52, 0.51, 0.505, 0.4, 0.39, 0.38, 0.37, 0.36, 0.35, 0.34, 0.33, 0.30, 0.1])
+    pl = tab.PlotROC(score_col='score', score_dir='+',
+                     class_col='classific',
+                     save=os.path.join("testfiles","roc-out.png"))
+    self.assertEquals(pl, None)
 
   def testPlotROCSameValues(self):
     if not HAS_MPL or not HAS_PIL:
@@ -1011,7 +1019,14 @@ class TestTable(unittest.TestCase):
     auc = tab.ComputeROCAUC(score_col='score', score_dir='+', class_col='classific')
     self.assertAlmostEquals(auc, auc_ref)
 
-  def testCalcROC(self):
+    # no true positives
+    tab = Table(['classific', 'score'], 'bf',
+                classific=[False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False],
+                score=[0.9, 0.8, 0.7, 0.6, 0.55, 0.54, 0.53, 0.52, 0.51, 0.505, 0.4, 0.39, 0.38, 0.37, 0.36, 0.35, 0.34, 0.33, 0.30, 0.1])
+    auc = tab.ComputeROCAUC(score_col='score', score_dir='+', class_col='classific')
+    self.assertEquals(auc, None)
+
+  def testCalcROCAUCWithCutoff(self):
     if not HAS_NUMPY:
       return
     tab = Table(['classific', 'score'], 'ff',
@@ -1020,6 +1035,10 @@ class TestTable(unittest.TestCase):
     auc = tab.ComputeROCAUC(score_col='score', class_col='classific', class_cutoff=0.5)
     self.assertEquals(auc, 1.0)
 
+    # no true positives
+    auc = tab.ComputeROCAUC(score_col='score', class_col='classific', class_cutoff=1.0)
+    self.assertEquals(auc, None)
+
   def testCalcROCFromFile(self):
     tab = Table.Load(os.path.join('testfiles','roc_table.dat'))
     auc = tab.ComputeROCAUC(score_col='prediction', class_col='reference', class_cutoff=0.4)
diff --git a/modules/conop/pymod/CMakeLists.txt b/modules/conop/pymod/CMakeLists.txt
index 97de72d7a52f1a74233a9782e746bd596620ffc7..650939bfd9aea21dac1925adadf6866f4db37e65 100644
--- a/modules/conop/pymod/CMakeLists.txt
+++ b/modules/conop/pymod/CMakeLists.txt
@@ -4,6 +4,7 @@ set(OST_CONOP_PYMOD_SOURCES
   export_compound.cc
   export_amino_acids.cc
   export_conop.cc
+  export_non_standard.cc
   export_ring_finder.cc
 )
 
diff --git a/modules/conop/pymod/export_non_standard.cc b/modules/conop/pymod/export_non_standard.cc
new file mode 100644
index 0000000000000000000000000000000000000000..025d2819a100584c85f3b088ce5320fdf02d0762
--- /dev/null
+++ b/modules/conop/pymod/export_non_standard.cc
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#include <boost/python.hpp>
+#include <ost/mol/mol.hh>
+#include <ost/conop/nonstandard.hh>
+
+using namespace boost::python;
+
+using namespace ost::conop;
+using namespace ost::mol;
+                   
+object copy_conserved_handle(ResidueHandle src_res, ResidueHandle dst_res,
+                          XCSEditor edi) {
+  bool has_cbeta = false;
+  bool ret = CopyConserved(src_res, dst_res, edi, has_cbeta);
+  return make_tuple(ret, has_cbeta);
+}
+
+object copy_non_conserved_handle(ResidueHandle src_res, ResidueHandle dst_res,
+                          XCSEditor edi) {
+  bool has_cbeta = false;
+  bool ret = CopyNonConserved(src_res, dst_res, edi, has_cbeta);
+  return make_tuple(ret, has_cbeta);
+}
+
+
+
+void export_NonStandard()
+{
+  def("CopyNonConserved",&copy_non_conserved_handle);
+  def("CopyConserved", copy_conserved_handle);
+  def("CopyResidue", &CopyResidue);
+ }
+
diff --git a/modules/conop/pymod/wrap_conop.cc b/modules/conop/pymod/wrap_conop.cc
index 2aba86654fb077bc42751b173a5185f22bb18ffc..6573bf41a7e6c8fcb471cbf25a79be77b1b03dfa 100644
--- a/modules/conop/pymod/wrap_conop.cc
+++ b/modules/conop/pymod/wrap_conop.cc
@@ -25,6 +25,8 @@ void export_Sanitizer();
 void export_Conop();
 void export_RingFinder();
 void export_AminoAcids();
+void export_NonStandard();
+
 BOOST_PYTHON_MODULE(_ost_conop)
 {
   export_Builder();
@@ -32,4 +34,5 @@ BOOST_PYTHON_MODULE(_ost_conop)
   export_Compound();
   export_RingFinder();
   export_AminoAcids();
+  export_NonStandard();
 }
diff --git a/modules/conop/src/CMakeLists.txt b/modules/conop/src/CMakeLists.txt
index 127bd15ea7757eaaa50abeda7c7e07d3f295f3f0..344f5e00755d3ba733f1d6a877840037c8da802b 100644
--- a/modules/conop/src/CMakeLists.txt
+++ b/modules/conop/src/CMakeLists.txt
@@ -7,6 +7,7 @@ amino_acids.hh
 compound.hh
 compound_lib.hh
 module_config.hh
+nonstandard.hh
 rule_based_builder.hh
 ring_finder.hh
 )
@@ -18,12 +19,13 @@ conop.cc
 heuristic_builder.cc
 compound.cc
 compound_lib.cc
+nonstandard.cc
 rule_based_builder.cc
 ring_finder.cc
 )
 
 module(NAME conop SOURCES ${OST_CONOP_SOURCES}
-       HEADERS ${OST_CONOP_HEADERS} DEPENDS_ON ost_mol ost_geom ost_db)
+       HEADERS ${OST_CONOP_HEADERS} DEPENDS_ON ost_mol ost_mol_alg ost_geom ost_db)
 
 executable(NAME chemdict_tool SOURCES chemdict_tool.cc DEPENDS_ON ost_io STATIC)
 
diff --git a/modules/conop/src/nonstandard.cc b/modules/conop/src/nonstandard.cc
new file mode 100644
index 0000000000000000000000000000000000000000..620cd9a1d5ef2d90c23deb950486dc2be0e34f30
--- /dev/null
+++ b/modules/conop/src/nonstandard.cc
@@ -0,0 +1,265 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Marco Biasini, Juergen Haas
+ */
+
+#include <ost/log.hh>
+#include <ost/dyn_cast.hh>
+#include <ost/conop/conop.hh>
+#include <ost/mol/mol.hh>
+#include <ost/mol/alg/construct_cbeta.hh>
+#include <ost/conop/rule_based_builder.hh>
+#include <ost/conop/compound_lib.hh>
+#include "nonstandard.hh"
+using namespace ost::mol;
+using namespace ost;
+using namespace ost::conop;
+
+namespace ost { namespace conop {
+
+namespace {
+
+bool CheckBackboneAtoms(ResidueHandle res)
+{
+  String atom_names[]={"N", "CA", "C", "O"};
+  std::vector<String> missing;
+  for (int i =0; i<4; ++i) {
+    if (!res.FindAtom(atom_names[i])) {
+      missing.push_back(atom_names[i]);
+    }
+  }
+  if (!missing.empty()) {
+    std::stringstream ss;
+    ss << "residue " << res.GetQualifiedName() << " is missing atoms ";
+    for (std::vector<String>::const_iterator
+         i=missing.begin(), e=missing.end(); i!=e; ++i) {
+      if (i!=missing.begin()) {
+        ss << ", ";
+      }
+      ss << *i;
+    }
+    LOG_WARNING(ss.str());
+    return false;
+  }
+  return true;
+}
+
+bool CheckCalphaAtom(ResidueHandle res)
+{
+  String atom_names[]={"N", "CA", "C", "O"};
+  std::vector<String> missing;
+  for (int i =0; i<4; ++i) {
+    if (!res.FindAtom(atom_names[i])) {
+      missing.push_back(atom_names[i]);
+    }
+  }
+  if (!res.FindAtom("CA")) {
+    LOG_WARNING("residue " << res.GetQualifiedName() << " is missing CA atom");
+    return false;
+  }
+  return true;
+}
+
+}
+
+bool CopyResidue(ResidueHandle src_res, ResidueHandle dst_res, XCSEditor& edi)
+{
+  bool has_cbeta = false;
+  bool ret;
+  if (src_res.GetName()==dst_res.GetName()) {
+    ret = CopyConserved(src_res, dst_res, edi, has_cbeta);
+  } else {
+    ret = CopyNonConserved(src_res, dst_res, edi, has_cbeta);
+  }
+  // insert Cbeta, unless dst residue is glycine.
+  if (!has_cbeta && dst_res.GetName()!="GLY") {
+    geom::Vec3 cbeta_pos=mol::alg::CBetaPosition(dst_res);
+    edi.InsertAtom(dst_res, "CB", cbeta_pos, "C");
+  }
+  return ret;
+}
+
+bool CopyConserved(ResidueHandle src_res, ResidueHandle dst_res, XCSEditor& edi,
+                   bool& has_cbeta)
+{
+  // check if the residue name of dst and src are the same. In the easy 
+  // case, the two residue names match and we just copy over all atoms.
+  // If they don't match, we are dealing with modified residues.
+
+  //~ return copy_conserved(src_res, dst_res, edi, has_cbeta);
+
+  if (dst_res.GetName()==src_res.GetName()) {
+    return CopyIdentical(src_res, dst_res, edi, has_cbeta);
+  } else if (src_res.GetName()=="MSE") {
+    return CopyMSE(src_res, dst_res, edi, has_cbeta);
+  } else {
+    return CopyModified(src_res, dst_res, edi, has_cbeta);
+  }
+}
+
+bool CopyIdentical(ResidueHandle src_res, ResidueHandle dst_res, XCSEditor& edi, 
+                   bool& has_cbeta)
+{
+  //~ return copy_identical();
+  AtomHandleList atoms=src_res.GetAtomList();
+  for (AtomHandleList::const_iterator 
+       a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
+    if (a->GetName()=="CB") {
+      has_cbeta=true;
+    }
+    if (a->GetElement()=="D" || a->GetElement()=="H") {
+      continue;
+    }
+    edi.InsertAtom(dst_res, a->GetName(), a->GetPos(), a->GetElement(), 
+                   a->GetOccupancy(), a->GetBFactor());
+  }
+  return true;
+}
+
+
+bool CopyMSE(ResidueHandle src_res, ResidueHandle dst_res, XCSEditor& edi, 
+             bool& has_cbeta)
+{
+  // selenium methionine is easy. We copy all atoms and substitute the SE 
+  // with SD
+  AtomHandleList atoms=src_res.GetAtomList();
+  for (AtomHandleList::const_iterator 
+       a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
+    if (a->GetName()=="CB") {
+      has_cbeta=true;
+    }
+    if (a->GetElement()=="D" || a->GetElement()=="H") {
+      continue;
+    }
+    if (a->GetName()=="SE") {
+      edi.InsertAtom(dst_res, "SD", a->GetPos(), "S", 
+                     a->GetOccupancy(), a->GetBFactor());             
+    } else {
+      edi.InsertAtom(dst_res, a->GetName(), a->GetPos(), a->GetElement(), 
+                     a->GetOccupancy(), a->GetBFactor());            
+    }
+  }
+  return true;
+}
+
+bool CopyModified(ResidueHandle src_res, ResidueHandle dst_res, 
+                  XCSEditor& edi, bool& has_cbeta)
+{
+  // FIXME: for now this functions ignores chirality changes of sidechain 
+  //        chiral atoms. To detect those changes, we would need to store the 
+  //        chirality of those centers in the compound library.
+  
+  // For now, this function just handles cases where the src_res contains 
+  // additional atoms, but the dst_atom doesn't contain any atoms the src_res 
+  // doesn't have. It these two requirements are not met, we fall back to 
+  // CopyNonConserved.
+  
+  // first let's get our hands on the component library
+  conop::BuilderP builder=conop::Conopology::Instance().GetBuilder("DEFAULT");
+  conop::RuleBasedBuilderPtr rbb=dyn_cast<conop::RuleBasedBuilder>(builder);
+  conop::CompoundLibPtr comp_lib=rbb->GetCompoundLib(); 
+
+  CompoundPtr src_compound=comp_lib->FindCompound(src_res.GetName(), 
+                                                  Compound::PDB);
+  if (!src_compound) {
+    // OK, that's bad. Let's copy the backbone and be done with it!
+    return CopyNonConserved(src_res, dst_res, edi, has_cbeta);
+  }
+  // since dst_res is one of the 20 amino acids, we don't have to check for 
+  // existence of the compound. We know it is there!
+  CompoundPtr dst_compound=comp_lib->FindCompound(dst_res.GetName(),
+                                                  Compound::PDB);
+  std::set<String> dst_atoms;
+  std::set<String> src_atoms;
+  // to compare the atoms of dst_res with those of src_res, let's create two 
+  // sets containing all heavy atoms.
+  for (AtomSpecList::const_iterator i=dst_compound->GetAtomSpecs().begin(), 
+       e=dst_compound->GetAtomSpecs().end(); i!=e; ++i) {
+    if (i->element=="H" || i->element=="D") {
+      continue;
+    }
+    dst_atoms.insert(i->name);
+  }
+  for (AtomSpecList::const_iterator i=src_compound->GetAtomSpecs().begin(), 
+       e=src_compound->GetAtomSpecs().end(); i!=e; ++i) {
+    if (i->element=="H" || i->element=="D") {
+      continue;
+    }
+    src_atoms.insert(i->name);
+  }
+  for (std::set<String>::const_iterator i=dst_atoms.begin(), 
+       e=dst_atoms.end(); i!=e; ++i) {
+    if (src_atoms.find(*i)==src_atoms.end()) {
+      return CopyNonConserved(src_res, dst_res, edi, has_cbeta);
+    }
+  }
+  // Muahaha, all is good. Let's copy the atoms. Muahaha
+  AtomHandleList atoms=src_res.GetAtomList();
+  for (AtomHandleList::const_iterator 
+       a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
+    if (a->GetName()=="CB") {
+      if (dst_res.GetName()=="GLY") {
+        continue;
+      }
+      has_cbeta=true;
+    }
+    if (a->GetElement()=="D" || a->GetElement()=="H") {
+      continue;
+    }
+    if (dst_atoms.find(a->GetName())==dst_atoms.end()) {
+      continue;
+    }
+    edi.InsertAtom(dst_res, a->GetName(), a->GetPos(), a->GetElement(), 
+                   a->GetOccupancy(), a->GetBFactor());
+  }
+  return true;
+}
+
+
+bool CopyNonConserved(ResidueHandle src_res, ResidueHandle dst_res, 
+                      XCSEditor& edi, bool& has_cbeta) 
+{  
+  AtomHandleList atoms=src_res.GetAtomList();
+  for (AtomHandleList::const_iterator 
+       a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
+    String name=a->GetName();
+    if (name=="CA" || name=="N" || name=="C" || name=="O" || name=="CB") {
+      if (name=="CB") {
+        if (dst_res.GetName()=="GLY") {
+          continue;
+        }
+        has_cbeta=true;
+      }
+      if (a->GetElement()=="D" || a->GetElement()=="H") {
+        continue;
+      }
+      edi.InsertAtom(dst_res, a->GetName(), a->GetPos(), a->GetElement(), 
+                     a->GetOccupancy(), a->GetBFactor());     
+    }
+  }
+  return false;
+}
+
+
+
+
+
+}}
diff --git a/modules/conop/src/nonstandard.hh b/modules/conop/src/nonstandard.hh
new file mode 100644
index 0000000000000000000000000000000000000000..f8ad1cfa33d07b8d4c51db0b9019de340a882163
--- /dev/null
+++ b/modules/conop/src/nonstandard.hh
@@ -0,0 +1,97 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+#ifndef OST_CONOP_NONSTANDARD_HH
+#define OST_CONOP_NONSTANDARD_HH
+/*
+  Author: Marco Biasini, Juergen Haas
+ */
+#include "module_config.hh"
+
+
+
+
+namespace ost { namespace conop {
+
+
+/// \brief copies all atom of src_res to dst_res 
+/// \param has_cbeta will be set to true if the src_res has a cbeta and the 
+///      dst_residue is not a glycine, it will be inserted if in the dst should
+///      be one and in src it was not present
+
+                             
+bool DLLEXPORT_OST_CONOP CopyResidue(ost::mol::ResidueHandle src_res,
+                             ost::mol::ResidueHandle dst_res, 
+                             ost::mol::XCSEditor& edi);
+                             
+/// \brief copies all atom of src_res to dst_res
+/// \param has_cbeta will be set to true if the src_res has a cbeta and the 
+///      dst_residue is not a glycine
+
+                             
+bool DLLEXPORT_OST_CONOP CopyIdentical(ost::mol::ResidueHandle src_res,
+                             ost::mol::ResidueHandle dst_res, 
+                             ost::mol::XCSEditor& edi, 
+                             bool& has_cbeta);
+
+/// \brief copies atoms of src_res to dst_res
+///
+/// src_res and dst_res are thought to be conserved, e.g. the parent standard 
+/// amino acid of both residues is the same. This includes cases where e.g. the 
+/// src_rs is and MSE and the dst_res is a MET. This function automatically 
+/// tries to do the right thing an keep as many atoms as possible from src_res
+
+
+                             
+bool DLLEXPORT_OST_CONOP CopyConserved(ost::mol::ResidueHandle src_res, 
+                             ost::mol::ResidueHandle dst_res, 
+                             ost::mol::XCSEditor& edi,
+                             bool& has_cbeta);
+
+/// \brief construct dst_res in case src_res and dst_res are not conserved.
+/// 
+/// This essentially copies the backbone of src_res to dst_res. The CB atom is 
+/// only copied if dst_res is not equal to glycine.
+
+
+bool DLLEXPORT_OST_CONOP CopyNonConserved(ost::mol::ResidueHandle src_res, 
+                                ost::mol::ResidueHandle dst_res, 
+                                ost::mol::XCSEditor& edi, 
+                                bool& has_cbeta);
+
+/// \brief construct dst_res from src_res when src_res is an MSE
+
+bool DLLEXPORT_OST_CONOP CopyMSE(ost::mol::ResidueHandle src_res, 
+                       ost::mol::ResidueHandle dst_res, 
+                       ost::mol::XCSEditor& edi, 
+                       bool& has_cbeta);
+                       
+/// \brief construct a dst_res with only atoms matching the standard aminoacid
+/// from src_res when src_res is an is modified
+                            
+bool DLLEXPORT_OST_CONOP CopyModified(ost::mol::ResidueHandle src_res, 
+                            ost::mol::ResidueHandle dst_res, 
+                            ost::mol::XCSEditor& edi, 
+                            bool& has_cbeta);
+
+
+
+}}
+
+#endif
diff --git a/modules/conop/tests/CMakeLists.txt b/modules/conop/tests/CMakeLists.txt
index 1af92df10be705d46354506d72df5c0c645be732..6a832115b5933b66241c9dec5ce23c21dd532c48 100644
--- a/modules/conop/tests/CMakeLists.txt
+++ b/modules/conop/tests/CMakeLists.txt
@@ -5,6 +5,7 @@ set(OST_CONOP_UNIT_TESTS
   test_builder.cc
   test_compound.py
   test_cleanup.py
+  test_nonstandard.py
 )
 
 ost_unittest(MODULE conop
diff --git a/modules/conop/tests/test_nonstandard.py b/modules/conop/tests/test_nonstandard.py
new file mode 100644
index 0000000000000000000000000000000000000000..57de3864e87575ffde1c7bdd705b5549f488fa31
--- /dev/null
+++ b/modules/conop/tests/test_nonstandard.py
@@ -0,0 +1,127 @@
+import unittest
+from ost import conop
+
+
+class TestNonStandard(unittest.TestCase):
+ 
+  def test_fastModified(self):
+    # phoshoserine: test if we correctly strip off modifications
+    tpl=io.LoadPDB('testfiles/sep.pdb')
+    new_hdl=mol.CreateEntity();
+    ed=new_hdl.EditXCS()
+    c=ed.InsertChain('A')
+    ed.AppendResidue(c, 'SER')
+
+    err, has_cbeta=conop.CopyConserved(tpl.residues[0], new_hdl.residues[0], ed)
+    self.assertTrue(err)
+    self.assertTrue(has_cbeta)
+    residues=new_hdl.residues
+    self.assertEqual(len(residues), 1)
+    self.assertEqual(len(residues[0].atoms), 6)
+    self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "N").IsValid())
+    self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "CA").IsValid())
+    self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "C").IsValid())
+    self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "O").IsValid())
+    self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "CB").IsValid())
+    self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "OG").IsValid())
+    
+    
+  def test_CBeta(self):
+    # test if the dst residues contain cbeta, unless they are glycines
+    tpl=io.LoadPDB('testfiles/cbeta.pdb')
+    new_hdl=mol.CreateEntity();
+    ed=new_hdl.EditXCS()
+    c=ed.InsertChain('A')
+    ed.AppendResidue(c, 'MET')
+    ed.AppendResidue(c, 'GLY')
+    ed.AppendResidue(c, 'GLY')
+    ed.AppendResidue(c, 'HIS')
+    err, has_cbeta=conop.CopyConserved(tpl.residues[0], new_hdl.residues[0], ed)
+    self.assertTrue(has_cbeta)
+    self.assertTrue(err)
+    err, has_cbeta=conop.CopyConserved(tpl.residues[1], new_hdl.residues[1], ed)
+    self.assertFalse(has_cbeta)
+    self.assertTrue(err)
+    err, has_cbeta=conop.CopyConserved(tpl.residues[2], new_hdl.residues[2], ed)
+    self.assertFalse(has_cbeta)
+    self.assertTrue(err)
+    err, has_cbeta=conop.CopyConserved(tpl.residues[3], new_hdl.residues[3], ed)
+    self.assertTrue(has_cbeta)
+    self.assertTrue(err)
+      
+    residues=new_hdl.residues
+    self.assertEqual(len(residues), 4)
+    self.assertTrue(residues[0].FindAtom("CB").IsValid())
+    self.assertFalse(residues[1].FindAtom("CB").IsValid())
+    self.assertFalse(residues[2].FindAtom("CB").IsValid())
+    self.assertTrue(residues[3].FindAtom("CB").IsValid())
+
+
+  def test_CopyResidue(self):
+    tpl=io.LoadPDB('testfiles/cbeta.pdb')
+    new_hdl=mol.CreateEntity();
+    ed=new_hdl.EditXCS()
+    c=ed.InsertChain('A')
+    ed.AppendResidue(c, 'MET')
+    ed.AppendResidue(c, 'GLY')
+    ed.AppendResidue(c, 'GLY')
+    ed.AppendResidue(c, 'HIS')
+    ed.AppendResidue(c, 'HIS')
+    ed.AppendResidue(c, 'GLY')
+    ed.AppendResidue(c, 'HIS')
+    ed.AppendResidue(c, 'MET')
+    
+    # MET to MET
+    err =conop.CopyResidue(tpl.residues[0], new_hdl.residues[0], ed)
+    self.assertTrue(err)
+    #GLY to GLY
+    err =conop.CopyResidue(tpl.residues[1], new_hdl.residues[1], ed)
+    self.assertTrue(err)
+    # GLY to GLY
+    err =conop.CopyResidue(tpl.residues[2], new_hdl.residues[2], ed)
+    self.assertTrue(err)
+    #now we copy a HIS to a HIS
+    err =conop.CopyResidue(tpl.residues[3], new_hdl.residues[3], ed)
+    self.assertTrue(err)
+    # copy a GLY to a HIS
+    err, has_cbeta=conop.CopyNonConserved(tpl.residues[1], new_hdl.residues[4], ed)
+    self.assertFalse(has_cbeta)
+    # copy a MET to a GLY 
+    err =conop.CopyResidue(tpl.residues[0], new_hdl.residues[5], ed)
+    self.assertFalse(err)
+    # copy a MET to a HIS 
+    err =conop.CopyResidue(tpl.residues[0], new_hdl.residues[6], ed)
+    self.assertFalse(err)
+    # copy a GLY to a MET with adding CB
+    err=conop.CopyResidue(tpl.residues[1], new_hdl.residues[7], ed)
+    self.assertFalse(err)
+      
+    residues=new_hdl.residues
+    self.assertEqual(len(residues), 8)
+    # MET to MET
+    self.assertTrue(residues[0].FindAtom("CB").IsValid())
+    #GLY to GLY
+    self.assertFalse(residues[1].FindAtom("CB").IsValid())
+    #now we copy a GLY to a GLY
+    self.assertFalse(residues[2].FindAtom("CB").IsValid())
+    #now we copy a HIS to a HIS
+    self.assertTrue(residues[3].FindAtom("CB").IsValid())
+    #now we copy a GLY to a HIS without adding CB
+    self.assertFalse(residues[4].FindAtom("CB").IsValid())
+    #now we copy a MET to a GLY
+    self.assertFalse(residues[5].FindAtom("CB").IsValid())
+    # copy a MET to a HIS
+    self.assertTrue(residues[6].FindAtom("CB").IsValid())
+    # copy a GLY to a MET with adding CB
+    self.assertTrue(residues[7].FindAtom("CB").IsValid())
+    
+
+if __name__ == "__main__":
+  builder=conop.GetBuilder()
+  if not hasattr(builder, 'compound_lib'):
+    print 'default builder does not use compound library. ignoring unit tests'
+  else:
+    suite = unittest.TestLoader().loadTestsFromTestCase(TestNonStandard)
+    unittest.TextTestRunner().run(suite)
+
+
diff --git a/modules/conop/tests/testfiles/cbeta.pdb b/modules/conop/tests/testfiles/cbeta.pdb
new file mode 100644
index 0000000000000000000000000000000000000000..fcb59f778ba67b568a83c99605d14f3c8cdc96a4
--- /dev/null
+++ b/modules/conop/tests/testfiles/cbeta.pdb
@@ -0,0 +1,27 @@
+ATOM      1  N   MET A  55     -11.301  11.863  12.812  1.00 46.35           N  
+ATOM      2  CA  MET A  55     -10.174  12.241  13.713  1.00 45.84           C  
+ATOM      3  C   MET A  55      -9.595  11.051  14.465  1.00 44.35           C  
+ATOM      4  O   MET A  55     -10.219   9.989  14.526  1.00 46.54           O  
+ATOM      5  CB  MET A  55     -10.591  13.367  14.670  1.00 48.03           C  
+ATOM      6  CG  MET A  55     -11.911  13.150  15.404  1.00 49.20           C  
+ATOM      7  SD  MET A  55     -12.173  14.422  16.660  1.00 55.85           S  
+ATOM      8  CE  MET A  55     -10.955  13.907  17.875  1.00 52.51           C  
+ATOM      9  N   GLY A  56      -8.383  11.240  14.995  1.00 42.02           N  
+ATOM     10  CA  GLY A  56      -7.611  10.243  15.755  1.00 39.04           C  
+ATOM     11  C   GLY A  56      -7.093   9.042  14.960  1.00 35.73           C  
+ATOM     12  O   GLY A  56      -7.875   8.322  14.336  1.00 35.25           O  
+ATOM     18  N   GLY A  57      -5.757   8.838  14.934  1.00 32.59           N  
+ATOM     19  CA  GLY A  57      -5.167   7.704  14.210  1.00 30.22           C  
+ATOM     20  C   GLY A  57      -5.475   6.389  14.924  1.00 28.03           C  
+ATOM     21  O   GLY A  57      -5.774   6.389  16.125  1.00 25.91           O   
+ATOM     25  N   HIS A  58      -5.434   5.288  14.176  1.00 26.73           N  
+ATOM     26  CA  HIS A  58      -5.705   3.960  14.726  1.00 26.95           C  
+ATOM     27  C   HIS A  58      -4.622   3.524  15.706  1.00 27.12           C  
+ATOM     28  O   HIS A  58      -3.426   3.545  15.366  1.00 27.18           O  
+ATOM     29  CB  HIS A  58      -5.849   2.928  13.607  1.00 26.98           C  
+ATOM     30  CG  HIS A  58      -7.149   3.014  12.872  1.00 27.32           C  
+ATOM     31  ND1 HIS A  58      -8.359   3.179  13.510  1.00 28.47           N  
+ATOM     32  CD2 HIS A  58      -7.428   2.948  11.552  1.00 26.86           C  
+ATOM     33  CE1 HIS A  58      -9.327   3.211  12.613  1.00 28.81           C  
+ATOM     34  NE2 HIS A  58      -8.789   3.073  11.416  1.00 28.59           N  
+END   
diff --git a/modules/conop/tests/testfiles/sep.pdb b/modules/conop/tests/testfiles/sep.pdb
new file mode 100644
index 0000000000000000000000000000000000000000..f381b42b76b5bac59fc77925b742811410a8f157
--- /dev/null
+++ b/modules/conop/tests/testfiles/sep.pdb
@@ -0,0 +1,10 @@
+HETATM 2554  N   SEP A 338      22.112  31.452   4.376  1.00 36.83           N  
+HETATM 2555  CA  SEP A 338      21.303  32.489   4.986  1.00 35.62           C  
+HETATM 2556  CB  SEP A 338      20.220  31.868   5.843  1.00 36.98           C  
+HETATM 2557  OG  SEP A 338      19.529  32.909   6.526  1.00 38.75           O  
+HETATM 2558  C   SEP A 338      22.121  33.517   5.710  1.00 36.32           C  
+HETATM 2559  O   SEP A 338      23.245  32.996   6.389  1.00 28.28           O  
+HETATM 2560  P   SEP A 338      18.280  33.605   5.779  1.00 36.73           P  
+HETATM 2561  O1P SEP A 338      17.256  33.885   6.849  1.00 38.47           O  
+HETATM 2562  O2P SEP A 338      17.811  32.606   4.750  1.00 39.29           O  
+HETATM 2563  O3P SEP A 338      18.956  34.824   5.189  1.00 32.24           O
\ No newline at end of file
diff --git a/modules/img/alg/tests/test_stat.cc b/modules/img/alg/tests/test_stat.cc
index 9c9694a4caace6c7b79c14fd9d2fc2c9a1b57778..b736c6bd93d30aebbcc2eb05616e70c4d0d19f7e 100644
--- a/modules/img/alg/tests/test_stat.cc
+++ b/modules/img/alg/tests/test_stat.cc
@@ -52,7 +52,7 @@ void test() {
   im.Apply(stat);
   BOOST_CHECK_CLOSE(stat.GetMean(),Real(5.0),Real(0.0001));
   BOOST_CHECK_CLOSE(stat.GetStandardDeviation(),Real(2.58198889747),Real(0.0001));
-  BOOST_CHECK_CLOSE(stat.GetSkewness()+0.5,Real(0.5),Real(0.0001));
+  BOOST_CHECK_CLOSE(stat.GetSkewness()+Real(0.5),Real(0.5),Real(0.0001));
   BOOST_CHECK_CLOSE(stat.GetKurtosis(),Real(1.77),Real(0.0001));
 
   // check for rounding errors
@@ -60,7 +60,7 @@ void test() {
   im.Apply(stat);
   BOOST_CHECK_CLOSE(stat.GetMean(),Real(10005.0),Real(0.0001));
   BOOST_CHECK_CLOSE(stat.GetStandardDeviation(),Real(2.58198889747),Real(0.01));
-  BOOST_CHECK_CLOSE(stat.GetSkewness()+0.5,Real(0.5),Real(0.01));
+  BOOST_CHECK_CLOSE(stat.GetSkewness()+Real(0.5),Real(0.5),Real(0.01));
   BOOST_CHECK_CLOSE(stat.GetKurtosis(),Real(1.77),Real(0.01));
 
 
@@ -72,7 +72,7 @@ void test() {
   }
   BOOST_CHECK_CLOSE(acc.GetMean(),Real(5.0),Real(0.0001));
   BOOST_CHECK_CLOSE(acc.GetStandardDeviation(),Real(2.58198889747),Real(0.0001));
-  BOOST_CHECK_CLOSE(acc.GetSkewness()+0.5,Real(0.5),Real(0.0001));
+  BOOST_CHECK_CLOSE(acc.GetSkewness()+Real(0.5),Real(0.5),Real(0.0001));
   BOOST_CHECK_CLOSE(acc.GetKurtosis(),Real(1.77),Real(0.0001));
 
   StatAccumulator<> acc1,acc2,acc3;
@@ -84,7 +84,7 @@ void test() {
   StatAccumulator<> acc_c=acc1+acc2+acc3;
   BOOST_CHECK_CLOSE(acc_c.GetMean(),Real(5.0),Real(0.0001));
   BOOST_CHECK_CLOSE(acc_c.GetStandardDeviation(),Real(2.58198889747),Real(0.0001));
-  BOOST_CHECK_CLOSE(acc_c.GetSkewness()+0.5,Real(0.5),Real(0.0001));
+  BOOST_CHECK_CLOSE(acc_c.GetSkewness()+Real(0.5),Real(0.5),Real(0.0001));
   BOOST_CHECK_CLOSE(acc_c.GetKurtosis(),Real(1.77),Real(0.0001));
 }
 
diff --git a/modules/io/pymod/wrap_io.cc b/modules/io/pymod/wrap_io.cc
index 1d9e3b93613dfb9ef2bb8d5d91e44ba8f460c533..53ba11f7c85173c3ebc56c14002db8443e5c229f 100644
--- a/modules/io/pymod/wrap_io.cc
+++ b/modules/io/pymod/wrap_io.cc
@@ -113,7 +113,6 @@ BOOST_PYTHON_MODULE(_ost_io)
   def("LoadCRD", &LoadCRD);
   def("LoadCHARMMTraj_", &LoadCHARMMTraj, (arg("ent"), arg("trj_filename"), 
       arg("stride")=1, arg("lazy_load")=false));
-  def("SaveCHARMMTraj",SaveCHARMMTraj,save_charmm_trj_ov());
 
   def("LoadMAE", &LoadMAE);
 
@@ -122,4 +121,7 @@ BOOST_PYTHON_MODULE(_ost_io)
 #if OST_IMG_ENABLED  
   export_map_io();
 #endif
+  def("SaveCHARMMTraj", &SaveCHARMMTraj, 
+      (arg("traj"), arg("pdb_filename"), arg("dcd_filename"), arg("stride")=1, 
+       arg("profile")=IOProfile()));
 }
diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc
index 7178667b3bc57cf337defa972c4371d830ce3b19..3d7bd37563205c8f4428791717fe068536241490 100644
--- a/modules/io/src/mol/pdb_reader.cc
+++ b/modules/io/src/mol/pdb_reader.cc
@@ -102,6 +102,9 @@ void PDBReader::Init(const boost::filesystem::path& loc)
   hard_end_=false;
   skip_next_=false;
   data_continues_=false;
+  old_key_="";
+  mol_id_=std::make_pair(false, 0);
+  
 }
 
 void PDBReader::ThrowFaultTolerant(const String& msg) {
@@ -114,7 +117,7 @@ void PDBReader::ThrowFaultTolerant(const String& msg) {
 
 void PDBReader::ParseCompndEntry (const StringRef& line, int line_num)
 {
-  if (line.size()<20) {
+  if (line.size()<12) {
     if (profile_.fault_tolerant) {
       LOG_WARNING("invalid COMPND record on line " << line_num 
                   << ": record is too short");
@@ -147,11 +150,22 @@ void PDBReader::ParseCompndEntry (const StringRef& line, int line_num)
   }
   if((entry.find(':')!=entry.end())){
     std::vector<StringRef> fields=entry.split(':');
-    key=fields[0].trim();
-    old_key_=key.str();
-    data=fields[1].trim();
+      key=fields[0].trim();
+      old_key_=key.str();
+    if (fields.size()>1) {
+      data=fields[1].trim();
+    }
+
 
     if(data.size()<1){
+      if (!(key.str()=="MOL_ID")&&!(key.str()=="CHAIN")){
+        LOG_WARNING("skipping unsupported COMPND record on line " << line_num<< ": record value"<< key.str()<<" too small");
+        if (data_continues_) {
+          skip_next_=true;
+        } else {
+          return;
+        }
+      }
       ThrowFaultTolerant(str(format("invalid COMPND record on line %d, record after ':' too small")%line_num));
     }
     data_continues_=true;
@@ -179,7 +193,7 @@ void PDBReader::ParseCompndEntry (const StringRef& line, int line_num)
   } 
       //currently only these are parsed
   if (!(key.str()=="MOL_ID")&&!(key.str()=="CHAIN")){
-    LOG_TRACE("reading COMPND record on line " << line_num<< "is not supported");
+    LOG_INFO("reading COMPND record on line " << line_num<< "is not supported");
     if (data_continues_) {
       skip_next_=true;
     } else {
@@ -464,15 +478,18 @@ void PDBReader::AssignMolIds(mol::EntityHandle ent) {
     for (std::vector<String>::const_iterator chain_iterator = compnd_iterator->chains.begin();
                                              chain_iterator!= compnd_iterator->chains.end();
                                              ++chain_iterator) {
+      //~ std::cout << "chain: "<<*chain_iterator <<":: "<<std::endl;
       if (restrict_chains_.size()==0 ||
         (restrict_chains_.find(*chain_iterator)!=String::npos)) {
         mol::ChainHandle chain=ent.FindChain(*chain_iterator);
         if (chain) {
           chain.SetIntProp("mol_id", compnd_iterator->mol_id);
         }else{
+          std::cout << "failed to assign MOL_ID to chain: "<<*chain_iterator <<std::endl;
+
           std::stringstream ss;
-          ss << "could not map COMPND record MOL_ID onto chain "
-             <<*chain_iterator;
+          ss << "could not map COMPND record MOL_ID onto chain";
+          ss <<*chain_iterator;
           ThrowFaultTolerant(ss.str());
         }
       }
@@ -482,9 +499,13 @@ void PDBReader::AssignMolIds(mol::EntityHandle ent) {
     mol::ChainHandleList ch_list=ent.GetChainList();
     for (mol::ChainHandleList::const_iterator chain=ch_list.begin();
          chain!=ch_list.end(); ++chain) {
+           //~ skip HETATM only chains!!
       if(chain->IsValid()){
         if (!chain->HasProp("mol_id")) {
-          ThrowFaultTolerant("found chain without MOL_ID");
+          std::stringstream ss;
+          ss << "found chain without MOL_ID: ";
+          ss << chain->GetName();
+          LOG_WARNING(ss.str());
         }
       }
     }
diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc
index 0056bd194eb54d6624482acfdb2eca1e1605c68e..5bbfbf699a9684f0eee761fbe04f42698f77daa2 100644
--- a/modules/io/tests/test_io_pdb.cc
+++ b/modules/io/tests/test_io_pdb.cc
@@ -139,7 +139,45 @@ BOOST_AUTO_TEST_CASE(test_parse_compnd_record5)
   PDBReader reader(fname, IOProfile()); 
   mol::EntityHandle ent=mol::CreateEntity();
   
+  BOOST_CHECK_NO_THROW(reader.Import(ent));
+  
+  mol::ChainHandle ch = ent.FindChain("A");
+  BOOST_CHECK(ch.HasProp("mol_id")==true);
+  BOOST_CHECK(ch.GetIntProp("mol_id")==1);
+  
+  ch = ent.FindChain("B");
+  BOOST_CHECK(ch.HasProp("mol_id")==false);
+}
+
+//chain I in MOL_ID record but no chain I
+BOOST_AUTO_TEST_CASE(test_parse_compnd_record6) 
+{
+  String fname("testfiles/pdb/1oax.pdb");
+  PDBReader reader(fname, IOProfile()); 
+  mol::EntityHandle ent=mol::CreateEntity();
+  
   BOOST_CHECK_THROW(reader.Import(ent), IOException);
+  
+}
+
+// has an empy MOLECULE record (unsupported ATM anyway, but crashed ost)
+BOOST_AUTO_TEST_CASE(test_parse_compnd_record7) 
+{
+  String fname("testfiles/pdb/2p6a.pdb");
+  PDBReader reader(fname, IOProfile()); 
+  mol::EntityHandle ent=mol::CreateEntity();
+  
+  reader.Import(ent);
+  mol::ChainHandle ch = ent.FindChain("A");
+  BOOST_CHECK(ch.HasProp("mol_id")==true);
+  BOOST_CHECK(ch.GetIntProp("mol_id")==1);
+  ch = ent.FindChain("D");
+  BOOST_CHECK(ch.HasProp("mol_id")==true);
+  BOOST_CHECK(ch.GetIntProp("mol_id")==2);
+
+  ch = ent.FindChain("E");
+  BOOST_CHECK(ch.HasProp("mol_id")==true);
+  BOOST_CHECK(ch.GetIntProp("mol_id")==3);
 }
 
 
diff --git a/modules/io/tests/testfiles/pdb/1oax.pdb b/modules/io/tests/testfiles/pdb/1oax.pdb
new file mode 100644
index 0000000000000000000000000000000000000000..8a61950e8a0970d2b719b35c65465907ff0b6f3d
--- /dev/null
+++ b/modules/io/tests/testfiles/pdb/1oax.pdb
@@ -0,0 +1,24 @@
+
+COMPND    MOL_ID: 1;                                                            
+COMPND   2 MOLECULE: IMMUNOGLOBULIN E;                                          
+COMPND   3 CHAIN: H, I, J, K;                                                   
+COMPND   4 FRAGMENT: FV REGION, RESIDUES 1-122;                                 
+COMPND   5 ENGINEERED: YES;                                                     
+COMPND   6 MOL_ID: 2;                                                           
+COMPND   7 MOLECULE: IMMUNOGLOBULIN E;                                          
+COMPND   8 CHAIN: L, M, N, O;                                                   
+COMPND   9 FRAGMENT: FV REGION, RESIDUES 1-110;                                 
+COMPND  10 ENGINEERED: YES                       
+
+ATOM    961  CB  ALA H 122      24.405  78.113 110.762  1.00 46.85           C  
+TER     962      ALA H 122                                                      
+ATOM   1923  CB  ALA J 122     -18.810  34.607  14.909  1.00 46.23           C  
+TER    1924      ALA J 122                                                      
+ATOM   2722  CD2 LEU L 109      61.832  51.079 106.030  1.00 43.23           C  
+TER    2723      LEU L 109                                                      
+ATOM   3521  CD2 LEU M 109       2.184  -0.589  68.108  1.00 43.23           C  
+TER    3522      LEU M 109                                                      
+ATOM   4320  CD2 LEU N 109       7.889  -2.865  19.656  1.00 43.22           C  
+TER    4321      LEU N 109                                                      
+ATOM   5113  CD2 LEU O 109      59.692  56.678  57.399  1.00 43.23           C  
+TER    5114      LEU O 109                                                      
diff --git a/modules/io/tests/testfiles/pdb/2p6a.pdb b/modules/io/tests/testfiles/pdb/2p6a.pdb
new file mode 100644
index 0000000000000000000000000000000000000000..19935ba86c1e7b632bd02a2c50ac89a726f0e9cb
--- /dev/null
+++ b/modules/io/tests/testfiles/pdb/2p6a.pdb
@@ -0,0 +1,25 @@
+COMPND    MOL_ID: 1;                                                            
+COMPND   2 MOLECULE: INHIBIN BETA A CHAIN;                                      
+COMPND   3 CHAIN: A, B;                                                         
+COMPND   4 SYNONYM: ACTIVIN BETA-A CHAIN, ERYTHROID DIFFERENTIATION             
+COMPND   5 PROTEIN, EDF;                                                        
+COMPND   6 ENGINEERED: YES;                                                     
+COMPND   7 MOL_ID: 2;                                                           
+COMPND   8 MOLECULE: FOLLISTATIN;                                               
+COMPND   9 CHAIN: D, C;                                                         
+COMPND  10 SYNONYM: FS, ACTIVIN-BINDING PROTEIN;                                
+COMPND  11 ENGINEERED: YES;                                                     
+COMPND  12 MOL_ID: 3;                                                           
+COMPND  13 MOLECULE:;                                                           
+COMPND  14 CHAIN: E;                                                            
+COMPND  15 ENGINEERED: YES
+ATOM    882  OXT SER A 116      15.399  37.353  44.611  1.00 73.37           O  
+TER     883      SER A 116                                                      
+ATOM   3870  OXT SER B 116      13.780  40.357  30.274  1.00 27.95           O  
+TER    3871      SER B 116                                                      
+ATOM   2987  OE2 GLU D 299      33.348  36.499   4.332  1.00 81.88           O  
+TER    2988      GLU D 299                                                      
+ATOM   5905  CB  ILE C 290      46.026  -9.354  55.435  1.00233.79           C  
+TER    5906      ILE C 290                                                      
+ATOM   5956  CB  ALA E  10      30.651  13.129  53.296  1.00191.07           C  
+TER    5957      ALA E  10  
diff --git a/modules/mol/base/tests/test_ics.cc b/modules/mol/base/tests/test_ics.cc
index 0b19877c8a95b28e1230692c1a35a64cf7a0d8d6..4f84f6a78bf0882302f9d5edce87ed13656b6064 100644
--- a/modules/mol/base/tests/test_ics.cc
+++ b/modules/mol/base/tests/test_ics.cc
@@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(ics_update_icsbondlength)
 {
   TorsionStructure s;
   mol::BondHandle bond = s.a2.FindBondToAtom(s.a3);
-  BOOST_CHECK_CLOSE(bond.GetLength(), 1.0, EPSILON);
+  BOOST_CHECK_CLOSE(bond.GetLength(), Real(1.0), Real(EPSILON));
 }
 
 BOOST_AUTO_TEST_CASE(ics_settorsion_unbuffered)
@@ -115,20 +115,20 @@ BOOST_AUTO_TEST_CASE(ics_settorsion_unbuffered)
   Real eps = 0.0001;
   TorsionStructure s;
   ICSEditor e = s.e.EditICS(mol::UNBUFFERED_EDIT);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), M_PI, eps);
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(M_PI), Real(eps));
   BOOST_CHECK_SMALL(s.t2.GetAngle(), eps);
   e.SetTorsionAngle(s.t1,0);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI), Real(eps));
   e.SetTorsionAngle(s.t2,M_PI/4);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), -M_PI+M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(-M_PI+M_PI/4), Real(eps));
   e.SetTorsionAngle(s.t1,-M_PI/4);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), -M_PI/4, eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), 3/4.*M_PI, eps);
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(-M_PI/4), Real(eps));
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(3/4.*M_PI), Real(eps));
   e.RotateTorsionAngle(s.t1, M_PI/4);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
-  BOOST_CHECK_CLOSE(std::abs(s.t2.GetAngle()), M_PI, eps);
+  BOOST_CHECK_CLOSE(std::abs(s.t2.GetAngle()), Real(M_PI), Real(eps));
 }
 
 BOOST_AUTO_TEST_CASE(ics_settorsion_buffered)
@@ -136,20 +136,20 @@ BOOST_AUTO_TEST_CASE(ics_settorsion_buffered)
   Real eps = 0.0001;
   TorsionStructure s;
   ICSEditor e = s.e.EditICS(mol::BUFFERED_EDIT);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), M_PI, eps);
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(M_PI), Real(eps));
   BOOST_CHECK_SMALL(s.t2.GetAngle(), eps);
   e.SetTorsionAngle(s.t1,0);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI), Real(eps));
   e.SetTorsionAngle(s.t2,M_PI/4);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), -M_PI+M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(-M_PI+M_PI/4), Real(eps));
   e.SetTorsionAngle(s.t1,-M_PI/4);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), -M_PI/4, eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), 3/4.*M_PI, eps);
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(-M_PI/4), Real(eps));
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(3/4.*M_PI), Real(eps));
   e.RotateTorsionAngle(s.t1, M_PI/4);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
-  BOOST_CHECK_CLOSE(std::abs(s.t2.GetAngle()), M_PI, eps);
+  BOOST_CHECK_CLOSE(std::abs(s.t2.GetAngle()), Real(M_PI), Real(eps));
 }
 
 BOOST_AUTO_TEST_CASE(ics_settorsion_unbuffered_update_others)
@@ -157,20 +157,20 @@ BOOST_AUTO_TEST_CASE(ics_settorsion_unbuffered_update_others)
   Real eps = 0.0001;
   TorsionStructure s;
   ICSEditor e = s.e.EditICS(mol::UNBUFFERED_EDIT);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), M_PI, eps);
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(M_PI), Real(eps));
   BOOST_CHECK_SMALL(s.t2.GetAngle(), eps);
   e.SetTorsionAngle(s.t1,0,false);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
   BOOST_CHECK_SMALL(s.t2.GetAngle(), eps);
   e.SetTorsionAngle(s.t2,M_PI/4,false);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
   e.SetTorsionAngle(s.t1,-M_PI/4,false);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), -M_PI/4, eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(-M_PI/4), Real(eps));
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
   e.RotateTorsionAngle(s.t1, M_PI/4,false);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
 }
 
 BOOST_AUTO_TEST_CASE(ics_settorsion_buffered_update_others)
@@ -178,20 +178,20 @@ BOOST_AUTO_TEST_CASE(ics_settorsion_buffered_update_others)
   Real eps = 0.0001;
   TorsionStructure s;
   ICSEditor e = s.e.EditICS(mol::BUFFERED_EDIT);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), M_PI, eps);
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(M_PI), Real(eps));
   BOOST_CHECK_SMALL(s.t2.GetAngle(), eps);
   e.SetTorsionAngle(s.t1,0,false);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
   BOOST_CHECK_SMALL(s.t2.GetAngle(), eps);
   e.SetTorsionAngle(s.t2,M_PI/4,false);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
   e.SetTorsionAngle(s.t1,-M_PI/4,false);
-  BOOST_CHECK_CLOSE(s.t1.GetAngle(), -M_PI/4, eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(-M_PI/4), Real(eps));
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
   e.RotateTorsionAngle(s.t1, M_PI/4,false);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
 }
 
 BOOST_AUTO_TEST_CASE(ics_settorsion_linear_unbuffered)
@@ -207,13 +207,13 @@ BOOST_AUTO_TEST_CASE(ics_settorsion_linear_unbuffered)
   BOOST_CHECK_SMALL(s.t2.GetAngle(), eps);
   e.SetTorsionAngle(s.t2,M_PI/4);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
   e.SetTorsionAngle(s.t1,-M_PI/4);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
   BOOST_CHECK_SMALL(s.t2.GetAngle(), eps);
   e.RotateTorsionAngle(s.t1, M_PI/4);
   BOOST_CHECK_SMALL(s.t1.GetAngle(), eps);
-  BOOST_CHECK_CLOSE(s.t2.GetAngle(), M_PI/4, eps);
+  BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps));
 }
 
 BOOST_AUTO_TEST_CASE(ics_angle_trivia)