Skip to content

Commit

Permalink
Merge pull request #2649 from fredrikw/gh_2646
Browse files Browse the repository at this point in the history
Proper aromatic support for CML
  • Loading branch information
ghutchis committed Dec 6, 2023
2 parents bcb7900 + 5def2f7 commit 182c80f
Show file tree
Hide file tree
Showing 3 changed files with 409 additions and 301 deletions.
43 changes: 38 additions & 5 deletions src/formats/xml/cmlformat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ GNU General Public License for more details.
#include <openbabel/xml.h>
#include <cfloat>
#include <openbabel/reaction.h>

#include <openbabel/kekulize.h>

#ifdef WIN32
#pragma warning (disable : 4800)
Expand Down Expand Up @@ -835,9 +835,11 @@ namespace OpenBabel
vector<pair<string,string> >::iterator AttributeIter;
cmlArray::iterator BondIter;
bool HaveWarned = false;
bool needs_kekulization = false; // Have we have found an aromatic bond?
for(BondIter=BondArray.begin();BondIter!=BondArray.end();++BondIter)
{
int indx1=0,indx2=0, ord=0;
unsigned int flag=0;
string bondstereo, BondStereoRefs;
string colour;
string label;
Expand Down Expand Up @@ -894,9 +896,11 @@ namespace OpenBabel
ord=2;
else if(bo=='T')
ord=3;
else if(bo=='A')
ord=5;
else {
else if(bo=='A') {
ord=1;
flag |= OBBond::Aromatic;
needs_kekulization = true;
} else {
char* endptr;
ord = strtol(value.c_str(), &endptr, 10);
}
Expand All @@ -922,7 +926,7 @@ namespace OpenBabel
//But unspecied bond order means cannot assign spinmultiplicity
_pmol->SetIsPatternStructure();
}
_pmol->AddBond(indx1,indx2,ord,0);
_pmol->AddBond(indx1,indx2,ord,flag);

if(!colour.empty())
{
Expand All @@ -941,6 +945,35 @@ namespace OpenBabel
}
}

// Kekulization is necessary if an aromatic bond is present
if (needs_kekulization)
{
_pmol->SetAromaticPerceived();
// First of all, set the atoms at the ends of the aromatic bonds to also
// be aromatic. This information is required for OBKekulize.
FOR_BONDS_OF_MOL(bond, _pmol)
{
if (bond->IsAromatic())
{
bond->GetBeginAtom()->SetAromatic();
bond->GetEndAtom()->SetAromatic();
}
}
bool ok = OBKekulize(_pmol);
if (!ok)
{
stringstream errorMsg;
errorMsg << "Failed to kekulize aromatic bonds in MOL file";
std::string title = _pmol->GetTitle();
if (!title.empty())
errorMsg << " (title is " << title << ")";
errorMsg << endl;
obErrorLog.ThrowError(__FUNCTION__, errorMsg.str(), obWarning);
// return false; Should we return false for a kekulization failure?
}
_pmol->SetAromaticPerceived(false);
}

return true;
}

Expand Down

0 comments on commit 182c80f

Please sign in to comment.