From 1b172eb008acc3fb2b88d92be2edd3d906770634 Mon Sep 17 00:00:00 2001 From: Aliaksandr Dziarkach <18146690+AliaksandrDziarkach@users.noreply.github.com> Date: Fri, 4 Oct 2024 21:50:01 +0300 Subject: [PATCH] #2257 - Unable to save CHEM SS3 to IDT format (#2500) --- .../integration/ref/formats/ket_to_idt.py.out | 1 + .../integration/tests/formats/ket_to_idt.py | 1 + .../tests/formats/ref/idt_issue_2257.ket | 236 ++++++++++++++++++ .../tests/formats/ref/monomer_library.ket | 6 + .../molecule/src/sequence_saver.cpp | 34 ++- 5 files changed, 265 insertions(+), 13 deletions(-) create mode 100644 api/tests/integration/tests/formats/ref/idt_issue_2257.ket diff --git a/api/tests/integration/ref/formats/ket_to_idt.py.out b/api/tests/integration/ref/formats/ket_to_idt.py.out index 04c83091ec..49483f82e0 100644 --- a/api/tests/integration/ref/formats/ket_to_idt.py.out +++ b/api/tests/integration/ref/formats/ket_to_idt.py.out @@ -15,6 +15,7 @@ idt_i2moera_32moera.ket:SUCCEED idt_i2moera_sp.ket:SUCCEED idt_i2moera_sp_32moera.ket:SUCCEED idt_i2moera_t.ket:SUCCEED +idt_issue_2257.ket:SUCCEED idt_many_molecules.ket:SUCCEED idt_mixed.ket:SUCCEED idt_mixed_custom.ket:SUCCEED diff --git a/api/tests/integration/tests/formats/ket_to_idt.py b/api/tests/integration/tests/formats/ket_to_idt.py index 922da746ff..9807b37374 100644 --- a/api/tests/integration/tests/formats/ket_to_idt.py +++ b/api/tests/integration/tests/formats/ket_to_idt.py @@ -65,6 +65,7 @@ def find_diff(a, b): "idt_mixed_custom": "(N1:10203050)(N1)N", "idt_rna_dna_mixed_custom": "r(R1:50003000)(R1)", "idt_mixed_ketcher": "KrK(K1:00003070)r(K2:00003070)", + "idt_issue_2257": "/3ThioMC3-D/", } for filename in sorted(idt_data.keys()): diff --git a/api/tests/integration/tests/formats/ref/idt_issue_2257.ket b/api/tests/integration/tests/formats/ref/idt_issue_2257.ket new file mode 100644 index 0000000000..b382835d2b --- /dev/null +++ b/api/tests/integration/tests/formats/ref/idt_issue_2257.ket @@ -0,0 +1,236 @@ +{ + "root": { + "nodes": [ + { + "$ref": "monomer0" + } + ], + "connections": [], + "templates": [ + { + "$ref": "monomerTemplate-SS3___Dipropanol-disulfide" + } + ] + }, + "monomer0": { + "type": "monomer", + "id": "0", + "position": { + "x": 14.424999999999997, + "y": -5.899999999999998 + }, + "alias": "SS3", + "templateId": "SS3___Dipropanol-disulfide" + }, + "monomerTemplate-SS3___Dipropanol-disulfide": { + "type": "monomerTemplate", + "atoms": [ + { + "label": "H", + "location": [ + -6.8609, + -0.665, + 0 + ] + }, + { + "label": "O", + "location": [ + -5.862, + 0, + 0 + ] + }, + { + "label": "C", + "location": [ + -4.5166, + -0.6653, + 0 + ] + }, + { + "label": "C", + "location": [ + -3.2673, + 0.1663, + 0 + ] + }, + { + "label": "C", + "location": [ + -1.922, + -0.499, + 0 + ] + }, + { + "label": "S", + "location": [ + -0.6726, + 0.3327, + 0 + ] + }, + { + "label": "S", + "location": [ + 0.6726, + -0.3327, + 0 + ] + }, + { + "label": "C", + "location": [ + 1.922, + 0.499, + 0 + ] + }, + { + "label": "C", + "location": [ + 3.2673, + -0.1663, + 0 + ] + }, + { + "label": "C", + "location": [ + 4.5166, + 0.6653, + 0 + ] + }, + { + "label": "O", + "location": [ + 5.862, + 0, + 0 + ] + }, + { + "label": "H", + "location": [ + 6.8609, + 0.665, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 5, + 6 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 6, + 7 + ] + }, + { + "type": 1, + "atoms": [ + 7, + 8 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 8, + 9 + ] + }, + { + "type": 1, + "atoms": [ + 9, + 10 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 10, + 11 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 5 + ] + } + ], + "class": "CHEM", + "classHELM": "CHEM", + "id": "SS3___Dipropanol-disulfide", + "fullName": "Dipropanol-disulfide", + "alias": "SS3", + "attachmentPoints": [ + { + "attachmentAtom": 1, + "leavingGroup": { + "atoms": [ + 0 + ] + }, + "type": "left" + }, + { + "attachmentAtom": 10, + "leavingGroup": { + "atoms": [ + 11 + ] + }, + "type": "right" + } + ], + "idtAliases": { + "base": "ThioMC3-D", + "modifications": { + "endpoint3": "3ThioMC3-D" + } + } + } +} \ No newline at end of file diff --git a/api/tests/integration/tests/formats/ref/monomer_library.ket b/api/tests/integration/tests/formats/ref/monomer_library.ket index 5dab2bcfc5..0ca4748b30 100644 --- a/api/tests/integration/tests/formats/ref/monomer_library.ket +++ b/api/tests/integration/tests/formats/ref/monomer_library.ket @@ -45012,6 +45012,12 @@ "id": "SS3___Dipropanol-disulfide", "fullName": "Dipropanol-disulfide", "alias": "SS3", + "idtAliases": { + "base": "ThioMC3-D", + "modifications": { + "endpoint3": "3ThioMC3-D" + } + }, "attachmentPoints": [ { "attachmentAtom": 1, diff --git a/core/indigo-core/molecule/src/sequence_saver.cpp b/core/indigo-core/molecule/src/sequence_saver.cpp index 99d845783d..eaf420c868 100644 --- a/core/indigo-core/molecule/src/sequence_saver.cpp +++ b/core/indigo-core/molecule/src/sequence_saver.cpp @@ -869,8 +869,12 @@ void SequenceSaver::saveIdt(KetDocument& doc, std::vector 0 && sequence.size() == 0) - modification = IdtModification::THREE_PRIME_END; + IdtModification possible_modification = modification; + if (sequence.size() == 0) // last monomer + if (seq_string.size() > 0) + modification = IdtModification::THREE_PRIME_END; + else // corner case - only one monomer + possible_modification = IdtModification::THREE_PRIME_END; if (monomer_class == MonomerClass::Phosphate) { @@ -898,17 +902,25 @@ void SequenceSaver::saveIdt(KetDocument& doc, std::vector bool { + bool has_modification = idtAlias.hasModification(modification); + if (has_modification || (possible_modification != modification && idtAlias.hasModification(possible_modification))) + { + const std::string& idt_alias = + has_modification ? idtAlias.getModification(modification) : idtAlias.getModification(possible_modification); + seq_string += '/'; + seq_string += idt_alias; + seq_string += '/'; + return true; + } + return false; + }; // Try to find in library const std::string& lib_monomer_id = _library.getMonomerTemplateIdByAlias(monomer_class, monomer); if (lib_monomer_id.size()) // Monomer in library { - const MonomerTemplate& templ = _library.getMonomerTemplateById(lib_monomer_id); - if (templ.idtAlias().hasModification(modification)) + if (write_name(_library.getMonomerTemplateById(lib_monomer_id).idtAlias())) { - const std::string& idt_alias = templ.idtAlias().getModification(modification); - seq_string += '/'; - seq_string += idt_alias; - seq_string += '/'; if (modification == IdtModification::FIVE_PRIME_END) modification = IdtModification::INTERNAL; continue; @@ -917,12 +929,8 @@ void SequenceSaver::saveIdt(KetDocument& doc, std::vectortemplateId()); - - if (monomer_template.idtAlias().hasModification(modification)) + if (write_name(monomer_template.idtAlias())) { - seq_string.push_back('/'); - seq_string.append(monomer_template.idtAlias().getModification(modification)); - seq_string.push_back('/'); modification = IdtModification::INTERNAL; continue; }