From 1cefbfb3ee5c9dd9ca98b2490c60e87412a23cf1 Mon Sep 17 00:00:00 2001 From: Yechen Qiao Date: Tue, 14 May 2024 16:34:11 -0400 Subject: [PATCH 1/5] =?UTF-8?q?[Sapio]=20[CHEMBUGS-184]=20In=20molfile=5Fs?= =?UTF-8?q?aver.cpp,=20we=20need=20to=20change=20it=20so=20the=20BEGIN=20S?= =?UTF-8?q?GROUP=20is=20before=20BEGIN=20COLLECTION=20This=20is=20consiste?= =?UTF-8?q?nt=20with=20RDKIt=20in=20https://github.com/rdkit/rdkit/blob/ma?= =?UTF-8?q?ster/Code/GraphMol/FileParsers/MolFileParser.cpp=20=20and=20tha?= =?UTF-8?q?t=20of=20the=20manual=20in=20https://www.daylight.com/meetings/?= =?UTF-8?q?mug05/Kappler/ctfile.pdf=20(Page=2085=20vs=2090)=20RDKIT=20will?= =?UTF-8?q?=20fail=20the=20load=20if=20the=20BEGIN=20SGROUP=20is=20after?= =?UTF-8?q?=20BEGIN=20COLLECTION.=20Also,=20while=20loading=20CTAB=20v2000?= =?UTF-8?q?/v3000,=20the=20add=20implicit=20h=20=E2=80=9Cadd=5Fimplicit=5F?= =?UTF-8?q?h=E2=80=9D=20adds=20s=20groups=20after=20the=20number=20of=20s?= =?UTF-8?q?=20group=20counts=20is=20already=20written=20in=20the=20header.?= =?UTF-8?q?=20So=20if=20that=20was=20ever=20executed,=20RKit=20will=20have?= =?UTF-8?q?=20a=20read=20failure.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../molecule/src/molfile_saver.cpp | 178 +++++++------- core/indigo-core/tests/common.cpp | 9 + core/indigo-core/tests/tests/molecule.cpp | 45 +++- data/reactions/other/stereo_reaction.rxn | 217 ++++++++++++++++++ 4 files changed, 360 insertions(+), 89 deletions(-) create mode 100644 data/reactions/other/stereo_reaction.rxn diff --git a/core/indigo-core/molecule/src/molfile_saver.cpp b/core/indigo-core/molecule/src/molfile_saver.cpp index db45ca31c3..2c753b40bb 100644 --- a/core/indigo-core/molecule/src/molfile_saver.cpp +++ b/core/indigo-core/molecule/src/molfile_saver.cpp @@ -444,6 +444,7 @@ void MolfileSaver::_writeMultiString(Output& output, const char* string, int len void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query) { + add_implicit_h = false; _handleCIP(mol); if (mol.tgroups.getTGroupCount()) _handleMonomers(mol); @@ -787,94 +788,6 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query) output.writeStringCR("M V30 END BOND"); - MoleculeStereocenters& stereocenters = mol.stereocenters; - - if (stereocenters.begin() != stereocenters.end() || mol.hasHighlighting()) - { - output.writeStringCR("M V30 BEGIN COLLECTION"); - - QS_DEF(Array, processed); - - processed.clear_resize(mol.vertexEnd()); - processed.zerofill(); - - for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) - { - if (processed[i]) - continue; - - ArrayOutput out(buf); - int j, type = stereocenters.getType(i); - - if (type == MoleculeStereocenters::ATOM_ABS) - out.writeString("MDLV30/STEABS ATOMS=("); - else if (type == MoleculeStereocenters::ATOM_OR) - out.printf("MDLV30/STEREL%d ATOMS=(", stereocenters.getGroup(i)); - else if (type == MoleculeStereocenters::ATOM_AND) - out.printf("MDLV30/STERAC%d ATOMS=(", stereocenters.getGroup(i)); - else - continue; - - QS_DEF(Array, list); - - list.clear(); - list.push(i); - - for (j = mol.vertexNext(i); j < mol.vertexEnd(); j = mol.vertexNext(j)) - if (stereocenters.sameGroup(i, j)) - { - list.push(j); - processed[j] = 1; - } - - out.printf("%d", list.size()); - for (j = 0; j < list.size(); j++) - out.printf(" %d", _atom_mapping[list[j]]); - out.writeChar(')'); - - _writeMultiString(output, buf.ptr(), buf.size()); - } - - if (mol.hasHighlighting()) - { - if (mol.countHighlightedBonds() > 0) - { - ArrayOutput out(buf); - - out.printf("MDLV30/HILITE BONDS=(%d", mol.countHighlightedBonds()); - - for (i = mol.edgeBegin(); i != mol.edgeEnd(); i = mol.edgeNext(i)) - if (mol.isBondHighlighted(i)) - out.printf(" %d", _bond_mapping[i]); - out.writeChar(')'); - - _writeMultiString(output, buf.ptr(), buf.size()); - } - if (mol.countHighlightedAtoms() > 0) - { - ArrayOutput out(buf); - out.printf("MDLV30/HILITE ATOMS=(%d", mol.countHighlightedAtoms()); - for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) - if (mol.isAtomHighlighted(i)) - out.printf(" %d", _atom_mapping[i]); - out.writeChar(')'); - - _writeMultiString(output, buf.ptr(), buf.size()); - } - } - if (mol.custom_collections.size() > 0) - { - for (i = mol.custom_collections.begin(); i != mol.custom_collections.end(); i = mol.custom_collections.next(i)) - { - ArrayOutput out(buf); - out.printf("%s", mol.custom_collections.at(i)); - _writeMultiString(output, buf.ptr(), buf.size()); - } - } - - output.writeStringCR("M V30 END COLLECTION"); - } - QS_DEF(Array, sgs_sorted); _checkSGroupIndices(mol, sgs_sorted); @@ -1074,6 +987,94 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query) _removeImplicitSGroups(mol, implicit_sgroups_indexes); } + MoleculeStereocenters& stereocenters = mol.stereocenters; + + if (stereocenters.begin() != stereocenters.end() || mol.hasHighlighting()) + { + output.writeStringCR("M V30 BEGIN COLLECTION"); + + QS_DEF(Array, processed); + + processed.clear_resize(mol.vertexEnd()); + processed.zerofill(); + + for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) + { + if (processed[i]) + continue; + + ArrayOutput out(buf); + int j, type = stereocenters.getType(i); + + if (type == MoleculeStereocenters::ATOM_ABS) + out.writeString("MDLV30/STEABS ATOMS=("); + else if (type == MoleculeStereocenters::ATOM_OR) + out.printf("MDLV30/STEREL%d ATOMS=(", stereocenters.getGroup(i)); + else if (type == MoleculeStereocenters::ATOM_AND) + out.printf("MDLV30/STERAC%d ATOMS=(", stereocenters.getGroup(i)); + else + continue; + + QS_DEF(Array, list); + + list.clear(); + list.push(i); + + for (j = mol.vertexNext(i); j < mol.vertexEnd(); j = mol.vertexNext(j)) + if (stereocenters.sameGroup(i, j)) + { + list.push(j); + processed[j] = 1; + } + + out.printf("%d", list.size()); + for (j = 0; j < list.size(); j++) + out.printf(" %d", _atom_mapping[list[j]]); + out.writeChar(')'); + + _writeMultiString(output, buf.ptr(), buf.size()); + } + + if (mol.hasHighlighting()) + { + if (mol.countHighlightedBonds() > 0) + { + ArrayOutput out(buf); + + out.printf("MDLV30/HILITE BONDS=(%d", mol.countHighlightedBonds()); + + for (i = mol.edgeBegin(); i != mol.edgeEnd(); i = mol.edgeNext(i)) + if (mol.isBondHighlighted(i)) + out.printf(" %d", _bond_mapping[i]); + out.writeChar(')'); + + _writeMultiString(output, buf.ptr(), buf.size()); + } + if (mol.countHighlightedAtoms() > 0) + { + ArrayOutput out(buf); + out.printf("MDLV30/HILITE ATOMS=(%d", mol.countHighlightedAtoms()); + for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) + if (mol.isAtomHighlighted(i)) + out.printf(" %d", _atom_mapping[i]); + out.writeChar(')'); + + _writeMultiString(output, buf.ptr(), buf.size()); + } + } + if (mol.custom_collections.size() > 0) + { + for (i = mol.custom_collections.begin(); i != mol.custom_collections.end(); i = mol.custom_collections.next(i)) + { + ArrayOutput out(buf); + out.printf("%s", mol.custom_collections.at(i)); + _writeMultiString(output, buf.ptr(), buf.size()); + } + } + + output.writeStringCR("M V30 END COLLECTION"); + } + output.writeStringCR("M V30 END CTAB"); int n_rgroups = mol.rgroups.getRGroupCount(); @@ -1212,6 +1213,7 @@ void MolfileSaver::_writeTGroup(Output& output, BaseMolecule& mol, int tg_idx) void MolfileSaver::_writeCtab2000(Output& output, BaseMolecule& mol, bool query) { + add_implicit_h = false; _handleCIP(mol); QueryMolecule* qmol = nullptr; diff --git a/core/indigo-core/tests/common.cpp b/core/indigo-core/tests/common.cpp index 9dafb72df0..69a38f253e 100644 --- a/core/indigo-core/tests/common.cpp +++ b/core/indigo-core/tests/common.cpp @@ -1,4 +1,6 @@ #include "common.h" +#include "reaction/reaction.h" +#include "reaction/reaction_auto_loader.h" #include "reaction/reaction_cml_saver.h" #include "reaction/reaction_json_saver.h" #include "reaction/rxnfile_saver.h" @@ -25,6 +27,13 @@ void IndigoCoreTest::loadMolecule(const char* buf, Molecule& molecule) loader.loadMolecule(molecule); } +void IndigoCoreTest::loadReaction(const char* buf, Reaction& reaction) +{ + BufferScanner scanner(buf); + ReactionAutoLoader loader(scanner); + loader.loadReaction(reaction); +} + void IndigoCoreTest::loadQueryMolecule(const char* buf, QueryMolecule& queryMolecule) { BufferScanner scanner(buf); diff --git a/core/indigo-core/tests/tests/molecule.cpp b/core/indigo-core/tests/tests/molecule.cpp index 35630248fb..0401e9eb7e 100644 --- a/core/indigo-core/tests/tests/molecule.cpp +++ b/core/indigo-core/tests/tests/molecule.cpp @@ -15,11 +15,12 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ - +#include #include #include #include +#include #include #include #include @@ -29,6 +30,11 @@ #include #include "common.h" +#include "molecule/elements.h" +#include "molecule/molfile_saver.h" +#include "reaction/reaction.h" +#include "reaction/reaction_auto_loader.h" +#include "reaction/reaction_automapper.h" using namespace std; using namespace indigo; @@ -352,3 +358,40 @@ TEST_F(IndigoCoreMoleculeTest, dearomatize_smarts) // printf("%s", sm.c_str()); EXPECT_STREQ("c1-c=c-c=c-c=1", sm.c_str()); } + +TEST_F(IndigoCoreMoleculeTest, Reaction) +{ + Reaction reaction; + { + char dir[250]; + getcwd(dir, 250); + cout << "Current directory: " << dir << "\n"; + ifstream reactionFile("../../data/reactions/other/stereo_reaction.rxn"); + string content; + string line; + while (getline(reactionFile, line)) + { + content += line; + content.push_back('\n'); + } + reactionFile.close(); + // cout << "The content is: \n" << content << "\n"; + cout << "Loading reaction..."; + loadReaction(content.c_str(), reaction); + + reaction.aromatize(AromaticityOptions(AromaticityOptions::GENERIC)); + ReactionAutomapper ram(reaction); + ram.automap(0); + + for (int i = reaction.productBegin(); i < reaction.productEnd(); i = reaction.productNext(i)) + { + cout << " *** Current Product Index is: " << i << " *** \n"; + Molecule& mol = reaction.getMolecule(i); + string molOutStr; + StringOutput molOut(molOutStr); + MolfileSaver molSaver(molOut); + molSaver.saveMolecule(mol); + cout << molOutStr; + } + } +} \ No newline at end of file diff --git a/data/reactions/other/stereo_reaction.rxn b/data/reactions/other/stereo_reaction.rxn new file mode 100644 index 0000000000..fa2fc41435 --- /dev/null +++ b/data/reactions/other/stereo_reaction.rxn @@ -0,0 +1,217 @@ +$RXN + + Mrv2305 052320232337 + + 2 1 +$MOL + + Mrv2305 05232323372D + + 18 19 0 0 0 0 999 V2000 + -6.9420 -0.0902 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -7.6565 -0.5027 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -7.6565 -1.3278 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -6.9420 -1.7402 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + -6.2275 -1.3278 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -6.2275 -0.5027 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + -5.5357 0.0000 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 + -4.7511 -0.2549 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -4.2661 0.4125 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 + -4.7510 1.0800 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 + -5.5356 0.8250 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 + -3.4411 0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -6.2031 1.3100 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + -4.4961 1.8646 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -5.4066 1.6399 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -8.3709 -1.7403 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -5.5130 -1.7403 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -2.8891 1.0256 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 2 3 1 0 0 0 0 + 9 10 1 0 0 0 0 + 10 11 1 0 0 0 0 + 7 11 1 0 0 0 0 + 9 12 1 1 0 0 0 + 3 16 2 0 0 0 0 + 5 17 2 0 0 0 0 + 8 9 1 0 0 0 0 + 7 8 1 0 0 0 0 + 10 14 1 6 0 0 0 + 12 18 1 0 0 0 0 + 11 15 1 1 0 0 0 + 11 13 1 6 0 0 0 + 1 6 1 0 0 0 0 + 5 6 1 0 0 0 0 + 7 6 1 1 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 +M STY 1 1 SUP +M SAL 1 1 15 +M SBL 1 1 13 +M SMT 1 Me +M SAP 1 1 15 11 1 +M END +$MOL + + Mrv2305 05232323372D + + 24 26 0 0 0 0 999 V2000 + -4.7105 -3.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 -0.2125 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + -4.7106 -2.2750 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -3.9961 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -3.9961 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -3.2816 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -2.5671 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -2.5671 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -3.2816 -2.2750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.8527 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.8527 0.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -2.5672 0.6126 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -2.5671 1.4375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.8527 1.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 1.4376 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 0.6125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -0.4237 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.2907 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.2907 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.0052 -2.2750 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.7197 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -0.4237 -2.2750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10 2 1 0 0 0 0 + 1 3 1 0 0 0 0 + 3 4 1 0 0 0 0 + 4 5 2 0 0 0 0 + 4 9 1 0 0 0 0 + 5 6 1 0 0 0 0 + 6 7 2 0 0 0 0 + 7 8 1 0 0 0 0 + 7 10 1 0 0 0 0 + 8 9 2 0 0 0 0 + 10 11 1 0 0 0 0 + 10 17 1 0 0 0 0 + 11 12 2 0 0 0 0 + 11 16 1 0 0 0 0 + 12 13 1 0 0 0 0 + 13 14 2 0 0 0 0 + 14 15 1 0 0 0 0 + 15 16 2 0 0 0 0 + 17 18 2 0 0 0 0 + 17 24 1 0 0 0 0 + 18 19 1 0 0 0 0 + 19 20 2 0 0 0 0 + 20 21 1 0 0 0 0 + 20 23 1 0 0 0 0 + 21 22 1 0 0 0 0 + 23 24 2 0 0 0 0 +M STY 1 1 SUP +M SAL 1 15 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +M SAL 1 8 17 18 19 20 21 22 23 24 +M SBL 1 1 1 +M SMT 1 DMTr +M SAP 1 1 10 2 1 +M END +$MOL + + Mrv2305 05232323372D + + 41 45 0 0 0 0 999 V2000 + 2.9291 -0.1300 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.2146 -0.5425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.2146 -1.3676 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.9291 -1.7800 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6436 -1.3676 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6436 -0.5425 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3354 -0.0398 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 + 5.1200 -0.2947 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 5.6049 0.3727 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 + 5.1200 1.0402 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 + 4.3354 0.7852 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 + 6.4299 0.3727 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6680 1.2701 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 5.3749 1.8248 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.4645 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.5002 -1.7801 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3581 -1.7801 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.9820 0.9858 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5195 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1070 0.9858 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 10.2820 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.8695 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.0445 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.6320 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.0445 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.8695 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8070 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3945 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8070 -0.4432 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3945 -1.1576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.5695 -1.1576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1570 -0.4432 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.5695 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3945 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.5695 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1570 2.4147 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.5695 3.1292 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1570 3.8437 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 5.3320 3.8437 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3945 3.1292 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8070 2.4147 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 2 3 1 0 0 0 0 + 9 10 1 0 0 0 0 + 10 11 1 0 0 0 0 + 7 11 1 0 0 0 0 + 9 12 1 1 0 0 0 + 3 16 2 0 0 0 0 + 5 17 2 0 0 0 0 + 8 9 1 0 0 0 0 + 7 8 1 0 0 0 0 + 10 14 1 6 0 0 0 + 12 18 1 0 0 0 0 + 11 15 1 1 0 0 0 + 11 13 1 6 0 0 0 + 1 6 1 0 0 0 0 + 5 6 1 0 0 0 0 + 7 6 1 1 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 + 18 27 1 0 0 0 0 + 19 20 1 0 0 0 0 + 20 21 1 0 0 0 0 + 21 22 2 0 0 0 0 + 21 26 1 0 0 0 0 + 22 23 1 0 0 0 0 + 23 24 2 0 0 0 0 + 24 25 1 0 0 0 0 + 24 27 1 0 0 0 0 + 25 26 2 0 0 0 0 + 27 28 1 0 0 0 0 + 27 34 1 0 0 0 0 + 28 29 2 0 0 0 0 + 28 33 1 0 0 0 0 + 29 30 1 0 0 0 0 + 30 31 2 0 0 0 0 + 31 32 1 0 0 0 0 + 32 33 2 0 0 0 0 + 34 35 2 0 0 0 0 + 34 41 1 0 0 0 0 + 35 36 1 0 0 0 0 + 36 37 2 0 0 0 0 + 37 38 1 0 0 0 0 + 37 40 1 0 0 0 0 + 38 39 1 0 0 0 0 + 40 41 2 0 0 0 0 +M STY 2 1 SUP 2 SUP +M SAL 1 1 15 +M SBL 1 1 13 +M SMT 1 Me +M SAP 1 1 15 11 1 +M SAL 2 15 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 +M SAL 2 8 34 35 36 37 38 39 40 41 +M SBL 2 1 20 +M SMT 2 DMTr +M SAP 2 1 27 18 1 +M END From 4b0267b54764435caedc268d83a2535c2b4f33fb Mon Sep 17 00:00:00 2001 From: Yechen Qiao Date: Fri, 6 Mar 2026 15:32:12 -0500 Subject: [PATCH 2/5] [Sapio] [CHEMBUGS-184] removed old hack on turning off implicit hydrogen counts added earlier for Issue 1 in https://github.com/epam/Indigo/issues/2109. Added more unit tests. Tested manually and confirmed original problem went away. --- .../molecule/src/molfile_saver.cpp | 1 - core/indigo-core/tests/tests/molecule.cpp | 67 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/core/indigo-core/molecule/src/molfile_saver.cpp b/core/indigo-core/molecule/src/molfile_saver.cpp index 2c753b40bb..927f34579f 100644 --- a/core/indigo-core/molecule/src/molfile_saver.cpp +++ b/core/indigo-core/molecule/src/molfile_saver.cpp @@ -444,7 +444,6 @@ void MolfileSaver::_writeMultiString(Output& output, const char* string, int len void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query) { - add_implicit_h = false; _handleCIP(mol); if (mol.tgroups.getTGroupCount()) _handleMonomers(mol); diff --git a/core/indigo-core/tests/tests/molecule.cpp b/core/indigo-core/tests/tests/molecule.cpp index 0401e9eb7e..bc4fc0ced6 100644 --- a/core/indigo-core/tests/tests/molecule.cpp +++ b/core/indigo-core/tests/tests/molecule.cpp @@ -31,6 +31,7 @@ #include "common.h" #include "molecule/elements.h" +#include "molecule/molfile_loader.h" #include "molecule/molfile_saver.h" #include "reaction/reaction.h" #include "reaction/reaction_auto_loader.h" @@ -359,6 +360,72 @@ TEST_F(IndigoCoreMoleculeTest, dearomatize_smarts) EXPECT_STREQ("c1-c=c-c=c-c=1", sm.c_str()); } +/* + * V3000 molfile roundtrip with add_implicit_h = true. + * Ensures SGROUP block is written before COLLECTION (CT file spec order) and + * that implicit H (e.g. MRV_IMPLICIT_H data sgroups) roundtrip correctly. + */ +TEST_F(IndigoCoreMoleculeTest, molfileV3000RoundtripImplicitH) +{ + Molecule mol; + loadMolecule("c1ccccc1O", mol); // phenol: aromatic carbons have implicit H + + string molfileStr; + StringOutput out(molfileStr); + MolfileSaver saver(out); + saver.mode = MolfileSaver::MODE_3000; + saver.add_implicit_h = true; + saver.saveMolecule(mol); + + // CT file order: SGROUP block must appear before COLLECTION block + size_t posSgroup = molfileStr.find("M V30 BEGIN SGROUP"); + size_t posCollection = molfileStr.find("M V30 BEGIN COLLECTION"); + if (posSgroup != string::npos && posCollection != string::npos) + EXPECT_LT(posSgroup, posCollection) << "SGROUP must be written before COLLECTION (CT file spec)"; + + BufferScanner scanner(molfileStr.c_str()); + MolfileLoader loader(scanner); + Molecule mol2; + loader.loadMolecule(mol2); + + EXPECT_EQ(mol.vertexCount(), mol2.vertexCount()) << "Roundtrip: atom count must match"; + EXPECT_EQ(mol.edgeCount(), mol2.edgeCount()) << "Roundtrip: bond count must match"; + // Same structure: roundtrip mol2 should match original as substructure and vice versa + EXPECT_TRUE(substructureMatch(smiles(mol2).c_str(), smiles(mol).c_str())); + EXPECT_TRUE(substructureMatch(smiles(mol).c_str(), smiles(mol2).c_str())); +} + +/* + * V3000 molfile roundtrip with add_implicit_h = false (explicit H only). + * Ensures molecules without MRV_IMPLICIT_H sgroups roundtrip correctly. + */ +TEST_F(IndigoCoreMoleculeTest, molfileV3000RoundtripExplicitH) +{ + Molecule mol; + loadMolecule("CCO", mol); + + string molfileStr; + StringOutput out(molfileStr); + MolfileSaver saver(out); + saver.mode = MolfileSaver::MODE_3000; + saver.add_implicit_h = false; + saver.saveMolecule(mol); + + size_t posSgroup = molfileStr.find("M V30 BEGIN SGROUP"); + size_t posCollection = molfileStr.find("M V30 BEGIN COLLECTION"); + if (posSgroup != string::npos && posCollection != string::npos) + EXPECT_LT(posSgroup, posCollection) << "SGROUP must be written before COLLECTION (CT file spec)"; + + BufferScanner scanner(molfileStr.c_str()); + MolfileLoader loader(scanner); + Molecule mol2; + loader.loadMolecule(mol2); + + EXPECT_EQ(mol.vertexCount(), mol2.vertexCount()) << "Roundtrip: atom count must match"; + EXPECT_EQ(mol.edgeCount(), mol2.edgeCount()) << "Roundtrip: bond count must match"; + EXPECT_STREQ(smiles(mol).c_str(), smiles(mol2).c_str()) << "Roundtrip: SMILES must match"; +} + TEST_F(IndigoCoreMoleculeTest, Reaction) { Reaction reaction; From e4ce543220e55d73dff939a0d111fc61ad40cd3c Mon Sep 17 00:00:00 2001 From: Yechen Qiao Date: Thu, 12 Mar 2026 08:42:52 -0400 Subject: [PATCH 3/5] clang format and windows env fix. --- core/indigo-core/tests/tests/molecule.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/indigo-core/tests/tests/molecule.cpp b/core/indigo-core/tests/tests/molecule.cpp index bc4fc0ced6..65fdef5f62 100644 --- a/core/indigo-core/tests/tests/molecule.cpp +++ b/core/indigo-core/tests/tests/molecule.cpp @@ -15,7 +15,13 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ + +#ifdef _WIN32 +#include +#define getcwd _getcwd +#else #include +#endif #include #include From 4efd18b4d77291f0a6d6bb8a28f070a213c1d8a5 Mon Sep 17 00:00:00 2001 From: Yechen Qiao Date: Thu, 12 Mar 2026 11:03:26 -0400 Subject: [PATCH 4/5] CHEMBUGS-184 Merge Up Fixes. 1. Use the old ordering unless S-Group block is actively being used. 2. Changed unit test on molecule.cpp so that it is no longer testing reaction but individual problematic molecules in reaction. --- .../molecule/src/molfile_saver.cpp | 196 ++++++----- core/indigo-core/tests/tests/molecule.cpp | 333 ++++++++++++------ data/reactions/other/stereo_reaction.rxn | 217 ------------ 3 files changed, 340 insertions(+), 406 deletions(-) delete mode 100644 data/reactions/other/stereo_reaction.rxn diff --git a/core/indigo-core/molecule/src/molfile_saver.cpp b/core/indigo-core/molecule/src/molfile_saver.cpp index 927f34579f..6d638c69c1 100644 --- a/core/indigo-core/molecule/src/molfile_saver.cpp +++ b/core/indigo-core/molecule/src/molfile_saver.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "base_cpp/locale_guard.h" #include "base_cpp/output.h" @@ -790,7 +791,110 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query) QS_DEF(Array, sgs_sorted); _checkSGroupIndices(mol, sgs_sorted); - if (mol.countSGroups() > 0) + //[Sapio] [CHEMBUGS-184] S-GROUP needs to be before COLLECTION when S GROUP is used. + const bool has_sgroups = (mol.countSGroups() > 0); + MoleculeStereocenters& stereocenters = mol.stereocenters; + const bool has_collection = (stereocenters.begin() != stereocenters.end() || mol.hasHighlighting() || mol.custom_collections.size() > 0); + const bool sgroup_collection_order_reversed = (has_sgroups && has_collection); + + // Default order: COLLECTION before SGROUP. + // When sgroup_collection_order_reversed, write SGROUP then COLLECTION (CT spec) page 22. + std::string collection_str; + StringOutput collection_buf(collection_str); + Output* collection_dest_ptr; + if (sgroup_collection_order_reversed) + collection_dest_ptr = static_cast(&collection_buf); + else + collection_dest_ptr = &output; + Output& collection_dest = *collection_dest_ptr; + + if (has_collection) + { + collection_dest.writeStringCR("M V30 BEGIN COLLECTION"); + + QS_DEF(Array, processed); + + processed.clear_resize(mol.vertexEnd()); + processed.zerofill(); + + for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) + { + if (processed[i]) + continue; + + ArrayOutput out(buf); + int j, type = stereocenters.getType(i); + + if (type == MoleculeStereocenters::ATOM_ABS) + out.writeString("MDLV30/STEABS ATOMS=("); + else if (type == MoleculeStereocenters::ATOM_OR) + out.printf("MDLV30/STEREL%d ATOMS=(", stereocenters.getGroup(i)); + else if (type == MoleculeStereocenters::ATOM_AND) + out.printf("MDLV30/STERAC%d ATOMS=(", stereocenters.getGroup(i)); + else + continue; + + QS_DEF(Array, list); + + list.clear(); + list.push(i); + + for (j = mol.vertexNext(i); j < mol.vertexEnd(); j = mol.vertexNext(j)) + if (stereocenters.sameGroup(i, j)) + { + list.push(j); + processed[j] = 1; + } + + out.printf("%d", list.size()); + for (j = 0; j < list.size(); j++) + out.printf(" %d", _atom_mapping[list[j]]); + out.writeChar(')'); + + _writeMultiString(collection_dest, buf.ptr(), buf.size()); + } + + if (mol.hasHighlighting()) + { + if (mol.countHighlightedBonds() > 0) + { + ArrayOutput out(buf); + + out.printf("MDLV30/HILITE BONDS=(%d", mol.countHighlightedBonds()); + + for (i = mol.edgeBegin(); i != mol.edgeEnd(); i = mol.edgeNext(i)) + if (mol.isBondHighlighted(i)) + out.printf(" %d", _bond_mapping[i]); + out.writeChar(')'); + + _writeMultiString(collection_dest, buf.ptr(), buf.size()); + } + if (mol.countHighlightedAtoms() > 0) + { + ArrayOutput out(buf); + out.printf("MDLV30/HILITE ATOMS=(%d", mol.countHighlightedAtoms()); + for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) + if (mol.isAtomHighlighted(i)) + out.printf(" %d", _atom_mapping[i]); + out.writeChar(')'); + + _writeMultiString(collection_dest, buf.ptr(), buf.size()); + } + } + if (mol.custom_collections.size() > 0) + { + for (i = mol.custom_collections.begin(); i != mol.custom_collections.end(); i = mol.custom_collections.next(i)) + { + ArrayOutput out(buf); + out.printf("%s", mol.custom_collections.at(i)); + _writeMultiString(collection_dest, buf.ptr(), buf.size()); + } + } + + collection_dest.writeStringCR("M V30 END COLLECTION"); + } + + if (has_sgroups) { MoleculeSGroups* sgroups = &mol.sgroups; int idx = 1; @@ -986,93 +1090,8 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query) _removeImplicitSGroups(mol, implicit_sgroups_indexes); } - MoleculeStereocenters& stereocenters = mol.stereocenters; - - if (stereocenters.begin() != stereocenters.end() || mol.hasHighlighting()) - { - output.writeStringCR("M V30 BEGIN COLLECTION"); - - QS_DEF(Array, processed); - - processed.clear_resize(mol.vertexEnd()); - processed.zerofill(); - - for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) - { - if (processed[i]) - continue; - - ArrayOutput out(buf); - int j, type = stereocenters.getType(i); - - if (type == MoleculeStereocenters::ATOM_ABS) - out.writeString("MDLV30/STEABS ATOMS=("); - else if (type == MoleculeStereocenters::ATOM_OR) - out.printf("MDLV30/STEREL%d ATOMS=(", stereocenters.getGroup(i)); - else if (type == MoleculeStereocenters::ATOM_AND) - out.printf("MDLV30/STERAC%d ATOMS=(", stereocenters.getGroup(i)); - else - continue; - - QS_DEF(Array, list); - - list.clear(); - list.push(i); - - for (j = mol.vertexNext(i); j < mol.vertexEnd(); j = mol.vertexNext(j)) - if (stereocenters.sameGroup(i, j)) - { - list.push(j); - processed[j] = 1; - } - - out.printf("%d", list.size()); - for (j = 0; j < list.size(); j++) - out.printf(" %d", _atom_mapping[list[j]]); - out.writeChar(')'); - - _writeMultiString(output, buf.ptr(), buf.size()); - } - - if (mol.hasHighlighting()) - { - if (mol.countHighlightedBonds() > 0) - { - ArrayOutput out(buf); - - out.printf("MDLV30/HILITE BONDS=(%d", mol.countHighlightedBonds()); - - for (i = mol.edgeBegin(); i != mol.edgeEnd(); i = mol.edgeNext(i)) - if (mol.isBondHighlighted(i)) - out.printf(" %d", _bond_mapping[i]); - out.writeChar(')'); - - _writeMultiString(output, buf.ptr(), buf.size()); - } - if (mol.countHighlightedAtoms() > 0) - { - ArrayOutput out(buf); - out.printf("MDLV30/HILITE ATOMS=(%d", mol.countHighlightedAtoms()); - for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) - if (mol.isAtomHighlighted(i)) - out.printf(" %d", _atom_mapping[i]); - out.writeChar(')'); - - _writeMultiString(output, buf.ptr(), buf.size()); - } - } - if (mol.custom_collections.size() > 0) - { - for (i = mol.custom_collections.begin(); i != mol.custom_collections.end(); i = mol.custom_collections.next(i)) - { - ArrayOutput out(buf); - out.printf("%s", mol.custom_collections.at(i)); - _writeMultiString(output, buf.ptr(), buf.size()); - } - } - - output.writeStringCR("M V30 END COLLECTION"); - } + if (sgroup_collection_order_reversed) + output.write(collection_str.data(), static_cast(collection_str.size())); output.writeStringCR("M V30 END CTAB"); @@ -1212,7 +1231,6 @@ void MolfileSaver::_writeTGroup(Output& output, BaseMolecule& mol, int tg_idx) void MolfileSaver::_writeCtab2000(Output& output, BaseMolecule& mol, bool query) { - add_implicit_h = false; _handleCIP(mol); QueryMolecule* qmol = nullptr; diff --git a/core/indigo-core/tests/tests/molecule.cpp b/core/indigo-core/tests/tests/molecule.cpp index 65fdef5f62..3d569d1ca2 100644 --- a/core/indigo-core/tests/tests/molecule.cpp +++ b/core/indigo-core/tests/tests/molecule.cpp @@ -16,32 +16,21 @@ * limitations under the License. ***************************************************************************/ -#ifdef _WIN32 -#include -#define getcwd _getcwd -#else -#include -#endif #include #include #include -#include #include #include #include #include +#include #include #include #include #include "common.h" #include "molecule/elements.h" -#include "molecule/molfile_loader.h" -#include "molecule/molfile_saver.h" -#include "reaction/reaction.h" -#include "reaction/reaction_auto_loader.h" -#include "reaction/reaction_automapper.h" using namespace std; using namespace indigo; @@ -366,105 +355,249 @@ TEST_F(IndigoCoreMoleculeTest, dearomatize_smarts) EXPECT_STREQ("c1-c=c-c=c-c=1", sm.c_str()); } -/* - * V3000 molfile roundtrip with add_implicit_h = true. - * Ensures SGROUP block is written before COLLECTION (CT file spec order) and - * that implicit H (e.g. MRV_IMPLICIT_H data sgroups) roundtrip correctly. - */ -TEST_F(IndigoCoreMoleculeTest, molfileV3000RoundtripImplicitH) +// [Sapio] [CHEMBUGS-184] Stereo reaction molecules (from former stereo_reaction.rxn): load as mol blocks to verify parsing. +namespace { - Molecule mol; - loadMolecule("c1ccccc1O", mol); // phenol: aromatic carbons have implicit H - - string molfileStr; - StringOutput out(molfileStr); - MolfileSaver saver(out); - saver.mode = MolfileSaver::MODE_3000; - saver.add_implicit_h = true; - saver.saveMolecule(mol); + const char* const stereoReactionReactant1 = R"( + Mrv2305 05232323372D - // CT file order: SGROUP block must appear before COLLECTION block - size_t posSgroup = molfileStr.find("M V30 BEGIN SGROUP"); - size_t posCollection = molfileStr.find("M V30 BEGIN COLLECTION"); - if (posSgroup != string::npos && posCollection != string::npos) - EXPECT_LT(posSgroup, posCollection) << "SGROUP must be written before COLLECTION (CT file spec)"; + 18 19 0 0 0 0 999 V2000 + -6.9420 -0.0902 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -7.6565 -0.5027 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -7.6565 -1.3278 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -6.9420 -1.7402 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + -6.2275 -1.3278 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -6.2275 -0.5027 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + -5.5357 0.0000 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 + -4.7511 -0.2549 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -4.2661 0.4125 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 + -4.7510 1.0800 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 + -5.5356 0.8250 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 + -3.4411 0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -6.2031 1.3100 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + -4.4961 1.8646 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -5.4066 1.6399 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -8.3709 -1.7403 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -5.5130 -1.7403 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -2.8891 1.0256 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 2 3 1 0 0 0 0 + 9 10 1 0 0 0 0 + 10 11 1 0 0 0 0 + 7 11 1 0 0 0 0 + 9 12 1 1 0 0 0 + 3 16 2 0 0 0 0 + 5 17 2 0 0 0 0 + 8 9 1 0 0 0 0 + 7 8 1 0 0 0 0 + 10 14 1 6 0 0 0 + 12 18 1 0 0 0 0 + 11 15 1 1 0 0 0 + 11 13 1 6 0 0 0 + 1 6 1 0 0 0 0 + 5 6 1 0 0 0 0 + 7 6 1 1 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 +M STY 1 1 SUP +M SAL 1 1 15 +M SBL 1 1 13 +M SMT 1 Me +M SAP 1 1 15 11 1 +M END +)"; + const char* const stereoReactionReactant2 = R"( + Mrv2305 05232323372D - BufferScanner scanner(molfileStr.c_str()); - MolfileLoader loader(scanner); - Molecule mol2; - loader.loadMolecule(mol2); + 24 26 0 0 0 0 999 V2000 + -4.7105 -3.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 -0.2125 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + -4.7106 -2.2750 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + -3.9961 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -3.9961 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -3.2816 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -2.5671 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -2.5671 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -3.2816 -2.2750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.8527 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.8527 0.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -2.5672 0.6126 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -2.5671 1.4375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.8527 1.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 1.4376 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 0.6125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -0.4237 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.2907 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.2907 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.0052 -2.2750 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.7197 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -0.4237 -2.2750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.1382 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10 2 1 0 0 0 0 + 1 3 1 0 0 0 0 + 3 4 1 0 0 0 0 + 4 5 2 0 0 0 0 + 4 9 1 0 0 0 0 + 5 6 1 0 0 0 0 + 6 7 2 0 0 0 0 + 7 8 1 0 0 0 0 + 7 10 1 0 0 0 0 + 8 9 2 0 0 0 0 + 10 11 1 0 0 0 0 + 10 17 1 0 0 0 0 + 11 12 2 0 0 0 0 + 11 16 1 0 0 0 0 + 12 13 1 0 0 0 0 + 13 14 2 0 0 0 0 + 14 15 1 0 0 0 0 + 15 16 2 0 0 0 0 + 17 18 2 0 0 0 0 + 17 24 1 0 0 0 0 + 18 19 1 0 0 0 0 + 19 20 2 0 0 0 0 + 20 21 1 0 0 0 0 + 20 23 1 0 0 0 0 + 21 22 1 0 0 0 0 + 23 24 2 0 0 0 0 +M STY 1 1 SUP +M SAL 1 15 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +M SAL 1 8 17 18 19 20 21 22 23 24 +M SBL 1 1 1 +M SMT 1 DMTr +M SAP 1 1 10 2 1 +M END +)"; + const char* const stereoReactionProduct = R"( + Mrv2305 05232323372D - EXPECT_EQ(mol.vertexCount(), mol2.vertexCount()) << "Roundtrip: atom count must match"; - EXPECT_EQ(mol.edgeCount(), mol2.edgeCount()) << "Roundtrip: bond count must match"; - // Same structure: roundtrip mol2 should match original as substructure and vice versa - EXPECT_TRUE(substructureMatch(smiles(mol2).c_str(), smiles(mol).c_str())); - EXPECT_TRUE(substructureMatch(smiles(mol).c_str(), smiles(mol2).c_str())); + 41 45 0 0 0 0 999 V2000 + 2.9291 -0.1300 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.2146 -0.5425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.2146 -1.3676 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.9291 -1.7800 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6436 -1.3676 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6436 -0.5425 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3354 -0.0398 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 + 5.1200 -0.2947 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 5.6049 0.3727 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 + 5.1200 1.0402 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 + 4.3354 0.7852 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 + 6.4299 0.3727 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6680 1.2701 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 5.3749 1.8248 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.4645 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.5002 -1.7801 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3581 -1.7801 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.9820 0.9858 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5195 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1070 0.9858 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 10.2820 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.8695 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.0445 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.6320 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.0445 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.8695 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8070 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3945 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8070 -0.4432 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3945 -1.1576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.5695 -1.1576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1570 -0.4432 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.5695 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3945 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.5695 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1570 2.4147 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.5695 3.1292 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1570 3.8437 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 5.3320 3.8437 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3945 3.1292 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8070 2.4147 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 2 3 1 0 0 0 0 + 9 10 1 0 0 0 0 + 10 11 1 0 0 0 0 + 7 11 1 0 0 0 0 + 9 12 1 1 0 0 0 + 3 16 2 0 0 0 0 + 5 17 2 0 0 0 0 + 8 9 1 0 0 0 0 + 7 8 1 0 0 0 0 + 10 14 1 6 0 0 0 + 12 18 1 0 0 0 0 + 11 15 1 1 0 0 0 + 11 13 1 6 0 0 0 + 1 6 1 0 0 0 0 + 5 6 1 0 0 0 0 + 7 6 1 1 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 + 18 27 1 0 0 0 0 + 19 20 1 0 0 0 0 + 20 21 1 0 0 0 0 + 21 22 2 0 0 0 0 + 21 26 1 0 0 0 0 + 22 23 1 0 0 0 0 + 23 24 2 0 0 0 0 + 24 25 1 0 0 0 0 + 24 27 1 0 0 0 0 + 25 26 2 0 0 0 0 + 27 28 1 0 0 0 0 + 27 34 1 0 0 0 0 + 28 29 2 0 0 0 0 + 28 33 1 0 0 0 0 + 29 30 1 0 0 0 0 + 30 31 2 0 0 0 0 + 31 32 1 0 0 0 0 + 32 33 2 0 0 0 0 + 34 35 2 0 0 0 0 + 34 41 1 0 0 0 0 + 35 36 1 0 0 0 0 + 36 37 2 0 0 0 0 + 37 38 1 0 0 0 0 + 37 40 1 0 0 0 0 + 38 39 1 0 0 0 0 + 40 41 2 0 0 0 0 +M STY 2 1 SUP 2 SUP +M SAL 1 1 15 +M SBL 1 1 13 +M SMT 1 Me +M SAP 1 1 15 11 1 +M SAL 2 15 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 +M SAL 2 8 34 35 36 37 38 39 40 41 +M SBL 2 1 20 +M SMT 2 DMTr +M SAP 2 1 27 18 1 +M END +)"; } -/* - * V3000 molfile roundtrip with add_implicit_h = false (explicit H only). - * Ensures molecules without MRV_IMPLICIT_H sgroups roundtrip correctly. - */ -TEST_F(IndigoCoreMoleculeTest, molfileV3000RoundtripExplicitH) +TEST_F(IndigoCoreMoleculeTest, stereoReactionReactant1) { Molecule mol; - loadMolecule("CCO", mol); - - string molfileStr; - StringOutput out(molfileStr); - MolfileSaver saver(out); - saver.mode = MolfileSaver::MODE_3000; - saver.add_implicit_h = false; - saver.saveMolecule(mol); - - size_t posSgroup = molfileStr.find("M V30 BEGIN SGROUP"); - size_t posCollection = molfileStr.find("M V30 BEGIN COLLECTION"); - if (posSgroup != string::npos && posCollection != string::npos) - EXPECT_LT(posSgroup, posCollection) << "SGROUP must be written before COLLECTION (CT file spec)"; - - BufferScanner scanner(molfileStr.c_str()); + BufferScanner scanner(stereoReactionReactant1); MolfileLoader loader(scanner); - Molecule mol2; - loader.loadMolecule(mol2); - - EXPECT_EQ(mol.vertexCount(), mol2.vertexCount()) << "Roundtrip: atom count must match"; - EXPECT_EQ(mol.edgeCount(), mol2.edgeCount()) << "Roundtrip: bond count must match"; - EXPECT_STREQ(smiles(mol).c_str(), smiles(mol2).c_str()) << "Roundtrip: SMILES must match"; + loader.loadMolecule(mol); + EXPECT_EQ(18, mol.vertexCount()); + EXPECT_EQ(19, mol.edgeCount()); } -TEST_F(IndigoCoreMoleculeTest, Reaction) +TEST_F(IndigoCoreMoleculeTest, stereoReactionReactant2) { - Reaction reaction; - { - char dir[250]; - getcwd(dir, 250); - cout << "Current directory: " << dir << "\n"; - ifstream reactionFile("../../data/reactions/other/stereo_reaction.rxn"); - string content; - string line; - while (getline(reactionFile, line)) - { - content += line; - content.push_back('\n'); - } - reactionFile.close(); - // cout << "The content is: \n" << content << "\n"; - cout << "Loading reaction..."; - loadReaction(content.c_str(), reaction); - - reaction.aromatize(AromaticityOptions(AromaticityOptions::GENERIC)); - ReactionAutomapper ram(reaction); - ram.automap(0); + Molecule mol; + BufferScanner scanner(stereoReactionReactant2); + MolfileLoader loader(scanner); + loader.loadMolecule(mol); + EXPECT_EQ(24, mol.vertexCount()); + EXPECT_EQ(26, mol.edgeCount()); +} - for (int i = reaction.productBegin(); i < reaction.productEnd(); i = reaction.productNext(i)) - { - cout << " *** Current Product Index is: " << i << " *** \n"; - Molecule& mol = reaction.getMolecule(i); - string molOutStr; - StringOutput molOut(molOutStr); - MolfileSaver molSaver(molOut); - molSaver.saveMolecule(mol); - cout << molOutStr; - } - } +TEST_F(IndigoCoreMoleculeTest, stereoReactionProduct) +{ + Molecule mol; + BufferScanner scanner(stereoReactionProduct); + MolfileLoader loader(scanner); + loader.loadMolecule(mol); + EXPECT_EQ(41, mol.vertexCount()); + EXPECT_EQ(45, mol.edgeCount()); } \ No newline at end of file diff --git a/data/reactions/other/stereo_reaction.rxn b/data/reactions/other/stereo_reaction.rxn deleted file mode 100644 index fa2fc41435..0000000000 --- a/data/reactions/other/stereo_reaction.rxn +++ /dev/null @@ -1,217 +0,0 @@ -$RXN - - Mrv2305 052320232337 - - 2 1 -$MOL - - Mrv2305 05232323372D - - 18 19 0 0 0 0 999 V2000 - -6.9420 -0.0902 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -7.6565 -0.5027 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -7.6565 -1.3278 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -6.9420 -1.7402 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 - -6.2275 -1.3278 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -6.2275 -0.5027 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 - -5.5357 0.0000 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 - -4.7511 -0.2549 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - -4.2661 0.4125 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 - -4.7510 1.0800 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 - -5.5356 0.8250 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 - -3.4411 0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -6.2031 1.3100 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - -4.4961 1.8646 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - -5.4066 1.6399 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -8.3709 -1.7403 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - -5.5130 -1.7403 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - -2.8891 1.0256 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 1 2 2 0 0 0 0 - 2 3 1 0 0 0 0 - 9 10 1 0 0 0 0 - 10 11 1 0 0 0 0 - 7 11 1 0 0 0 0 - 9 12 1 1 0 0 0 - 3 16 2 0 0 0 0 - 5 17 2 0 0 0 0 - 8 9 1 0 0 0 0 - 7 8 1 0 0 0 0 - 10 14 1 6 0 0 0 - 12 18 1 0 0 0 0 - 11 15 1 1 0 0 0 - 11 13 1 6 0 0 0 - 1 6 1 0 0 0 0 - 5 6 1 0 0 0 0 - 7 6 1 1 0 0 0 - 3 4 1 0 0 0 0 - 4 5 1 0 0 0 0 -M STY 1 1 SUP -M SAL 1 1 15 -M SBL 1 1 13 -M SMT 1 Me -M SAP 1 1 15 11 1 -M END -$MOL - - Mrv2305 05232323372D - - 24 26 0 0 0 0 999 V2000 - -4.7105 -3.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -1.1382 -0.2125 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0 - -4.7106 -2.2750 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - -3.9961 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -3.9961 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -3.2816 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -2.5671 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -2.5671 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -3.2816 -2.2750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -1.8527 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -1.8527 0.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -2.5672 0.6126 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -2.5671 1.4375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -1.8527 1.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -1.1382 1.4376 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -1.1382 0.6125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -1.1382 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -0.4237 -0.6250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 0.2907 -1.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 0.2907 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 1.0052 -2.2750 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 1.7197 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -0.4237 -2.2750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - -1.1382 -1.8625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 10 2 1 0 0 0 0 - 1 3 1 0 0 0 0 - 3 4 1 0 0 0 0 - 4 5 2 0 0 0 0 - 4 9 1 0 0 0 0 - 5 6 1 0 0 0 0 - 6 7 2 0 0 0 0 - 7 8 1 0 0 0 0 - 7 10 1 0 0 0 0 - 8 9 2 0 0 0 0 - 10 11 1 0 0 0 0 - 10 17 1 0 0 0 0 - 11 12 2 0 0 0 0 - 11 16 1 0 0 0 0 - 12 13 1 0 0 0 0 - 13 14 2 0 0 0 0 - 14 15 1 0 0 0 0 - 15 16 2 0 0 0 0 - 17 18 2 0 0 0 0 - 17 24 1 0 0 0 0 - 18 19 1 0 0 0 0 - 19 20 2 0 0 0 0 - 20 21 1 0 0 0 0 - 20 23 1 0 0 0 0 - 21 22 1 0 0 0 0 - 23 24 2 0 0 0 0 -M STY 1 1 SUP -M SAL 1 15 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -M SAL 1 8 17 18 19 20 21 22 23 24 -M SBL 1 1 1 -M SMT 1 DMTr -M SAP 1 1 10 2 1 -M END -$MOL - - Mrv2305 05232323372D - - 41 45 0 0 0 0 999 V2000 - 2.9291 -0.1300 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 2.2146 -0.5425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 2.2146 -1.3676 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 2.9291 -1.7800 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 - 3.6436 -1.3676 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 3.6436 -0.5425 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 - 4.3354 -0.0398 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 - 5.1200 -0.2947 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 5.6049 0.3727 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 - 5.1200 1.0402 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0 - 4.3354 0.7852 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0 - 6.4299 0.3727 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 3.6680 1.2701 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 5.3749 1.8248 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 4.4645 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 1.5002 -1.7801 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 4.3581 -1.7801 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 6.9820 0.9858 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 11.5195 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 11.1070 0.9858 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 10.2820 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 9.8695 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 9.0445 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 8.6320 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 9.0445 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 9.8695 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 7.8070 0.9858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 7.3945 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 7.8070 -0.4432 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 7.3945 -1.1576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 6.5695 -1.1576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 6.1570 -0.4432 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 6.5695 0.2713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 7.3945 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 6.5695 1.7003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 6.1570 2.4147 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 6.5695 3.1292 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 6.1570 3.8437 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 5.3320 3.8437 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 7.3945 3.1292 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 7.8070 2.4147 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 1 2 2 0 0 0 0 - 2 3 1 0 0 0 0 - 9 10 1 0 0 0 0 - 10 11 1 0 0 0 0 - 7 11 1 0 0 0 0 - 9 12 1 1 0 0 0 - 3 16 2 0 0 0 0 - 5 17 2 0 0 0 0 - 8 9 1 0 0 0 0 - 7 8 1 0 0 0 0 - 10 14 1 6 0 0 0 - 12 18 1 0 0 0 0 - 11 15 1 1 0 0 0 - 11 13 1 6 0 0 0 - 1 6 1 0 0 0 0 - 5 6 1 0 0 0 0 - 7 6 1 1 0 0 0 - 3 4 1 0 0 0 0 - 4 5 1 0 0 0 0 - 18 27 1 0 0 0 0 - 19 20 1 0 0 0 0 - 20 21 1 0 0 0 0 - 21 22 2 0 0 0 0 - 21 26 1 0 0 0 0 - 22 23 1 0 0 0 0 - 23 24 2 0 0 0 0 - 24 25 1 0 0 0 0 - 24 27 1 0 0 0 0 - 25 26 2 0 0 0 0 - 27 28 1 0 0 0 0 - 27 34 1 0 0 0 0 - 28 29 2 0 0 0 0 - 28 33 1 0 0 0 0 - 29 30 1 0 0 0 0 - 30 31 2 0 0 0 0 - 31 32 1 0 0 0 0 - 32 33 2 0 0 0 0 - 34 35 2 0 0 0 0 - 34 41 1 0 0 0 0 - 35 36 1 0 0 0 0 - 36 37 2 0 0 0 0 - 37 38 1 0 0 0 0 - 37 40 1 0 0 0 0 - 38 39 1 0 0 0 0 - 40 41 2 0 0 0 0 -M STY 2 1 SUP 2 SUP -M SAL 1 1 15 -M SBL 1 1 13 -M SMT 1 Me -M SAP 1 1 15 11 1 -M SAL 2 15 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 -M SAL 2 8 34 35 36 37 38 39 40 41 -M SBL 2 1 20 -M SMT 2 DMTr -M SAP 2 1 27 18 1 -M END From 6addc5610f9e6bd0115d7faf45499ae20c4b3dd8 Mon Sep 17 00:00:00 2001 From: Yechen Qiao Date: Thu, 12 Mar 2026 11:30:26 -0400 Subject: [PATCH 5/5] CHEMBUGS-184 Fixed merge up on commons.cpp my changes. --- core/indigo-core/tests/common.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/indigo-core/tests/common.cpp b/core/indigo-core/tests/common.cpp index 69a38f253e..4a442bce02 100644 --- a/core/indigo-core/tests/common.cpp +++ b/core/indigo-core/tests/common.cpp @@ -27,13 +27,6 @@ void IndigoCoreTest::loadMolecule(const char* buf, Molecule& molecule) loader.loadMolecule(molecule); } -void IndigoCoreTest::loadReaction(const char* buf, Reaction& reaction) -{ - BufferScanner scanner(buf); - ReactionAutoLoader loader(scanner); - loader.loadReaction(reaction); -} - void IndigoCoreTest::loadQueryMolecule(const char* buf, QueryMolecule& queryMolecule) { BufferScanner scanner(buf);