Skip to content

Commit

Permalink
#1200 MolfileSaver add Data S-Groups to molecule at saveMolecule() (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
AliaksandrDziarkach authored Aug 8, 2023
1 parent 94f3e54 commit 18bd5dc
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 41 deletions.
4 changes: 2 additions & 2 deletions api/tests/integration/ref/deco/deco_sdf.py.out
Original file line number Diff line number Diff line change
Expand Up @@ -29762,7 +29762,7 @@ $END MOL

mapped scaffold: OCC1OC(O)C(O)C(O)C1O
RGROUP #1
fragment #0: c12c(Cl)c(ccc1[nH]cc%912)Br.[*:1]%91 |$;;;;;;;;;;;_AP1$,SgD:5:MRV_IMPLICIT_H:IMPL_H1::: :|
fragment #0: c12c(Cl)c(ccc1[nH]cc%912)Br.[*:1]%91 |$;;;;;;;;;;;_AP1$|
C1(COP(=O)(O)O)C(O)C(C(O)C(OP(=O)(O)O)O1)O.C1CCCCC1N.C1CCCCC1N.C1CCCCC1N.C1CCCCC1N.O |ha:0,1,2,7,8,9,10,11,12,13,18,19,hb:0,1,6,7,8,9,10,11,12,17,18,19|
decomposed molecule: C1(CO%91)C(O)C(C(O)C(O%92)O1)O.[*:3]%91.[*:1]%92 |$;;;;;;;;;;;;_R3;_R1$,RG:_R1={P%91(=O)(O)O.[*:1]%91 |$;;;;_AP1$|},_R3={P%91(=O)(O)O.[*:1]%91 |$;;;;_AP1$|}|
decomposed molecule: $MDL REV 1 0100000000
Expand Down Expand Up @@ -48077,7 +48077,7 @@ $END MOL

mapped scaffold: OCC1OC(O)C(O)C(O)C1O
RGROUP #1
fragment #0: c1%91c[nH]c2ccc(Br)c(Cl)c12.[*:1]%91 |$;;;;;;;;;;;_AP1$,SgD:5:MRV_IMPLICIT_H:IMPL_H1::: :|
fragment #0: c1%91c[nH]c2ccc(Br)c(Cl)c12.[*:1]%91 |$;;;;;;;;;;;_AP1$|
RGROUP #2
fragment #0: C1%91C(O)C(C(OC2C(O)C(C(O)C(CO)O2)O)C(CO)O1)O.[*:1]%91 |$;;;;;;;;;;;;;;;;;;;;;;_AP1$|
C1(CO)(OC(C(O)C1OC1C(O)C(C(O)C(CO)O1)O)CO)OC1C(O)C(C(O)C(CO)O1)O.O |ha:22,23,24,25,26,27,28,29,30,31,32,33,hb:24,25,26,27,28,29,30,31,32,33,34,35|
Expand Down
6 changes: 6 additions & 0 deletions core/indigo-core/molecule/molecule_sgroups.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ namespace indigo
int num_chars; // number of characters
int dasp_pos;
char tag; // tag
static constexpr char mrv_implicit_h[] = "MRV_IMPLICIT_H";
static constexpr char impl_prefix[] = "IMPL_H";
static constexpr size_t impl_prefix_len = sizeof(impl_prefix) - 1;
bool isMrv_implicit();
void setMrv_implicit(int atom_idx, int hydrogens_count);

private:
DataSGroup(const DataSGroup&);
};
Expand Down
17 changes: 17 additions & 0 deletions core/indigo-core/molecule/src/molecule_sgroups.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ DataSGroup::~DataSGroup()
{
}

constexpr char DataSGroup::mrv_implicit_h[];
constexpr char DataSGroup::impl_prefix[];

bool DataSGroup::isMrv_implicit()
{
return name.size() == sizeof(mrv_implicit_h) && strncmp(name.ptr(), mrv_implicit_h, name.size()) == 0;
}

void DataSGroup::setMrv_implicit(int atom_idx, int hydrogens_count)
{
atoms.push(atom_idx);
std::string sdata = impl_prefix + std::to_string(hydrogens_count);
data.readString(sdata.c_str(), true);
name.readString(mrv_implicit_h, true);
detached = true;
}

Superatom::Superatom()
{
sgroup_type = SGroup::SG_TYPE_SUP;
Expand Down
6 changes: 3 additions & 3 deletions core/indigo-core/molecule/src/molfile_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1939,11 +1939,11 @@ void MolfileLoader::_postLoad()
SGroup& sgroup = _bmol->sgroups.getSGroup(i);
if (sgroup.sgroup_type == SGroup::SG_TYPE_DAT)
{
DataSGroup& dsg = (DataSGroup&)sgroup;
if (dsg.name.size() > 0 && strncmp(dsg.name.ptr(), "MRV_IMPLICIT_H", 14) == 0)
DataSGroup& dsg = static_cast<DataSGroup&>(sgroup);
if (dsg.isMrv_implicit())
{
BufferScanner scanner(dsg.data);
scanner.skip(6); // IMPL_H
scanner.skip(DataSGroup::impl_prefix_len); // IMPL_H
int hcount = scanner.readInt1();
int k = dsg.atoms[0];

Expand Down
69 changes: 40 additions & 29 deletions core/indigo-core/molecule/src/molfile_saver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,32 @@ void convert_xyz_to_string(Vec3f& xyz, std::stringstream& coords)
write_c(xyz.z, coords);
}

/*
* Remove added implicit sgroups
*/
void _removeImplicitSGroups(BaseMolecule& mol, std::list<int>& implicit_sgroups_indexes)
{
for (int idx : implicit_sgroups_indexes)
{
SGroup& sg = mol.sgroups.getSGroup(idx);
if (sg.sgroup_type == SGroup::SG_TYPE_DAT)
{
DataSGroup& dsg = static_cast<DataSGroup&>(sg);
if (dsg.isMrv_implicit())
{
mol.sgroups.remove(idx);
}
else
{
throw MolfileSaver::Error("internal: wanted mrv_implicit sgroup but got other");
}
}
else
{
throw MolfileSaver::Error("internal: wanted data sgroup but got other");
}
}
}
void MolfileSaver::saveBaseMolecule(BaseMolecule& mol)
{
_saveMolecule(mol, mol.isQueryMolecule());
Expand Down Expand Up @@ -352,6 +378,7 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query)
int i;
int iw = 1;
QS_DEF(Array<char>, buf);
std::list<int> implicit_sgroups_indexes;

_atom_mapping.clear_resize(mol.vertexEnd());
_bond_mapping.clear_resize(mol.edgeEnd());
Expand Down Expand Up @@ -471,18 +498,9 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query)
int sg_idx;

sg_idx = mol.sgroups.addSGroup(SGroup::SG_TYPE_DAT);
DataSGroup& sgroup = (DataSGroup&)mol.sgroups.getSGroup(sg_idx);

sgroup.atoms.push(i);

QS_DEF(Array<char>, tmp_buf);
ArrayOutput tmp_out(tmp_buf);
tmp_out.printf("IMPL_H%d", hcount);
tmp_buf.push(0);
sgroup.data.readString(tmp_buf.ptr(), true);

sgroup.name.readString("MRV_IMPLICIT_H", true);
sgroup.detached = true;
implicit_sgroups_indexes.push_front(sg_idx);
DataSGroup& sgroup = static_cast<DataSGroup&>(mol.sgroups.getSGroup(sg_idx));
sgroup.setMrv_implicit(i, hcount);
}

if (radical > 0)
Expand Down Expand Up @@ -786,7 +804,7 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query)
}
else if (sgroup.sgroup_type == SGroup::SG_TYPE_SUP)
{
Superatom& sup = (Superatom&)sgroup;
Superatom& sup = static_cast<Superatom&>(sgroup);
if (sup.bond_connections.size() > 0)
{
for (int j = 0; j < sup.bond_connections.size(); j++)
Expand Down Expand Up @@ -827,7 +845,7 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query)
}
else if (sgroup.sgroup_type == SGroup::SG_TYPE_DAT)
{
DataSGroup& dsg = (DataSGroup&)sgroup;
DataSGroup& dsg = static_cast<DataSGroup&>(sgroup);

const char* name = dsg.name.ptr();
if (name != 0 && strlen(name) > 0)
Expand Down Expand Up @@ -904,7 +922,7 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query)
}
else if (sgroup.sgroup_type == SGroup::SG_TYPE_SRU)
{
RepeatingUnit& ru = (RepeatingUnit&)sgroup;
RepeatingUnit& ru = static_cast<RepeatingUnit&>(sgroup);
if (ru.connectivity == SGroup::HEAD_TO_HEAD)
out.printf(" CONNECT=HH");
else if (ru.connectivity == SGroup::HEAD_TO_TAIL)
Expand All @@ -922,7 +940,7 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query)
}
else if (sgroup.sgroup_type == SGroup::SG_TYPE_MUL)
{
MultipleGroup& mg = (MultipleGroup&)sgroup;
MultipleGroup& mg = static_cast<MultipleGroup&>(sgroup);
if (mg.parent_atoms.size() > 0)
{
out.printf(" PATOMS=(%d", mg.parent_atoms.size());
Expand All @@ -940,6 +958,7 @@ void MolfileSaver::_writeCtab(Output& output, BaseMolecule& mol, bool query)
}
}
output.writeStringCR("M V30 END SGROUP");
_removeImplicitSGroups(mol, implicit_sgroups_indexes);
}

output.writeStringCR("M V30 END CTAB");
Expand Down Expand Up @@ -1091,6 +1110,7 @@ void MolfileSaver::_writeCtab2000(Output& output, BaseMolecule& mol, bool query)
QS_DEF(Array<int[2]>, substitution_count);
QS_DEF(Array<int[2]>, ring_bonds);
QS_DEF(Array<int>, aliases);
std::list<int> implicit_sgroups_indexes;

_atom_mapping.clear_resize(mol.vertexEnd());
_bond_mapping.clear_resize(mol.edgeEnd());
Expand Down Expand Up @@ -1282,19 +1302,9 @@ void MolfileSaver::_writeCtab2000(Output& output, BaseMolecule& mol, bool query)
int sg_idx;

sg_idx = mol.sgroups.addSGroup(SGroup::SG_TYPE_DAT);
DataSGroup& sgroup = (DataSGroup&)mol.sgroups.getSGroup(sg_idx);

sgroup.atoms.push(i);

QS_DEF(Array<char>, tmp_buf);
ArrayOutput tmp_out(tmp_buf);
tmp_buf.clear();
tmp_out.printf("IMPL_H%d", hydrogens_count);
tmp_buf.push(0);
sgroup.data.readString(tmp_buf.ptr(), true);

sgroup.name.readString("MRV_IMPLICIT_H", true);
sgroup.detached = true;
implicit_sgroups_indexes.push_front(sg_idx);
DataSGroup& sgroup = static_cast<DataSGroup&>(mol.sgroups.getSGroup(sg_idx));
sgroup.setMrv_implicit(i, hydrogens_count);

hydrogens_count = 0;
}
Expand Down Expand Up @@ -1768,6 +1778,7 @@ void MolfileSaver::_writeCtab2000(Output& output, BaseMolecule& mol, bool query)
}
}
}
_removeImplicitSGroups(mol, implicit_sgroups_indexes);
}

void MolfileSaver::_writeFormattedString(Output& output, Array<char>& str, int length)
Expand Down
14 changes: 8 additions & 6 deletions core/indigo-core/tests/tests/formats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ TEST_F(IndigoCoreFormatsTest, mol_saver_issue_1200)
{
Molecule t_mol;

loadMolecule(R"(
const char* mol = R"(
-INDIGO-07262316452D
6 6 0 0 0 0 0 0 0 0999 V2000
Expand Down Expand Up @@ -308,16 +308,18 @@ M SDT 4 MRV_IMPLICIT_H
M SDD 4 0.0000 0.0000 DA ALL 1 1
M SED 4 IMPL_H1
M END
)",
t_mol);
)";
loadMolecule(mol, t_mol);
ASSERT_EQ(t_mol.sgroups.getSGroupCount(), 0);
Array<char> out;
ArrayOutput std_out(out);
MolfileSaver saver(std_out);
saver.saveMolecule(t_mol);
ASSERT_EQ(t_mol.sgroups.getSGroupCount(), 2);
ASSERT_EQ(t_mol.sgroups.getSGroupCount(), 0);
saver.mode = MolfileSaver::MODE_2000;
saver.saveMolecule(t_mol);
ASSERT_EQ(t_mol.sgroups.getSGroupCount(), 4);
ASSERT_EQ(t_mol.sgroups.getSGroupCount(), 0);
saver.mode = MolfileSaver::MODE_3000;
saver.saveMolecule(t_mol);
ASSERT_EQ(t_mol.sgroups.getSGroupCount(), 6);
ASSERT_EQ(t_mol.sgroups.getSGroupCount(), 0);
}
2 changes: 1 addition & 1 deletion core/indigo-core/tests/tests/structure_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TEST_F(IndigoCoreStructureCheckTest, radical)
TEST_F(IndigoCoreStructureCheckTest, issue731_stereo)
{
Molecule molecule;
char* mol = R"({"root":{"nodes":[{"$ref":"rg2"}]},
const char* mol = R"({"root":{"nodes":[{"$ref":"rg2"}]},
"header":{"moleculeName":"null"},"rg2":{"rlogic":{"number":2},"type":"rgroup",
"atoms":[{"label":"C","location":[14.808632653403645,17.2218585385598,0]},
{"label":"C","location":[13.997755777985581,16.696221303012916,0]},
Expand Down

0 comments on commit 18bd5dc

Please sign in to comment.