diff --git a/modules/mol/base/doc/entity.rst b/modules/mol/base/doc/entity.rst
index d4415da8c2fcfaaa059b4c8773f2d3fdd70cc954..41945d534e48b52c1c9771bbeab4de236a70802e 100644
--- a/modules/mol/base/doc/entity.rst
+++ b/modules/mol/base/doc/entity.rst
@@ -620,6 +620,25 @@ The Handle Classes
 
     Residue index (starting at 0) within chain.
 
+  .. attribute:: central_atom
+
+    Central atom used for rendering traces. For peptides, this is usually
+    the CA atom. For nucleotides, this is usually the P atom.
+
+    Also available as :meth:`GetCentralAtom` and :meth:`SetCentralAtom`.
+
+    :type: :class:`AtomHandle`
+
+  .. attribute:: central_normal
+
+    Normal computed for :attr:`central_atom`. Only defined for peptides and
+    nucleotides if all required atoms available. Otherwise, the (1,0,0) vector
+    is returned.
+
+    Read-only. Also available as :meth:`GetCentralNormal`.
+
+    :type: :class:`~ost.geom.Vec3`
+
   .. method:: FindAtom(atom_name)
 
     Get atom by atom name. See also :attr:`atoms`
@@ -666,6 +685,15 @@ The Handle Classes
   .. method:: GetIndex()
     
     See :attr:`index`
+
+  .. method:: GetCentralAtom()
+              SetCentralAtom()
+    
+    See :attr:`central_atom`
+
+  .. method:: GetCentralNormal()
+    
+    See :attr:`index`
   
 
 .. class:: AtomHandle
diff --git a/modules/mol/base/src/impl/residue_impl.cc b/modules/mol/base/src/impl/residue_impl.cc
index fe1e7f60b0448d79e661fabc2b4cbe2630cd58ae..014f4069f5cae65e808d25151db5cee4ef10f213 100644
--- a/modules/mol/base/src/impl/residue_impl.cc
+++ b/modules/mol/base/src/impl/residue_impl.cc
@@ -212,12 +212,12 @@ AtomImplPtr ResidueImpl::GetCentralAtom() const
     for (AtomImplList::const_iterator it=atom_list_.begin();
          it!=atom_list_.end();++it) {
       if((*it)->Name()=="P") return *it;
-    }    
+    }
   } else if (chem_class_.IsPeptideLinking()) {
     for (AtomImplList::const_iterator it=atom_list_.begin();
          it!=atom_list_.end();++it) {
       if((*it)->Name()=="CA") return *it;
-    }    
+    }
   }
 
   return AtomImplPtr();
@@ -266,18 +266,21 @@ geom::Vec3 ResidueImpl::GetCentralNormal() const
   geom::Vec3 nrvo(1,0,0);
   if (chem_class_.IsPeptideLinking()) {
     AtomImplPtr a1 = FindAtom("C");
-    AtomImplPtr a2 = FindAtom("O"); 
+    AtomImplPtr a2 = FindAtom("O");
     if(a1 && a2) {
       nrvo = geom::Normalize(a2->TransformedPos()-a1->TransformedPos());
     } else {
       a1 = FindAtom("CB");
-      a2 = FindAtom("CA"); 
+      a2 = FindAtom("CA");
       if(a1 && a2) {
         nrvo = geom::Normalize(a2->TransformedPos()-a1->TransformedPos());
       } else {
-        geom::Vec3 v0=GetCentralAtom()->TransformedPos();
-        nrvo=geom::Cross(geom::Normalize(v0),
-                         geom::Normalize(geom::Vec3(-v0[2],v0[0],v0[1])));
+        AtomImplPtr a0 = GetCentralAtom();
+        if (a0) {
+          geom::Vec3 v0 = a0->TransformedPos();
+          nrvo = geom::Cross(geom::Normalize(v0),
+                             geom::Normalize(geom::Vec3(-v0[2], v0[0], v0[1])));
+        }
         LOG_VERBOSE("warning: could not find atoms for proper central normal calculation");
       }
     }
@@ -288,9 +291,12 @@ geom::Vec3 ResidueImpl::GetCentralNormal() const
     if(a1 && a2 && a3) {
       nrvo = geom::Normalize(a1->TransformedPos()-(a2->TransformedPos()+a3->TransformedPos())*.5);
     } else {
-      geom::Vec3 v0=GetCentralAtom()->TransformedPos();
-      nrvo=geom::Cross(geom::Normalize(v0),
-                       geom::Normalize(geom::Vec3(-v0[2],v0[0],v0[1])));
+      AtomImplPtr a0 = GetCentralAtom();
+      if (a0) {
+        geom::Vec3 v0 = a0->TransformedPos();
+        nrvo = geom::Cross(geom::Normalize(v0),
+                           geom::Normalize(geom::Vec3(-v0[2], v0[0], v0[1])));
+      }
       LOG_VERBOSE("warning: could not find atoms for proper central normal calculation");
     }
   }
diff --git a/modules/mol/base/tests/test_residue.cc b/modules/mol/base/tests/test_residue.cc
index 89e8da33914110dc1d50150fb9dc19e2ab3dd50e..d828544b7eba1ef47d5c995b4341b438e68e8c9d 100644
--- a/modules/mol/base/tests/test_residue.cc
+++ b/modules/mol/base/tests/test_residue.cc
@@ -125,4 +125,92 @@ BOOST_AUTO_TEST_CASE(rename_res)
    BOOST_CHECK_EQUAL(rA2B.GetName(), "B");
 }
 
+BOOST_AUTO_TEST_CASE(test_centralatom)
+{
+  // COOK UP ENTITY FOR TEST
+  EntityHandle eh = CreateEntity();
+  XCSEditor e = eh.EditXCS();
+  ChainHandle ch = e.InsertChain("A");
+  // decent peptide with all entries
+  ResidueHandle rp1 = e.AppendResidue(ch, "A");
+  e.InsertAtom(rp1, "CA", geom::Vec3(2, 0, 0));
+  e.InsertAtom(rp1, "CB", geom::Vec3(1, 0, 0));
+  e.InsertAtom(rp1, "C",  geom::Vec3(0, 0, 0));
+  e.InsertAtom(rp1, "O",  geom::Vec3(0, 1, 0));
+  rp1.SetChemClass(ChemClass(ChemClass::PEPTIDE_LINKING));
+  // weird peptide with only CA and CB
+  ResidueHandle rp2 = e.AppendResidue(ch, "B");
+  e.InsertAtom(rp2, "CA", geom::Vec3(3, 0, 0));
+  e.InsertAtom(rp2, "CB", geom::Vec3(3, 1, 0));
+  rp2.SetChemClass(ChemClass(ChemClass::PEPTIDE_LINKING));
+  // CA-only peptide
+  ResidueHandle rp3 = e.AppendResidue(ch, "C");
+  e.InsertAtom(rp3, "CA", geom::Vec3(4, 0, 0));
+  rp3.SetChemClass(ChemClass(ChemClass::PEPTIDE_LINKING));
+  // peptide with custom atoms
+  ResidueHandle rp4 = e.AppendResidue(ch, "D");
+  AtomHandle rp4_ax = e.InsertAtom(rp4, "XX", geom::Vec3(5, 0, 0));
+  rp4.SetChemClass(ChemClass(ChemClass::PEPTIDE_LINKING));
+  // nucleotide with all needed entries
+  ResidueHandle rn1 = e.AppendResidue(ch, "E");
+  e.InsertAtom(rn1, "P", geom::Vec3(6, 0, 0));
+  e.InsertAtom(rn1, "OP1", geom::Vec3(6, 0.5, 0));
+  e.InsertAtom(rn1, "OP2", geom::Vec3(6, 1.5, 0));
+  rn1.SetChemClass(ChemClass(ChemClass::DNA_LINKING));
+  // nucleotide with only P
+  ResidueHandle rn2 = e.AppendResidue(ch, "F");
+  e.InsertAtom(rn2, "P", geom::Vec3(7, 0, 0));
+  rn2.SetChemClass(ChemClass(ChemClass::DNA_LINKING));
+  // nucleotide with custom atoms
+  ResidueHandle rn3 = e.AppendResidue(ch, "G");
+  AtomHandle rn3_ax = e.InsertAtom(rn3, "XX", geom::Vec3(8, 0, 0));
+  rn3.SetChemClass(ChemClass(ChemClass::DNA_LINKING));
+  // unknown chem class
+  ResidueHandle ru = e.AppendResidue(ch, "H");
+  e.InsertAtom(ru, "P",  geom::Vec3(9, 0, 0));
+  e.InsertAtom(ru, "CA", geom::Vec3(9, 1, 0));
+  AtomHandle ru_ax = e.InsertAtom(ru, "XX", geom::Vec3(9, 2, 0));
+  ru.SetChemClass(ChemClass(ChemClass::UNKNOWN));
+
+  // CHECK CENTRAL ATOMS
+  BOOST_CHECK(rp1.GetCentralAtom().IsValid());
+  BOOST_CHECK_EQUAL(rp1.GetCentralAtom().GetQualifiedName(), "A.A1.CA");
+  BOOST_CHECK(rp2.GetCentralAtom().IsValid());
+  BOOST_CHECK_EQUAL(rp2.GetCentralAtom().GetQualifiedName(), "A.B2.CA");
+  BOOST_CHECK(rp3.GetCentralAtom().IsValid());
+  BOOST_CHECK_EQUAL(rp3.GetCentralAtom().GetQualifiedName(), "A.C3.CA");
+  BOOST_CHECK(!rp4.GetCentralAtom().IsValid());
+  BOOST_CHECK(rn1.GetCentralAtom().IsValid());
+  BOOST_CHECK_EQUAL(rn1.GetCentralAtom().GetQualifiedName(), "A.E5.P");
+  BOOST_CHECK(rn2.GetCentralAtom().IsValid());
+  BOOST_CHECK_EQUAL(rn2.GetCentralAtom().GetQualifiedName(), "A.F6.P");
+  BOOST_CHECK(!rn3.GetCentralAtom().IsValid());
+  BOOST_CHECK(!ru.GetCentralAtom().IsValid());
+
+  // CHECK NORMALS
+  BOOST_CHECK_EQUAL(rp1.GetCentralNormal(), geom::Vec3(0, 1, 0));
+  BOOST_CHECK_EQUAL(rp2.GetCentralNormal(), geom::Vec3(0, -1, 0));
+  BOOST_CHECK_EQUAL(rp3.GetCentralNormal(), geom::Vec3(0, 0, 1));
+  BOOST_CHECK_EQUAL(rp4.GetCentralNormal(), geom::Vec3(1, 0, 0));
+  BOOST_CHECK_EQUAL(rn1.GetCentralNormal(), geom::Vec3(0, -1, 0));
+  BOOST_CHECK_EQUAL(rn2.GetCentralNormal(), geom::Vec3(0, 0, 1));
+  BOOST_CHECK_EQUAL(rn3.GetCentralNormal(), geom::Vec3(1, 0, 0));
+  BOOST_CHECK_EQUAL(ru.GetCentralNormal(), geom::Vec3(1, 0, 0));
+
+  // CHECK SETTING CENTRAL ATOMS
+  rp4.SetCentralAtom(rp4_ax);
+  BOOST_CHECK(rp4.GetCentralAtom().IsValid());
+  BOOST_CHECK_EQUAL(rp4.GetCentralAtom().GetQualifiedName(), "A.D4.XX");
+  BOOST_CHECK_EQUAL(rp4.GetCentralNormal(), geom::Vec3(0, 0, 1));
+  rn3.SetCentralAtom(rn3_ax);
+  BOOST_CHECK(rn3.GetCentralAtom().IsValid());
+  BOOST_CHECK_EQUAL(rn3.GetCentralAtom().GetQualifiedName(), "A.G7.XX");
+  BOOST_CHECK_EQUAL(rn3.GetCentralNormal(), geom::Vec3(0, 0, 1));
+  ru.SetCentralAtom(ru_ax);
+  BOOST_CHECK(ru.GetCentralAtom().IsValid());
+  BOOST_CHECK_EQUAL(ru.GetCentralAtom().GetQualifiedName(), "A.H8.XX");
+  // no normal for unknown residues
+  BOOST_CHECK_EQUAL(ru.GetCentralNormal(), geom::Vec3(1, 0, 0));
+}
+
 BOOST_AUTO_TEST_SUITE_END();