From 1494e7dd13a22db1829625aee6da4d9ae6cb4be8 Mon Sep 17 00:00:00 2001
From: Xavier Robin <xavier.robin@unibas.ch>
Date: Wed, 1 Feb 2023 17:15:00 +0100
Subject: [PATCH] fix: SCHWED-5783 make element uppercase by convention

Fixes the SDF reader and documents the convention.
---
 modules/io/src/mol/sdf_reader.cc        | 4 +++-
 modules/io/tests/test_io_sdf.cc         | 2 +-
 modules/mol/alg/pymod/ligand_scoring.py | 4 ++--
 modules/mol/base/doc/editors.rst        | 4 +++-
 modules/mol/base/doc/entity.rst         | 6 ++++--
 5 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/modules/io/src/mol/sdf_reader.cc b/modules/io/src/mol/sdf_reader.cc
index f402fc3c0..c8394ab77 100644
--- a/modules/io/src/mol/sdf_reader.cc
+++ b/modules/io/src/mol/sdf_reader.cc
@@ -199,6 +199,8 @@ void SDFReader::ParseAndAddAtom(const String& line, int line_num,
   }
 
   String ele=boost::trim_copy(s_ele);
+  String upper_ele=ele;
+  std::transform(upper_ele.begin(),upper_ele.end(),upper_ele.begin(),toupper);
   String aname=boost::lexical_cast<String>(anum);
   
   Real charge=0.0;  
@@ -215,7 +217,7 @@ void SDFReader::ParseAndAddAtom(const String& line, int line_num,
 
   LOG_DEBUG("adding atom " << aname << " (" << s_ele << ") @" << apos);
 
-  mol::AtomHandle atom=editor.InsertAtom(curr_residue_, aname,apos, ele);  
+  mol::AtomHandle atom=editor.InsertAtom(curr_residue_, aname, apos, upper_ele);
   atom.SetHetAtom(hetatm);
   atom.SetCharge(charge);
 }
diff --git a/modules/io/tests/test_io_sdf.cc b/modules/io/tests/test_io_sdf.cc
index 0dcbf5fd6..df84041b0 100644
--- a/modules/io/tests/test_io_sdf.cc
+++ b/modules/io/tests/test_io_sdf.cc
@@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(simple_sdf)
   mol::AtomHandle ah2=eh.GetAtomList()[5];
 
   BOOST_CHECK_EQUAL(ah.GetElement(),  "N");
-  BOOST_CHECK_EQUAL(ah2.GetElement(), "Cl");
+  BOOST_CHECK_EQUAL(ah2.GetElement(), "CL");
   BOOST_CHECK_CLOSE(ah.GetRadius(),  Real(1.55), Real(1e-2));
   BOOST_CHECK_CLOSE(ah2.GetRadius(), Real(1.75), Real(1e-2));
   BOOST_CHECK_CLOSE(ah.GetMass(),  Real(14.007), Real(1e-4));
diff --git a/modules/mol/alg/pymod/ligand_scoring.py b/modules/mol/alg/pymod/ligand_scoring.py
index ff0fbfb78..d03caf265 100644
--- a/modules/mol/alg/pymod/ligand_scoring.py
+++ b/modules/mol/alg/pymod/ligand_scoring.py
@@ -738,12 +738,12 @@ def _ResidueToGraph(residue, by_atom_index=False):
     :type by_atom_index: :class:`bool`
     :rtype: :class:`~networkx.classes.graph.Graph`
 
-    Nodes are labeled with the Atom's lowercase :attr:`~ost.mol.AtomHandle.element`.
+    Nodes are labeled with the Atom's uppercase :attr:`~ost.mol.AtomHandle.element`.
     """
     nxg = networkx.Graph()
 
     for atom in residue.atoms:
-        nxg.add_node(atom.name, element=atom.element.lower())
+        nxg.add_node(atom.name, element=atom.element.upper())
 
     # This will list all edges twice - once for every atom of the pair.
     # But as of NetworkX 3.0 adding the same edge twice has no effect, so we're good.
diff --git a/modules/mol/base/doc/editors.rst b/modules/mol/base/doc/editors.rst
index 6205ba44b..71577df36 100644
--- a/modules/mol/base/doc/editors.rst
+++ b/modules/mol/base/doc/editors.rst
@@ -118,7 +118,9 @@ The basic functionality of editors is implemented in the EditorBase class.
   .. method:: InsertAtom(residue, atom_name, pos, element="", occupancy=1.0, \
                          b_factor=0.0, is_hetatm=False)
   
-    Insert new atom and add it to residue. For atoms with alternative atom locations use :meth:`InsertAltAtom`. If the element parameter is a valid 
+    Insert new atom and add it to residue. By convention, this should be the
+    chemical symbol in upper case. For atoms with alternative atom locations
+    use :meth:`InsertAltAtom`. If the element parameter is a valid
     element, the atom properties mass, charge, and radius are set to default 
     values for that element. If element is an empty string (or an invalid 
     element), the properties are set to rather meaningless default values. You 
diff --git a/modules/mol/base/doc/entity.rst b/modules/mol/base/doc/entity.rst
index 1cd9ce388..5e778d670 100644
--- a/modules/mol/base/doc/entity.rst
+++ b/modules/mol/base/doc/entity.rst
@@ -908,8 +908,10 @@ The Handle Classes
      
   .. attribute:: element
   
-    The atom's element. Note that this may return an empty string. Also 
-    available as :meth:`GetElement`. Read-only.
+    The atom's element. By convention in Openstructure, this is the chemical
+    symbol in uppercase, but this is not strictly enforced and may be a non-
+    existing element or an empty string. Also available as :meth:`GetElement`.
+    Read-only.
     
     :type: str
     
-- 
GitLab