Repository: rdkit/rdkit — pull request #4243 (cpp)
Title: Fixes #3998

#### Reference Issue

Fixes #3998

#### What does this implement/fix? Explain your changes.

`MolFragmentToSmiles` removes ring info but it makes no sense and also causes troubles. This PR removes the code.

#### Any other comments?


Resolved issues:
title: MolFragmentToSmiles with kekuleSmiles=True raises AtomKekulizeException
body: **Describe the bug**
Release 2021_03_1 raises `AtomKekulizeException` by the following code.

**To Reproduce**
```python
from rdkit import Chem
mol = Chem.MolFromSmiles("CC(c1ccccc1)")
Chem.MolFragmentToSmiles(mol, [0], kekuleSmiles=False)
Chem.MolFragmentToSmiles(mol, [2,3,4,5,6,7], kekuleSmiles=False)
Chem.MolFragmentToSmiles(mol, [0], kekuleSmiles=True)  # Error is raised here
Chem.MolFragmentToSmiles(mol, [2,3,4,5,6,7], kekuleSmiles=True)
```

**Expected behavior**
```
'C'
'c1ccccc1'
'C'
'C1=CC=CC=C1'
```

**Screenshots**
```python
>>> import rdkit
>>> rdkit.__version__
'2021.03.1'
>>> from rdkit import Chem
>>> mol = Chem.MolFromSmiles("CC(c1ccccc1)")
>>> Chem.MolFragmentToSmiles(mol, [0], kekuleSmiles=False)
'C'
>>> Chem.MolFragmentToSmiles(mol, [2,3,4,5,6,7], kekuleSmiles=False)
'c1ccccc1'
>>> Chem.MolFragmentToSmiles(mol, [0], kekuleSmiles=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
rdkit.Chem.rdchem.AtomKekulizeException: non-ring atom 2 marked aromatic
>>> Chem.MolFragmentToSmiles(mol, [2,3,4,5,6,7], kekuleSmiles=True)
'C1=CC=CC=C1'
```

**Configuration (please complete the following information):**
 - RDKit version: 2021.03.1 
 - OS: Windows 10
 - Python version (if relevant): 3.8.5
 - Are you using conda? : Yes
 - If you are using conda, which channel did you install the rdkit from?: conda-forge
 - If you are not using conda: how did you install the RDKit? : conda install rdkit==2021.03.1

**Additional context**
The result with Release_2020_09_5 is below.
```python
>>> import rdkit
>>> rdkit.__version__
'2020.09.5'
>>> from rdkit import Chem
>>> mol = Chem.MolFromSmiles("CC(c1ccccc1)")
>>> Chem.MolFragmentToSmiles(mol, [0], kekuleSmiles=False)
'C'
>>> Chem.MolFragmentToSmiles(mol, [2,3,4,5,6,7], kekuleSmiles=False)
'c1ccccc1'
>>> Chem.MolFragmentToSmiles(mol, [0], kekuleSmiles=True)
'C'
>>> Chem.MolFragmentToSmiles(mol, [2,3,4,5,6,7], kekuleSmiles=True)
'C1:C:C:C:C:C:1'
```


Hints:

Fix patch:
diff --git a/Code/GraphMol/SmilesParse/SmilesWrite.cpp b/Code/GraphMol/SmilesParse/SmilesWrite.cpp
index fe8f331a51c..8f5998cdd53 100644
--- a/Code/GraphMol/SmilesParse/SmilesWrite.cpp
+++ b/Code/GraphMol/SmilesParse/SmilesWrite.cpp
@@ -646,33 +646,6 @@ std::string MolFragmentToSmiles(const ROMol &mol,
     }
   }
 
-  // copy over the rings that only involve atoms/bonds in this fragment:
-  if (mol.getRingInfo()->isInitialized()) {
-    tmol.getRingInfo()->reset();
-    tmol.getRingInfo()->initialize();
-    for (unsigned int ridx = 0; ridx < mol.getRingInfo()->numRings(); ++ridx) {
-      const INT_VECT &aring = mol.getRingInfo()->atomRings()[ridx];
-      bool keepIt = true;
-      for (auto aidx : aring) {
-        if (!atomsInPlay[aidx]) {
-          keepIt = false;
-          break;
-        }
-      }
-      if (keepIt) {
-        const INT_VECT &bring = mol.getRingInfo()->bondRings()[ridx];
-        for (auto bidx : bring) {
-          if (!bondsInPlay[bidx]) {
-            keepIt = false;
-            break;
-          }
-        }
-        if (keepIt) {
-          tmol.getRingInfo()->addRing(aring, bring);
-        }
-      }
-    }
-  }
   if (tmol.needsUpdatePropertyCache()) {
     for (auto atom : tmol.atoms()) {
       atom->updatePropertyCache(false);


Test patch:
diff --git a/Code/GraphMol/SmilesParse/test.cpp b/Code/GraphMol/SmilesParse/test.cpp
index 4e272cb66b0..f62a6674529 100644
--- a/Code/GraphMol/SmilesParse/test.cpp
+++ b/Code/GraphMol/SmilesParse/test.cpp
@@ -4360,6 +4360,27 @@ void testGithub3967() {
   BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
 }
 
+void testGithub3998() {
+  BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
+  BOOST_LOG(rdInfoLog) << "Testing Github 3998: MolFragmentToSmiles with "
+                          "kekuleSmiles=True raises AtomKekulizeException"
+                       << std::endl;
+  {
+    RWMol *m;
+    std::string smiles = "CC(c1ccccc1)";
+    m = SmilesToMol(smiles);
+    TEST_ASSERT(m);
+    int as[] = {0};
+    std::vector<int> atomsToUse(as, as + sizeof(as) / sizeof(int));
+    std::string smi = MolFragmentToSmiles(*m, atomsToUse, nullptr, nullptr, 
+                                               nullptr, true, true);
+    TEST_ASSERT(smi == "C");                                             
+    delete m;
+  }
+
+  BOOST_LOG(rdInfoLog) << "done" << std::endl;
+}
+
 int main(int argc, char *argv[]) {
   (void)argc;
   (void)argv;
@@ -4439,6 +4460,7 @@ int main(int argc, char *argv[]) {
   testGithub1028();
   testGithub3139();
   testGithub3967();
+  testGithub3998();
 #endif
   testOSSFuzzFailures();
 }