From b97fa59ee1ddc28295cc7bf7aaf20a2bf2d56e36 Mon Sep 17 00:00:00 2001 From: Aleksandr Paramonov Date: Wed, 18 Sep 2024 17:20:30 +0400 Subject: [PATCH] #2176: add ACS style reaction layout (#2307) Co-authored-by: Aliaksandr Dziarkach <18146690+AliaksandrDziarkach@users.noreply.github.com> Co-authored-by: Aliakasndr Dziarkach --- api/c/indigo-renderer/src/indigo_render2d.cpp | 18 +- .../src/indigo_renderer_internal.h | 2 +- api/c/indigo/src/indigo.cpp | 3 +- api/c/indigo/src/indigo_internal.h | 6 +- api/c/indigo/src/indigo_layout.cpp | 9 +- api/c/indigo/src/indigo_options.cpp | 64 +++ api/c/indigo/src/option_manager.h | 17 + api/c/tests/unit/tests/layout.cpp | 103 +++++ api/tests/integration/common/env_indigo.py | 45 +- .../ref/formats/rxn_no_layout.py.out | 196 ++++----- .../ref/layout/acs_style_reaction.py.out | 15 + .../tests/basic/ketfile_stereo_desc.py | 3 + .../tests/basic/ref/crazystereo.ket | 104 ++--- .../tests/formats/rxn_no_layout.py | 1 + .../tests/layout/acs_style_reaction.py | 49 +++ api/tests/integration/tests/layout/basic.py | 16 +- .../layout/reaction_layout_and_clean2d.py | 14 +- .../layout/reactions/acs_before_layout.ket | 409 ++++++++++++++++++ .../tests/layout/ref/932-agents.ket | 130 +++--- .../ref/acs_after_layout_default_margin.ket | 406 +++++++++++++++++ .../ref/acs_after_layout_zero_margin.ket | 406 +++++++++++++++++ .../tests/layout/ref/reaction_layout.rdf | 56 +-- .../integration/tests/layout/ref/test1.rxn | 54 +-- .../tests/layout/ref/test_sgroup.rxn | 28 +- .../integration/tests/layout/smiles_layout.py | 1 + .../tests/reaction/reactions/issue_1205.ket | 259 ++++++++++- .../tests/reaction/save_ket_layout_1205.py | 3 + .../tests/todo/bingo_get_indigo_object_bug.py | 2 +- core/indigo-core/common/math/algebra.h | 2 +- core/indigo-core/layout/metalayout.h | 138 +++++- core/indigo-core/layout/molecule_layout.h | 1 - core/indigo-core/layout/reaction_layout.h | 21 +- core/indigo-core/layout/src/metalayout.cpp | 25 +- .../layout/src/molecule_layout.cpp | 6 +- .../layout/src/reaction_layout.cpp | 107 +++-- .../layout/src/sequence_layout.cpp | 2 +- .../molecule/src/molfile_loader.cpp | 4 +- .../molecule/src/sequence_loader.cpp | 24 +- .../reaction/reaction_json_saver.h | 2 + .../reaction/src/reaction_json_saver.cpp | 2 +- core/render2d/render_common.h | 4 + .../basic/after_layout_default_margin.ket | 406 +++++++++++++++++ .../basic/after_layout_zero_margin.ket | 406 +++++++++++++++++ data/molecules/basic/before_layout.ket | 409 ++++++++++++++++++ .../backend/service/tests/api/indigo_test.py | 48 +- 45 files changed, 3587 insertions(+), 439 deletions(-) create mode 100644 api/c/tests/unit/tests/layout.cpp create mode 100644 api/tests/integration/ref/layout/acs_style_reaction.py.out create mode 100644 api/tests/integration/tests/layout/acs_style_reaction.py create mode 100644 api/tests/integration/tests/layout/reactions/acs_before_layout.ket create mode 100644 api/tests/integration/tests/layout/ref/acs_after_layout_default_margin.ket create mode 100644 api/tests/integration/tests/layout/ref/acs_after_layout_zero_margin.ket create mode 100644 data/molecules/basic/after_layout_default_margin.ket create mode 100644 data/molecules/basic/after_layout_zero_margin.ket create mode 100644 data/molecules/basic/before_layout.ket diff --git a/api/c/indigo-renderer/src/indigo_render2d.cpp b/api/c/indigo-renderer/src/indigo_render2d.cpp index a684e285b5..39b3221196 100644 --- a/api/c/indigo-renderer/src/indigo_render2d.cpp +++ b/api/c/indigo-renderer/src/indigo_render2d.cpp @@ -74,14 +74,6 @@ IndigoRenderer::~IndigoRenderer() { } -#define SET_POSITIVE_FLOAT_OPTION(option, error) \ - [](float value) { \ - if (value <= 0.0f) \ - throw IndigoError(error); \ - option = value; \ - }, \ - [](float& value) { value = option; } - #define CHECK_AND_SETTER_GETTER_COLOR_OPTION(option) \ [](float r, float g, float b) { \ CHECKRGB(r, g, b); \ @@ -689,9 +681,17 @@ void IndigoRenderer::setOptionsHandlers() if (!options_set) { auto mgr = sf::xlock_safe_ptr(indigoGetOptionManager(indigo_id)); + options_set = true; #define rp indigoRendererGetInstance().renderParams #define cdxmlContext getCdxmlContext() +#define indigo indigoGetInstance() + + rp.cnvOpt.bondLength = indigo.layout_options.bondLength; + rp.cnvOpt.bondLengthUnit = indigo.layout_options.bondLengthUnit; + rp.rOpt.reactionComponentMarginSize = indigo.layout_options.reactionComponentMarginSize; + rp.rOpt.reactionComponentMarginSizeUnit = indigo.layout_options.reactionComponentMarginSizeUnit; + rp.rOpt.ppi = indigo.layout_options.ppi; mgr->setOptionHandlerInt("render-comment-offset", SETTER_GETTER_INT_OPTION(rp.cnvOpt.commentOffset)); mgr->setOptionHandlerInt("render-image-width", SETTER_GETTER_INT_OPTION(rp.cnvOpt.width)); @@ -757,7 +757,5 @@ void IndigoRenderer::setOptionsHandlers() mgr->setOptionHandlerString("render-cdxml-title-face", SETTER_GETTER_STR_OPTION(cdxmlContext.titleFace)); mgr->setOptionHandlerVoid("reset-render-options", indigoRenderResetOptions); - - options_set = true; } } diff --git a/api/c/indigo-renderer/src/indigo_renderer_internal.h b/api/c/indigo-renderer/src/indigo_renderer_internal.h index 393ee87832..1d7cbde02d 100644 --- a/api/c/indigo-renderer/src/indigo_renderer_internal.h +++ b/api/c/indigo-renderer/src/indigo_renderer_internal.h @@ -36,7 +36,7 @@ class IndigoRenderer : public IndigoPluginContext private: void setOptionsHandlers(); - bool options_set = false; + std::atomic options_set = false; }; class IndigoHDCOutput : public IndigoObject diff --git a/api/c/indigo/src/indigo.cpp b/api/c/indigo/src/indigo.cpp index ae66c6bafd..be3f795e3e 100644 --- a/api/c/indigo/src/indigo.cpp +++ b/api/c/indigo/src/indigo.cpp @@ -207,10 +207,11 @@ void Indigo::initMoleculeJsonSaver(MoleculeJsonSaver& saver) saver.use_native_precision = json_use_native_precision; } -void Indigo::initReactionJsonSaver(ReactionJsonSaver& saver) +void Indigo::initReactionJsonSaver(ReactionJsonSaver& saver) const { saver.add_stereo_desc = json_saving_add_stereo_desc; saver.pretty_json = json_saving_pretty; + saver.layout_options = layout_options; saver.use_native_precision = json_use_native_precision; } diff --git a/api/c/indigo/src/indigo_internal.h b/api/c/indigo/src/indigo_internal.h index 4fc84bd59b..00d1051e93 100644 --- a/api/c/indigo/src/indigo_internal.h +++ b/api/c/indigo/src/indigo_internal.h @@ -335,7 +335,7 @@ class DLLEXPORT Indigo bool embedding_edges_uniqueness, find_unique_embeddings; int max_embeddings; - int layout_max_iterations; // default is zero -- no limit + int layout_max_iterations = 0; // default is zero -- no limit bool smart_layout = false; float layout_horintervalfactor = ReactionLayout::DEFAULT_HOR_INTERVAL_FACTOR; bool layout_preserve_existing = false; @@ -351,7 +351,7 @@ class DLLEXPORT Indigo void initMolfileSaver(MolfileSaver& saver); void initRxnfileSaver(RxnfileSaver& saver); void initMoleculeJsonSaver(MoleculeJsonSaver& saver); - void initReactionJsonSaver(ReactionJsonSaver& saver); + void initReactionJsonSaver(ReactionJsonSaver& saver) const; void initReactionJsonSaver(PathwayReactionJsonSaver& saver); bool preserve_ordering_in_serialize; @@ -366,6 +366,8 @@ class DLLEXPORT Indigo bool scsr_ignore_chem_templates; + indigo::LayoutOptions layout_options; + static const Array& getErrorMessage(); static void clearErrorMessage(); static void setErrorMessage(const char* message); diff --git a/api/c/indigo/src/indigo_layout.cpp b/api/c/indigo/src/indigo_layout.cpp index d27ff4aa0d..3eb34c35c9 100644 --- a/api/c/indigo/src/indigo_layout.cpp +++ b/api/c/indigo/src/indigo_layout.cpp @@ -58,7 +58,7 @@ CEXPORT int indigoLayout(int object) } ml.max_iterations = self.layout_max_iterations; - ml.bond_length = MoleculeLayout::DEFAULT_BOND_LENGTH; + ml.bond_length = LayoutOptions::DEFAULT_BOND_LENGTH; ml.layout_orientation = (layout_orientation_value)self.layout_orientation; if (self.layout_preserve_existing || mol->hasAtropoStereoBonds()) ml.respect_existing_layout = true; @@ -105,11 +105,12 @@ CEXPORT int indigoLayout(int object) obj.type == IndigoObject::PATHWAY_REACTION || rxn.multitaleCount(); if (!no_layout) { - ReactionLayout rl(rxn, self.smart_layout); + ReactionLayout rl(rxn, self.smart_layout, self.layout_options); rl.max_iterations = self.layout_max_iterations; rl.layout_orientation = (layout_orientation_value)self.layout_orientation; - rl.bond_length = MoleculeLayout::DEFAULT_BOND_LENGTH; - rl.horizontal_interval_factor = self.layout_horintervalfactor; + // TODO::ACS Why removed? + // rl.bond_length = LayoutOptions::DEFAULT_BOND_LENGTH; + // rl.reaction_margin_size = self.layout_horintervalfactor; if (self.layout_preserve_existing) rl.preserve_molecule_layout = true; rl.make(); diff --git a/api/c/indigo/src/indigo_options.cpp b/api/c/indigo/src/indigo_options.cpp index e48af77123..41e610c7d7 100644 --- a/api/c/indigo/src/indigo_options.cpp +++ b/api/c/indigo/src/indigo_options.cpp @@ -261,6 +261,62 @@ void indigoProductEnumeratorGetOneTubeMode(Array& value) value.readString("grid", true); } +bool isEqual(const char* l, const char* r) +{ + return strcmp(l, r) != 0; +} + +IndigoOptionManager::optf_string_t indigoSetUnitsOfMeasure(UnitsOfMeasure::TYPE& result) +{ + static auto func = [&result](const char* mode) { + if (isEqual(mode, "pt")) + { + result = UnitsOfMeasure::TYPE::PT; + } + else if (isEqual(mode, "px")) + { + result = UnitsOfMeasure::TYPE::PX; + } + else if (isEqual(mode, "inch")) + { + result = UnitsOfMeasure::TYPE::INCH; + } + else if (isEqual(mode, "cm")) + { + result = UnitsOfMeasure::TYPE::CM; + } + else + { + throw IndigoError("Invalid size unit, should be 'px', 'pt', 'inch' or 'all'"); + } + }; + + return [](const char* mode) -> void { return func(mode); }; +} + +IndigoOptionManager::get_optf_string_t indigoGetUnitsOfMeasure(const UnitsOfMeasure::TYPE input) +{ + static auto func = [input](Array& result) { + switch (input) + { + case UnitsOfMeasure::TYPE::PT: + result.readString("pt", true); + break; + case UnitsOfMeasure::TYPE::PX: + result.readString("px", true); + break; + case UnitsOfMeasure::TYPE::INCH: + result.readString("inch", true); + break; + case UnitsOfMeasure::TYPE::CM: + result.readString("cm", true); + break; + } + }; + + return [](Array& res) -> void { return func(res); }; +} + void IndigoOptionHandlerSetter::setBasicOptionHandlers(const qword id) { auto mgr = sf::xlock_safe_ptr(indigoGetOptionManager(id)); @@ -384,4 +440,12 @@ void IndigoOptionHandlerSetter::setBasicOptionHandlers(const qword id) mgr->setOptionHandlerInt("rpe-max-products-count", SETTER_GETTER_INT_OPTION(indigo.rpe_params.max_product_count)); mgr->setOptionHandlerBool("rpe-layout", SETTER_GETTER_BOOL_OPTION(indigo.rpe_params.is_layout)); mgr->setOptionHandlerBool("transform-layout", SETTER_GETTER_BOOL_OPTION(indigo.rpe_params.transform_is_layout)); + + mgr->setOptionHandlerFloat("bond-length", SET_POSITIVE_FLOAT_OPTION(indigo.layout_options.bondLength, "bond length must be positive")); + mgr->setOptionHandlerString("bond-length-unit", indigoSetUnitsOfMeasure(indigo.layout_options.bondLengthUnit), + indigoGetUnitsOfMeasure(indigo.layout_options.bondLengthUnit)); + mgr->setOptionHandlerFloat("reaction-component-margin-size", SETTER_GETTER_FLOAT_OPTION(indigo.layout_options.reactionComponentMarginSize)); + mgr->setOptionHandlerString("reaction-component-margin-size-unit", indigoSetUnitsOfMeasure(indigo.layout_options.reactionComponentMarginSizeUnit), + indigoGetUnitsOfMeasure(indigo.layout_options.reactionComponentMarginSizeUnit)); + mgr->setOptionHandlerInt("image-resolution", SET_POSITIVE_INT_OPTION(indigo.layout_options.ppi, "image resolution ppi must be positive")); } \ No newline at end of file diff --git a/api/c/indigo/src/option_manager.h b/api/c/indigo/src/option_manager.h index 5fb58eaca4..adac3d48bc 100644 --- a/api/c/indigo/src/option_manager.h +++ b/api/c/indigo/src/option_manager.h @@ -27,6 +27,7 @@ #include "base_cpp/os_sync_wrapper.h" #include "base_cpp/red_black.h" +#include #include using namespace indigo; @@ -89,6 +90,22 @@ using namespace indigo; value.push(0); \ } +#define SET_POSITIVE_FLOAT_OPTION(option, error) \ + [](float value) { \ + if (value <= 0.0f) \ + throw IndigoError(error); \ + option = value; \ + }, \ + [](float& value) { value = option; } + +#define SET_POSITIVE_INT_OPTION(option, error) \ + [](int32_t value) { \ + if (value <= 0) \ + throw IndigoError(error); \ + option = value; \ + }, \ + [](int32_t& value) { value = option; } + class DLLEXPORT IndigoOptionManager { public: diff --git a/api/c/tests/unit/tests/layout.cpp b/api/c/tests/unit/tests/layout.cpp new file mode 100644 index 0000000000..227d01d337 --- /dev/null +++ b/api/c/tests/unit/tests/layout.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** + * Copyright (C) from 2009 to Present EPAM Systems. + * + * This file is part of Indigo toolkit. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +#include + +#include + +#include + +#include +#include +#include +#include + +#include "common.h" + +using namespace indigo; + +class IndigoApiLayoutTest : public IndigoApiTest +{ +protected: + void SetUp() final + { + IndigoApiTest::SetUp(); + indigoRendererInit(session); + } + + void TearDown() final + { + indigoRendererDispose(session); + IndigoApiTest::TearDown(); + } + + struct TestCaseResult + { + std::string_view result; + std::string_view expected; + }; + + TestCaseResult applyLayoutAndGetResult(int reactionId, std::string_view expectedResultFilename) + { + indigoSetOptionBool("json-saving-pretty", true); + indigoSetOptionBool("json-use-native-precision", true); + indigoSetOptionBool("json-saving-add-stereo-desc", true); + + indigoLayout(reactionId); + std::string path_to_file = "molecules/basic/" + std::string(expectedResultFilename); + // indigoSaveJsonToFile(reactionId, dataPath(path_to_file.data()).c_str()); + std::ifstream is(dataPath(path_to_file.data()), std::ios::binary | std::ios::ate); + auto size = is.tellg(); + stringBuffer = std::string(size, '\0'); // construct string to stream size + is.seekg(0); + is.read(&stringBuffer[0], size); + stringBuffer.erase(std::remove(stringBuffer.begin(), stringBuffer.end(), '\r'), stringBuffer.end()); + + const char* res = indigoJson(reactionId); + return {res, stringBuffer}; + } + std::string stringBuffer; +}; + +// TEST_F(IndigoApiLayoutTest, check_reaction_margin_size) +// { +// indigoSetErrorHandler(errorHandler, nullptr); +// indigoSetOptionBool("json-saving-pretty", true); +// indigoSetOptionBool("json-use-native-precision", true); +// indigoSetOptionBool("json-saving-add-stereo-desc", true); +// try +// { +// auto reactionId = indigoLoadReactionFromFile(dataPath("molecules/basic/before_layout.ket").c_str()); +// { +// indigoSetOption("reaction-component-margin-size", "0.0"); +// auto files = applyLayoutAndGetResult(reactionId, "after_layout_zero_margin.ket"); +// EXPECT_STREQ(files.result.data(), files.expected.data()); +// } +// { +// indigoSetOption("bond-length", "40.0"); +// indigoSetOption("reaction-component-margin-size", "20.0"); +// auto files = applyLayoutAndGetResult(reactionId, "after_layout_default_margin.ket"); +// EXPECT_STREQ(files.result.data(), files.expected.data()); +// } +// indigoFree(reactionId); +// } +// catch (Exception& e) +// { +// ASSERT_STREQ("", e.message()); +// } +// } diff --git a/api/tests/integration/common/env_indigo.py b/api/tests/integration/common/env_indigo.py index 3262b17f6b..d19097da2a 100644 --- a/api/tests/integration/common/env_indigo.py +++ b/api/tests/integration/common/env_indigo.py @@ -203,11 +203,31 @@ def dist_vec(a, b): return sqrt(sum((a - b) ** 2 for a, b in zip(a, b))) -def moleculeLayoutDiff(indigo, mol, ref, delta=0.01, ref_is_file=True): +def moleculeLayoutDiff( + indigo, + mol, + ref, + delta=0.01, + ref_is_file=True, + update=False, + update_format="mol", +): if ref_is_file: ref_name = getRefFilepath2(ref) + if update: + if update_format == "mol": + txt = mol.molfile() + elif update_format == "ket": + txt = mol.json() + with open(ref_name, "w") as file: + file.write(txt) m2 = indigo.loadMoleculeFromFile(ref_name) else: + if update: + if update_format == "mol": + print(mol.molfile()) + elif update_format == "ket": + print(mol.json()) m2 = indigo.loadMolecule(ref) error_buf = [] @@ -242,11 +262,32 @@ def moleculeLayoutDiff(indigo, mol, ref, delta=0.01, ref_is_file=True): return "Success" -def reactionLayoutDiff(indigo, rxn, ref, delta=0.001, ref_is_file=True): +def reactionLayoutDiff( + indigo, + rxn, + ref, + delta=0.001, + ref_is_file=True, + update=False, + update_format="mol", +): if ref_is_file: ref_name = getRefFilepath2(ref) + if update: + if update_format == "mol": + txt = rxn.rxnfile() + elif update_format == "ket": + txt = rxn.json() + with open(ref_name, "w") as file: + file.write(txt) r2 = indigo.loadReactionFromFile(ref_name) else: + if update: + if update_format == "mol": + print(rxn.rxnfile()) + elif update_format == "ket": + print(rxn.json()) + print("ref=\n", ref) r2 = indigo.loadReaction(ref) error_buf = [] for m in rxn.iterateMolecules(): diff --git a/api/tests/integration/ref/formats/rxn_no_layout.py.out b/api/tests/integration/ref/formats/rxn_no_layout.py.out index cd598ab3ad..1db8dc7c56 100644 --- a/api/tests/integration/ref/formats/rxn_no_layout.py.out +++ b/api/tests/integration/ref/formats/rxn_no_layout.py.out @@ -29,7 +29,7 @@ { "type": "plus", "location": [ - 9.501733779907229, + 10.201734, 0.0, 0.0 ] @@ -37,7 +37,7 @@ { "type": "plus", "location": [ - 19.503467559814458, + 21.603466, 0.0, 0.0 ] @@ -45,7 +45,7 @@ { "type": "plus", "location": [ - 23.103466033935548, + 26.603466, 0.0, 0.0 ] @@ -53,7 +53,7 @@ { "type": "plus", "location": [ - 26.70346450805664, + 31.603462, 0.0, 0.0 ] @@ -61,7 +61,7 @@ { "type": "plus", "location": [ - 31.90349578857422, + 38.203495, 0.0, 0.0 ] @@ -69,7 +69,7 @@ { "type": "plus", "location": [ - 48.90950775146485, + 57.809509, 0.0, 0.0 ] @@ -80,12 +80,12 @@ "mode": "open-angle", "pos": [ { - "x": 36.30352783203125, + "x": 45.003529, "y": 0.0, "z": 0.0 }, { - "x": 40.50352478027344, + "x": 47.003525, "y": 0.0, "z": 0.0 } @@ -100,80 +100,80 @@ { "label": "C", "location": [ - 3.7037816047668459, - 1.3882975578308106, + 3.703782, + 1.388298, 0.0 ] }, { "label": "C", "location": [ - 6.101698875427246, - 0.004801750183105469, + 6.101699, + 0.004802, 0.0 ] }, { "label": "C", "location": [ - 5.304883003234863, - 1.3877620697021485, + 5.304883, + 1.387762, 0.0 ] }, { "label": "C", "location": [ - 5.301149368286133, - -1.3824270963668824, + 5.301149, + -1.382427, 0.0 ] }, { "label": "C", "location": [ - 2.900032997131348, - -0.004266738891601563, + 2.900033, + -0.004267, 0.0 ] }, { "label": "C", "location": [ - 3.708050489425659, - -1.3850938081741334, + 3.70805, + -1.385094, 0.0 ] }, { "label": "C", "location": [ - 2.90376615524292, - 2.773924827575684, + 2.903766, + 2.773925, 0.0 ] }, { "label": "C", "location": [ - 2.9133682250976564, - -2.773924827575684, + 2.913368, + -2.773925, 0.0 ] }, { "label": "C", "location": [ - 1.2999999523162842, - -0.008531332015991211, + 1.3, + -0.008531, 0.0 ] }, { "label": "C", "location": [ - 7.701733589172363, - 0.004266738891601563, + 7.701734, + 0.004267, 0.0 ] } @@ -257,80 +257,80 @@ { "label": "C", "location": [ - 13.70551586151123, - 1.3882975578308106, + 15.105515, + 1.388298, 0.0 ] }, { "label": "C", "location": [ - 16.10343360900879, - 0.004801750183105469, + 17.503433, + 0.004802, 0.0 ] }, { "label": "C", "location": [ - 15.306617736816408, - 1.3877620697021485, + 16.706617, + 1.387762, 0.0 ] }, { "label": "C", "location": [ - 15.30288314819336, - -1.3824270963668824, + 16.702883, + -1.382427, 0.0 ] }, { "label": "C", "location": [ - 12.901766777038576, - -0.004266738891601563, + 14.301766, + -0.004267, 0.0 ] }, { "label": "C", "location": [ - 13.709784507751465, - -1.3850938081741334, + 15.109784, + -1.385094, 0.0 ] }, { "label": "C", "location": [ - 12.905500411987305, - 2.773924827575684, + 14.3055, + 2.773925, 0.0 ] }, { "label": "C", "location": [ - 12.915102005004885, - -2.773924827575684, + 14.315102, + -2.773925, 0.0 ] }, { "label": "C", "location": [ - 11.30173397064209, - -0.008531332015991211, + 12.701734, + -0.008531, 0.0 ] }, { "label": "C", "location": [ - 17.703468322753908, - 0.004266738891601563, + 19.103468, + 0.004267, 0.0 ] } @@ -414,7 +414,7 @@ { "label": "O", "location": [ - 21.303466796875, + 24.103466, 0.0, 0.0 ] @@ -428,7 +428,7 @@ { "label": "O", "location": [ - 24.903465270996099, + 29.103464, 0.0, 0.0 ] @@ -442,7 +442,7 @@ { "label": "O", "location": [ - 28.503463745117189, + 34.103462, 0.0, 0.0 ], @@ -451,7 +451,7 @@ { "label": "O", "location": [ - 30.10349464416504, + 35.703495, 0.0, 0.0 ] @@ -473,7 +473,7 @@ { "label": "O", "location": [ - 33.703495025634769, + 40.703495, 0.0, 0.0 ] @@ -481,7 +481,7 @@ { "label": "O", "location": [ - 35.30352783203125, + 42.303528, 0.0, 0.0 ] @@ -503,88 +503,88 @@ { "label": "C", "location": [ - 44.71158981323242, - 1.3882975578308106, + 52.911591, + 1.388298, 0.0 ] }, { "label": "C", "location": [ - 47.1095085144043, - 0.004801750183105469, + 55.309509, + 0.004802, 0.0 ] }, { "label": "C", "location": [ - 46.31269073486328, - 1.3877620697021485, + 54.512691, + 1.387762, 0.0 ] }, { "label": "C", "location": [ - 46.3089599609375, - -1.3824270963668824, + 54.508961, + -1.382427, 0.0 ] }, { "label": "C", "location": [ - 43.90784454345703, - -0.004266738891601563, + 52.107845, + -0.004267, 0.0 ] }, { "label": "C", "location": [ - 44.715858459472659, - -1.3850938081741334, + 52.915859, + -1.385094, 0.0 ] }, { "label": "C", "location": [ - 43.921180725097659, - -2.773924827575684, + 52.121181, + -2.773925, 0.0 ] }, { "label": "C", "location": [ - 42.30780792236328, - -0.008531332015991211, + 50.507809, + -0.008531, 0.0 ] }, { "label": "O", "location": [ - 41.50352478027344, - 1.3744287490844729, + 49.703526, + 1.374429, 0.0 ] }, { "label": "O", "location": [ - 41.51152420043945, - -1.3968271017074586, + 49.711525, + -1.396827, 0.0 ] }, { "label": "C", "location": [ - 43.91157531738281, - 2.773924827575684, + 52.111576, + 2.773925, 0.0 ] } @@ -675,88 +675,88 @@ { "label": "C", "location": [ - 53.917572021484378, - 1.3882975578308106, + 63.517574, + 1.388298, 0.0 ] }, { "label": "C", "location": [ - 56.31549072265625, - 0.004801750183105469, + 65.915497, + 0.004802, 0.0 ] }, { "label": "C", "location": [ - 55.51867294311524, - 1.3877620697021485, + 65.118675, + 1.387762, 0.0 ] }, { "label": "C", "location": [ - 55.51494216918945, - -1.3824270963668824, + 65.114944, + -1.382427, 0.0 ] }, { "label": "C", "location": [ - 53.113826751708987, - -0.004266738891601563, + 62.713829, + -0.004267, 0.0 ] }, { "label": "C", "location": [ - 53.92184066772461, - -1.3850938081741334, + 63.521843, + -1.385094, 0.0 ] }, { "label": "C", "location": [ - 53.12716293334961, - -2.773924827575684, + 62.727165, + -2.773925, 0.0 ] }, { "label": "C", "location": [ - 51.51379013061524, - -0.008531332015991211, + 61.113792, + -0.008531, 0.0 ] }, { "label": "O", "location": [ - 50.70950698852539, - 1.3744287490844729, + 60.309509, + 1.374429, 0.0 ] }, { "label": "O", "location": [ - 50.717506408691409, - -1.3968271017074586, + 60.317509, + -1.396827, 0.0 ] }, { "label": "C", "location": [ - 53.117557525634769, - 2.773924827575684, + 62.71756, + 2.773925, 0.0 ] } diff --git a/api/tests/integration/ref/layout/acs_style_reaction.py.out b/api/tests/integration/ref/layout/acs_style_reaction.py.out new file mode 100644 index 0000000000..2e2311fbfd --- /dev/null +++ b/api/tests/integration/ref/layout/acs_style_reaction.py.out @@ -0,0 +1,15 @@ +*** ACS reaction layout testing *** + +*** test zero margin *** + Result: Molecule #0: Success + Molecule #1: Success + Molecule #2: Success + Molecule #3: Success + Molecule #4: Success + +*** test default margin *** + Result: Molecule #0: Success + Molecule #1: Success + Molecule #2: Success + Molecule #3: Success + Molecule #4: Success diff --git a/api/tests/integration/tests/basic/ketfile_stereo_desc.py b/api/tests/integration/tests/basic/ketfile_stereo_desc.py index dac7cd19c7..443f35bb61 100644 --- a/api/tests/integration/tests/basic/ketfile_stereo_desc.py +++ b/api/tests/integration/tests/basic/ketfile_stereo_desc.py @@ -73,7 +73,10 @@ def stereo_desc_test(py_file, out_queue): os.path.join(joinPathPy("reactions/", __file__), filename) ) + indigo.setOption("json-use-native-precision", True) ketfile = joinPathPy(os.path.join(ref_path, "crazystereo.ket"), __file__) + # with open(ketfile, "w") as file: + # file.write(rxn.json()) with open(ketfile, "r") as file: ket_ref = file.read() diff = find_diff(ket_ref, rxn.json()) diff --git a/api/tests/integration/tests/basic/ref/crazystereo.ket b/api/tests/integration/tests/basic/ref/crazystereo.ket index bfcfd8ce1a..4e8bb3b987 100644 --- a/api/tests/integration/tests/basic/ref/crazystereo.ket +++ b/api/tests/integration/tests/basic/ref/crazystereo.ket @@ -13,12 +13,12 @@ "mode": "open-angle", "pos": [ { - "x": 7.842718124389648, + "x": 9.542718, "y": 0.0, "z": 0.0 }, { - "x": 12.042718887329102, + "x": 11.542719, "y": 0.0, "z": 0.0 } @@ -33,80 +33,80 @@ { "label": "C", "location": [ - 4.071358680725098, - 0.7999899387359619, + 4.071359, + 0.79999, 0.0 ] }, { "label": "C", "location": [ - 2.685678482055664, - 1.599979877471924, + 2.685678, + 1.59998, 0.0 ] }, { "label": "C", "location": [ - 1.2999999523162842, - 0.7999899387359619, + 1.3, + 0.79999, 0.0 ] }, { "label": "C", "location": [ - 1.2999999523162842, - -0.7999899387359619, + 1.3, + -0.79999, 0.0 ] }, { "label": "C", "location": [ - 2.685678482055664, - -1.599979877471924, + 2.685678, + -1.59998, 0.0 ] }, { "label": "C", "location": [ - 4.071358680725098, - -0.7999899387359619, + 4.071359, + -0.79999, 0.0 ] }, { "label": "C", "location": [ - 5.456844329833984, - -1.599979877471924, + 5.456844, + -1.59998, 0.0 ] }, { "label": "C", "location": [ - 6.842718124389648, - -0.7999899387359619, + 6.842718, + -0.79999, 0.0 ] }, { "label": "C", "location": [ - 6.842718124389648, - 0.7999899387359619, + 6.842718, + 0.79999, 0.0 ] }, { "label": "C", "location": [ - 5.456844329833984, - 1.599979877471924, + 5.456844, + 1.59998, 0.0 ] } @@ -197,24 +197,24 @@ { "label": "C", "location": [ - 18.585243225097658, - 3.599954843521118, + 19.785242, + 3.599955, 0.0 ] }, { "label": "C", "location": [ - 17.19956398010254, - 2.799964189529419, + 18.399563, + 2.799964, 0.0 ] }, { "label": "C", "location": [ - 17.19956398010254, - 1.1999847888946534, + 18.399563, + 1.199985, 0.0 ], "stereoLabel": "&1" @@ -222,32 +222,32 @@ { "label": "C", "location": [ - 18.585243225097658, - 0.3999948501586914, + 19.785242, + 0.399995, 0.0 ] }, { "label": "C", "location": [ - 19.970922470092778, - 1.1999847888946534, + 21.170923, + 1.199985, 0.0 ] }, { "label": "C", "location": [ - 19.970922470092778, - 2.799964189529419, + 21.170923, + 2.799964, 0.0 ] }, { "label": "C", "location": [ - 15.814078330993653, - 0.3999948501586914, + 17.014078, + 0.399995, 0.0 ], "stereoLabel": "&1" @@ -255,64 +255,64 @@ { "label": "C", "location": [ - 14.42839813232422, - 1.1999847888946534, + 15.628398, + 1.199985, 0.0 ] }, { "label": "C", "location": [ - 13.042718887329102, - 0.3999948501586914, + 14.242719, + 0.399995, 0.0 ] }, { "label": "C", "location": [ - 13.042718887329102, - -1.1999850273132325, + 14.242719, + -1.199985, 0.0 ] }, { "label": "C", "location": [ - 14.42839813232422, - -1.999975085258484, + 15.628398, + -1.999975, 0.0 ] }, { "label": "C", "location": [ - 15.814078330993653, - -1.1999850273132325, + 17.014078, + -1.199985, 0.0 ] }, { "label": "P", "location": [ - 17.19956398010254, - -1.999975085258484, + 18.399563, + -1.999975, 0.0 ] }, { "label": "C", "location": [ - 18.799543380737306, - -1.999975085258484, + 19.999542, + -1.999975, 0.0 ] }, { "label": "C", "location": [ - 17.19956398010254, - -3.599954843521118, + 18.399563, + -3.599955, 0.0 ] } diff --git a/api/tests/integration/tests/formats/rxn_no_layout.py b/api/tests/integration/tests/formats/rxn_no_layout.py index 4a013d4629..1f7a1243c5 100644 --- a/api/tests/integration/tests/formats/rxn_no_layout.py +++ b/api/tests/integration/tests/formats/rxn_no_layout.py @@ -11,6 +11,7 @@ indigo = Indigo() indigo.setOption("json-saving-pretty", True) +indigo.setOption("json-use-native-precision", True) root_rxn = joinPathPy("reactions/", __file__) filename = "1113-no-layout.rxn" print(filename) diff --git a/api/tests/integration/tests/layout/acs_style_reaction.py b/api/tests/integration/tests/layout/acs_style_reaction.py new file mode 100644 index 0000000000..6bee3142c0 --- /dev/null +++ b/api/tests/integration/tests/layout/acs_style_reaction.py @@ -0,0 +1,49 @@ +import errno +import os +import sys + +sys.path.append( + os.path.normpath( + os.path.join(os.path.abspath(__file__), "..", "..", "..", "common") + ) +) +from env_indigo import Indigo, joinPathPy, reactionLayoutDiff + +indigo = Indigo() +indigo.setOption("molfile-saving-skip-date", "1") +indigo.setOption("json-saving-pretty", "1") +indigo.setOption("json-use-native-precision", "1") +indigo.setOption("json-saving-add-stereo-desc", "1") + +root = joinPathPy("reactions/", __file__) +ref = joinPathPy("ref/", __file__) + +upd = False + +print("*** ACS reaction layout testing ***") +print("\n*** test zero margin ***") +rxn = indigo.loadReactionFromFile(os.path.join(root, "acs_before_layout.ket")) +indigo.setOption("reaction-component-margin-size", "0.0") +rxn.layout() +res = reactionLayoutDiff( + indigo, + rxn, + "acs_after_layout_zero_margin.ket", + update=upd, + update_format="ket", +) +print(" Result: {}".format(res)) + +print("\n*** test default margin ***") +rxn = indigo.loadReactionFromFile(os.path.join(root, "acs_before_layout.ket")) +indigo.setOption("bond-length", "40.0") +indigo.setOption("reaction-component-margin-size", "20.0") +rxn.layout() +res = reactionLayoutDiff( + indigo, + rxn, + "acs_after_layout_default_margin.ket", + update=upd, + update_format="ket", +) +print(" Result: {}".format(res)) diff --git a/api/tests/integration/tests/layout/basic.py b/api/tests/integration/tests/layout/basic.py index 1b24873475..2ba0c1c17e 100644 --- a/api/tests/integration/tests/layout/basic.py +++ b/api/tests/integration/tests/layout/basic.py @@ -19,12 +19,14 @@ indigo = Indigo() indigo.setOption("molfile-saving-skip-date", "1") +upd = False + print("*** Reaction layout testing ***") test = indigo.loadReaction( "ClCC1CO1>>CN(CC1CO1)S(=O)(=O)C(F)(F)C(F)(F)C(F)(F)C(F)(F)F" ) test.layout() -res = reactionLayoutDiff(indigo, test, "test1.rxn") +res = reactionLayoutDiff(indigo, test, "test1.rxn", update=upd) test.saveRxnfile(joinPathPy("out/test1.rxn", __file__)) print(" Result: {}".format(res)) @@ -71,7 +73,7 @@ def testLayout(m, subset): joinPathPy("molecules/sgroups/datasgroup.mol", __file__) ) m.layout() -res = moleculeLayoutDiff(indigo, m, "test_sgroup.mol") +res = moleculeLayoutDiff(indigo, m, "test_sgroup.mol", update=upd) print(" Result: {}".format(res)) m.saveMolfile(joinPathPy("out/test_sgroup.mol", __file__)) @@ -79,7 +81,7 @@ def testLayout(m, subset): ref = joinPathPy("molecules/sgroups/reaction_datasgroup.rxn", __file__) test = indigo.loadReactionFromFile(ref) test.layout() -res = reactionLayoutDiff(indigo, test, "test_sgroup.rxn") +res = reactionLayoutDiff(indigo, test, "test_sgroup.rxn", update=upd) print(" Result: {}".format(res)) test.saveRxnfile(joinPathPy("out/test_sgroup.rxn", __file__)) @@ -89,7 +91,7 @@ def testLayout(m, subset): joinPathPy("molecules/mol-ind-468.mol", __file__) ) m.layout() -res = moleculeLayoutDiff(indigo, m, "mol-ind-468.mol") +res = moleculeLayoutDiff(indigo, m, "mol-ind-468.mol", update=upd) print(" Result: {}".format(res)) m.saveMolfile(joinPathPy("out/mol-ind-468.mol", __file__)) @@ -100,7 +102,7 @@ def testLayout(m, subset): ) m.layout() # print(m.molfile()) -res = moleculeLayoutDiff(indigo, m, "mol-indsp-93.mol") +res = moleculeLayoutDiff(indigo, m, "mol-indsp-93.mol", update=upd) print(" Result: {}".format(res)) m.saveMolfile(joinPathPy("out/mol-indsp-93.mol", __file__)) @@ -114,9 +116,9 @@ def testLayout(m, subset): sub = mol.getSubmolecule(atoms) sub.layout() # IND-617 -> bug: exception -res = moleculeLayoutDiff(indigo, mol, "ind-617-test-fixed-1.mol") +res = moleculeLayoutDiff(indigo, mol, "ind-617-test-fixed-1.mol", update=upd) print(" mol Result: {}".format(res)) -res = moleculeLayoutDiff(indigo, mol2, "ind-617-test-fixed-2.mol") +res = moleculeLayoutDiff(indigo, mol2, "ind-617-test-fixed-2.mol", update=upd) print(" mol2 Result: {}".format(res)) mol2.saveMolfile(joinPathPy("out/ind-617-test-fixed-2.mol", __file__)) mol.saveMolfile(joinPathPy("out/ind-617-test-fixed-1.mol", __file__)) diff --git a/api/tests/integration/tests/layout/reaction_layout_and_clean2d.py b/api/tests/integration/tests/layout/reaction_layout_and_clean2d.py index 8369d42ff7..0b79599736 100644 --- a/api/tests/integration/tests/layout/reaction_layout_and_clean2d.py +++ b/api/tests/integration/tests/layout/reaction_layout_and_clean2d.py @@ -21,6 +21,8 @@ indigo.setOption("treat-x-as-pseudoatom", "1") indigo.setOption("smart-layout", "1") +upd = False + saver_layout = indigo.writeFile( joinPathPy("out/reaction_layout.rdf", __file__) ) @@ -45,7 +47,11 @@ rxn = item.clone() rxn.layout() res = reactionLayoutDiff( - indigo, rxn, ref_layout.at(idx).rawData(), ref_is_file=False + indigo, + rxn, + ref_layout.at(idx).rawData(), + ref_is_file=False, + update=upd, ) print(" Item #{}: Result of layout: {}".format(idx, res)) saver_layout.rdfAppend(rxn) @@ -61,7 +67,11 @@ rxn = item.clone() rxn.clean2d() res = reactionLayoutDiff( - indigo, rxn, ref_clean2d.at(idx).rawData(), ref_is_file=False + indigo, + rxn, + ref_clean2d.at(idx).rawData(), + ref_is_file=False, + update=upd, ) print(" Item #{}: Result of clean2d: {}".format(idx, res)) saver_clean.rdfAppend(rxn) diff --git a/api/tests/integration/tests/layout/reactions/acs_before_layout.ket b/api/tests/integration/tests/layout/reactions/acs_before_layout.ket new file mode 100644 index 0000000000..97bbf9023f --- /dev/null +++ b/api/tests/integration/tests/layout/reactions/acs_before_layout.ket @@ -0,0 +1,409 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + }, + { + "$ref": "mol3" + }, + { + "$ref": "mol4" + }, + { + "type": "arrow", + "data": { + "mode": "open-angle", + "pos": [ + { + "x": -7.394363028677862, + "y": -6.362093778161939, + "z": 0 + }, + { + "x": -5.694363028677859, + "y": -7.18709377816194, + "z": 0 + } + ] + } + }, + { + "type": "plus", + "location": [ + -12.377241893411822, + -7.324774847536024, + 0 + ], + "prop": {} + }, + { + "type": "plus", + "location": [ + 1.775960072742631, + -6.424774847536024, + 0 + ], + "prop": {} + } + ], + "connections": [], + "templates": [] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + -13.768267539670937, + -6.949774873495124, + 0 + ] + }, + { + "label": "C", + "location": [ + -13.768267390659325, + -5.949774863718258, + 0 + ] + }, + { + "label": "O", + "location": [ + -14.63429292347398, + -5.4497749705885346, + 0 + ] + }, + { + "label": "O", + "location": [ + -12.90224200685628, + -5.449774821576923, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 3 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + -11.002241779967369, + -5.599774887233143, + 0 + ] + }, + { + "label": "C", + "location": [ + -10.136216694187546, + -5.099774807838904, + 0 + ] + }, + { + "label": "C", + "location": [ + -9.270191012361279, + -5.599774812727337, + 0 + ] + }, + { + "label": "C", + "location": [ + -8.404165926581456, + -5.099774807838904, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + -3.904166661693825, + -7.524774873495127, + 0 + ] + }, + { + "label": "C", + "location": [ + -3.03814097986756, + -7.024774794100886, + 0 + ] + }, + { + "label": "O", + "location": [ + -2.1721152980412946, + -7.524774798989321, + 0 + ] + }, + { + "label": "C", + "location": [ + -1.3060908083079177, + -7.024774794100886, + 0 + ] + }, + { + "label": "C", + "location": [ + -0.4400651264816453, + -7.524774798989321, + 0 + ] + }, + { + "label": "C", + "location": [ + 0.4259605553446235, + -7.024774794100886, + 0 + ] + }, + { + "label": "O", + "location": [ + -3.03814097986756, + -6.024774821576924, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 6 + ] + } + ] + }, + "mol3": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 3.300959590140639, + -7.574774847536024, + 0 + ] + } + ] + }, + "mol4": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + -6.339747371437873, + -4.792796796383729, + 0 + ] + }, + { + "label": "N", + "location": [ + -5.555813985618887, + -4.175225152463979, + 0 + ] + }, + { + "label": "C", + "location": [ + -4.582783087033036, + -4.397775297256338, + 0 + ] + }, + { + "label": "C", + "location": [ + -4.148700131348928, + -5.293584700956992, + 0 + ] + }, + { + "label": "C", + "location": [ + -6.334238704487571, + -5.799981430061476, + 0 + ] + }, + { + "label": "N", + "location": [ + -4.582081983966631, + -6.200611753720088, + 0 + ] + }, + { + "label": "C", + "location": [ + -5.555813985618887, + -6.423161898512448, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 1, + 0 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 6 + ] + }, + { + "type": 1, + "atoms": [ + 6, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 1 + ] + } + ] + } +} \ No newline at end of file diff --git a/api/tests/integration/tests/layout/ref/932-agents.ket b/api/tests/integration/tests/layout/ref/932-agents.ket index 48ddc90a81..86cf6df7ec 100644 --- a/api/tests/integration/tests/layout/ref/932-agents.ket +++ b/api/tests/integration/tests/layout/ref/932-agents.ket @@ -43,7 +43,7 @@ { "type": "plus", "location": [ - 4.699999809265137, + 4.1, 0.0, 0.0 ] @@ -51,7 +51,7 @@ { "type": "plus", "location": [ - 8.300000190734864, + 7.5, 0.0, 0.0 ] @@ -59,7 +59,7 @@ { "type": "plus", "location": [ - 55.84254455566406, + 40.442543, 0.0, 0.0 ] @@ -67,7 +67,7 @@ { "type": "plus", "location": [ - 63.3052864074707, + 47.705284, 0.0, 0.0 ] @@ -78,12 +78,12 @@ "mode": "open-angle", "pos": [ { - "x": 12.699999809265137, + "x": 12.400001, "y": 0.0, "z": 0.0 }, { - "x": 52.04254531860352, + "x": 37.142548, "y": 0.0, "z": 0.0 } @@ -98,24 +98,24 @@ { "label": "C", "location": [ - 1.2999999523162842, - 0.6928203105926514, + 0.8, + 0.69282, 0.0 ] }, { "label": "C", "location": [ - 2.8999996185302736, - 0.6928203105926514, + 2.4, + 0.69282, 0.0 ] }, { "label": "C", "location": [ - 2.0999999046325685, - -0.6928203105926514, + 1.6, + -0.69282, 0.0 ] } @@ -150,7 +150,7 @@ { "label": "S", "location": [ - 6.5, + 5.8, 0.0, 0.0 ] @@ -164,32 +164,32 @@ { "label": "C", "location": [ - 10.100000381469729, - 0.7999998927116394, + 9.200001, + 0.8, 0.0 ] }, { "label": "C", "location": [ - 11.699999809265137, - 0.7999998927116394, + 10.8, + 0.8, 0.0 ] }, { "label": "C", "location": [ - 11.699999809265137, - -0.7999998927116394, + 10.8, + -0.8, 0.0 ] }, { "label": "C", "location": [ - 10.100000381469729, - -0.7999998927116394, + 9.200001, + -0.8, 0.0 ] } @@ -231,24 +231,24 @@ { "label": "C", "location": [ - 15.90000057220459, - 1.892820119857788, + 14.000001, + 2.69282, 0.0 ] }, { "label": "C", "location": [ - 17.285640716552736, - 1.0928202867507937, + 15.385641, + 1.89282, 0.0 ] }, { "label": "C", "location": [ - 18.671281814575197, - 1.892820119857788, + 16.771282, + 2.69282, 0.0 ] } @@ -276,8 +276,8 @@ { "label": "C", "location": [ - 22.871280670166017, - 1.4928202629089356, + 19.17128, + 2.29282, 0.0 ] } @@ -290,8 +290,8 @@ { "label": "P", "location": [ - 27.071279525756837, - 1.4928202629089356, + 21.571278, + 2.29282, 0.0 ] } @@ -304,24 +304,24 @@ { "label": "C", "location": [ - 31.271278381347658, - 1.892820119857788, + 23.971275, + 2.69282, 0.0 ] }, { "label": "C", "location": [ - 32.65691757202149, - 1.0928202867507937, + 25.356916, + 1.89282, 0.0 ] }, { "label": "C", "location": [ - 34.04256057739258, - 1.892820119857788, + 26.742556, + 2.69282, 0.0 ] } @@ -349,24 +349,24 @@ { "label": "C", "location": [ - 38.242557525634769, - 2.185640573501587, + 29.142553, + 2.985641, 0.0 ] }, { "label": "C", "location": [ - 39.84255599975586, - 2.185640573501587, + 30.742554, + 2.985641, 0.0 ] }, { "label": "C", "location": [ - 39.04255676269531, - 0.7999999523162842, + 29.942553, + 1.6, 0.0 ] } @@ -401,8 +401,8 @@ { "label": "F", "location": [ - 44.04255294799805, - 1.4928202629089356, + 33.142551, + 2.29282, 0.0 ] } @@ -415,8 +415,8 @@ { "label": "I", "location": [ - 48.24254989624024, - 1.4928202629089356, + 35.542549, + 2.29282, 0.0 ] } @@ -429,7 +429,7 @@ { "label": "S", "location": [ - 54.04254531860352, + 38.742546, 0.0, 0.0 ] @@ -443,64 +443,64 @@ { "label": "C", "location": [ - 60.3739128112793, - 1.931370735168457, + 44.873913, + 1.931371, 0.0 ] }, { "label": "C", "location": [ - 58.7739143371582, - 1.931370735168457, + 43.273914, + 1.931371, 0.0 ] }, { "label": "C", "location": [ - 57.64254379272461, - 0.7999999523162842, + 42.142544, + 0.8, 0.0 ] }, { "label": "C", "location": [ - 57.64254379272461, - -0.7999998331069946, + 42.142544, + -0.8, 0.0 ] }, { "label": "C", "location": [ - 58.7739143371582, - -1.931370735168457, + 43.273914, + -1.931371, 0.0 ] }, { "label": "C", "location": [ - 60.3739128112793, - -1.931370735168457, + 44.873913, + -1.931371, 0.0 ] }, { "label": "C", "location": [ - 61.50528717041016, - -0.7999998331069946, + 46.005287, + -0.8, 0.0 ] }, { "label": "C", "location": [ - 61.50528335571289, - 0.7999999523162842, + 46.005283, + 0.8, 0.0 ] } @@ -570,7 +570,7 @@ { "label": "O", "location": [ - 65.10528564453125, + 49.405285, 0.0, 0.0 ] diff --git a/api/tests/integration/tests/layout/ref/acs_after_layout_default_margin.ket b/api/tests/integration/tests/layout/ref/acs_after_layout_default_margin.ket new file mode 100644 index 0000000000..574b2dd3dd --- /dev/null +++ b/api/tests/integration/tests/layout/ref/acs_after_layout_default_margin.ket @@ -0,0 +1,406 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + }, + { + "$ref": "mol3" + }, + { + "$ref": "mol4" + }, + { + "type": "plus", + "location": [ + 5.271281, + 0.0, + 0.0 + ] + }, + { + "type": "plus", + "location": [ + 29.75157, + 0.0, + 0.0 + ] + }, + { + "type": "arrow", + "data": { + "mode": "open-angle", + "pos": [ + { + "x": 12.728203, + "y": 0.0, + "z": 0.0 + }, + { + "x": 19.523369, + "y": 0.0, + "z": 0.0 + } + ] + } + } + ] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 2.185641, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 2.185641, + 0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 0.8, + 1.2, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 3.571281, + 1.2, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 3 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 6.971282, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 8.356922, + 0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 9.742562, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 11.128202, + 0.4, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 21.123369, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 22.50901, + -0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 23.89465, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 25.280291, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 26.665932, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 28.051571, + -0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 22.50901, + 1.2, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 6 + ] + } + ] + }, + "mol3": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 31.451569, + 0.0, + 0.0 + ] + } + ], + "bonds": [] + }, + "mol4": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + 16.925787, + 5.10503, + 0.0 + ] + }, + { + "label": "N", + "location": [ + 15.325788, + 5.10503, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 14.328203, + 3.8541, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 14.684236, + 2.294215, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 17.923372, + 3.854097, + 0.0 + ] + }, + { + "label": "N", + "location": [ + 16.125786, + 1.6, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 17.567337, + 2.294213, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 1, + 0 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 6 + ] + }, + { + "type": 1, + "atoms": [ + 6, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 1 + ] + } + ] + } +} \ No newline at end of file diff --git a/api/tests/integration/tests/layout/ref/acs_after_layout_zero_margin.ket b/api/tests/integration/tests/layout/ref/acs_after_layout_zero_margin.ket new file mode 100644 index 0000000000..33b2f3ea27 --- /dev/null +++ b/api/tests/integration/tests/layout/ref/acs_after_layout_zero_margin.ket @@ -0,0 +1,406 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + }, + { + "$ref": "mol3" + }, + { + "$ref": "mol4" + }, + { + "type": "plus", + "location": [ + 4.871281, + 0.0, + 0.0 + ] + }, + { + "type": "plus", + "location": [ + 25.351574, + 0.0, + 0.0 + ] + }, + { + "type": "arrow", + "data": { + "mode": "open-angle", + "pos": [ + { + "x": 11.128203, + "y": 0.0, + "z": 0.0 + }, + { + "x": 16.323372, + "y": 0.0, + "z": 0.0 + } + ] + } + } + ] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 2.185641, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 2.185641, + 0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 0.8, + 1.2, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 3.571281, + 1.2, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 3 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 6.171281, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 7.556922, + 0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 8.942562, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 10.328203, + 0.4, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 17.123371, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 18.509012, + -0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 19.894651, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 21.280293, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 22.665934, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 24.051575, + -0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 18.509012, + 1.2, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 6 + ] + } + ] + }, + "mol3": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 26.651573, + 0.0, + 0.0 + ] + } + ], + "bonds": [] + }, + "mol4": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + 14.525787, + 4.30503, + 0.0 + ] + }, + { + "label": "N", + "location": [ + 12.925788, + 4.30503, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 11.928204, + 3.0541, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 12.284236, + 1.494215, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 15.523372, + 3.054097, + 0.0 + ] + }, + { + "label": "N", + "location": [ + 13.725786, + 0.8, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 15.167336, + 1.494213, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 1, + 0 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 6 + ] + }, + { + "type": 1, + "atoms": [ + 6, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 1 + ] + } + ] + } +} \ No newline at end of file diff --git a/api/tests/integration/tests/layout/ref/reaction_layout.rdf b/api/tests/integration/tests/layout/ref/reaction_layout.rdf index 46f3e0097b..b387c7c006 100644 --- a/api/tests/integration/tests/layout/ref/reaction_layout.rdf +++ b/api/tests/integration/tests/layout/ref/reaction_layout.rdf @@ -9,14 +9,14 @@ $MOL -INDIGO-01000000002D 8 7 0 0 0 0 0 0 0 0999 V2000 - 1.3000 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 2.6856 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 4.0713 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 5.4569 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 6.8426 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 8.2282 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 9.6138 1.2000 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0 - 5.4569 -1.2000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 0.8000 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.1856 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.5713 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.9569 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.3426 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.7282 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1138 1.2000 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0 + 4.9569 -1.2000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 1 0 0 0 0 3 4 1 0 0 0 0 @@ -30,12 +30,12 @@ $MOL -INDIGO-01000000002D 6 6 0 0 0 0 0 0 0 0999 V2000 - 14.5995 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 13.2138 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 13.2138 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 14.5995 -1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 15.9851 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 15.9851 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.8995 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5138 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5138 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.8995 -1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.2851 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.2851 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 2 0 0 0 0 3 4 1 0 0 0 0 @@ -48,13 +48,13 @@ $MOL -INDIGO-01000000002D 7 6 0 0 0 0 0 0 0 0999 V2000 - 22.1851 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 23.5708 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 24.9564 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 26.3420 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 27.7277 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 29.1133 1.2000 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0 - 24.9564 -1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.6851 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.0708 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.4564 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.8420 1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.2277 0.4000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.6133 1.2000 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0 + 24.4564 -1.2000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 1 0 0 0 0 3 4 1 0 0 0 0 @@ -67,13 +67,13 @@ $MOL -INDIGO-01000000002D 7 7 0 0 0 0 0 0 0 0999 V2000 - 32.7133 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 33.5133 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 35.1133 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 35.9133 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 35.1133 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 33.5133 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 37.5133 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 32.0133 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.8133 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.4133 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.2133 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.4133 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.8133 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.8133 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 2 0 0 0 0 3 4 1 0 0 0 0 diff --git a/api/tests/integration/tests/layout/ref/test1.rxn b/api/tests/integration/tests/layout/ref/test1.rxn index 38bf3dff3a..29b19b4eb8 100644 --- a/api/tests/integration/tests/layout/ref/test1.rxn +++ b/api/tests/integration/tests/layout/ref/test1.rxn @@ -8,11 +8,11 @@ $MOL -INDIGO-01000000002D 5 5 0 0 0 0 0 0 0 0999 V2000 - 1.3000 -1.0928 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0 - 2.1000 0.2928 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 3.7000 0.2928 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 5.0856 -0.5072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 5.0856 1.0928 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 0.8000 -1.0928 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + 1.6000 0.2928 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.2000 0.2928 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.5856 -0.5072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.5856 1.0928 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 1 0 0 0 0 3 4 1 0 0 0 0 @@ -24,28 +24,28 @@ $MOL -INDIGO-01000000002D 22 22 0 0 0 0 0 0 0 0999 V2000 - 15.6569 -2.3391 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 15.6569 -0.7391 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 - 14.2713 0.0609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 12.8856 -0.7391 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 12.0856 -2.1247 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 11.2856 -0.7391 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 17.0426 0.0609 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 - 16.2426 1.4465 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 17.8426 -1.3247 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 - 18.4282 0.8609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 19.0405 2.3391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 17.8159 2.3391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 19.8138 0.0609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 19.2016 -1.4173 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 20.4261 -1.4173 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 21.1995 0.8609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 21.8118 2.3391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 20.5872 2.3391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 22.5851 0.0609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 22.5851 -1.5391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 23.9708 0.8609 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 - 23.9708 -0.7391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 15.3569 -2.3391 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.3569 -0.7391 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 13.9713 0.0609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5856 -0.7391 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.7856 -2.1247 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.9856 -0.7391 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 16.7426 0.0609 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 15.9426 1.4465 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 17.5426 -1.3247 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 18.1282 0.8609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.7405 2.3391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 17.5159 2.3391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 19.5138 0.0609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.9016 -1.4173 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 20.1261 -1.4173 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 20.8995 0.8609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.5118 2.3391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 20.2872 2.3391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 22.2851 0.0609 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.2851 -1.5391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 23.6708 0.8609 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 23.6708 -0.7391 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 1 0 0 0 0 3 4 1 0 0 0 0 diff --git a/api/tests/integration/tests/layout/ref/test_sgroup.rxn b/api/tests/integration/tests/layout/ref/test_sgroup.rxn index 8ccdbbdb32..8fe3567ad9 100644 --- a/api/tests/integration/tests/layout/ref/test_sgroup.rxn +++ b/api/tests/integration/tests/layout/ref/test_sgroup.rxn @@ -8,12 +8,12 @@ $MOL -INDIGO-01000000002D 6 6 0 0 0 0 0 0 0 0999 V2000 - 3.7000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 2.1000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 1.3000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 2.1000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 3.7000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 4.5000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.2000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.6000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.8000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.6000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.2000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.0000 0.0000 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 3 4 2 0 0 0 0 @@ -24,7 +24,7 @@ M STY 1 1 DAT M SLB 1 1 1 M SAL 1 6 1 2 3 4 5 6 M SDT 1 asd -M SDD 1 4.0571 -0.8839 DA ALL 1 1 +M SDD 1 3.5571 -0.8839 DA ALL 1 1 M SED 1 asd M END $MOL @@ -32,12 +32,12 @@ $MOL -INDIGO-01000000002D 6 6 0 0 0 0 0 0 0 0999 V2000 - 13.1000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 11.5000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 10.7000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 11.5000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 13.1000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 13.9000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.8000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.2000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.4000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.2000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.8000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6000 0.0000 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 3 4 2 0 0 0 0 @@ -48,6 +48,6 @@ M STY 1 1 DAT M SLB 1 1 1 M SAL 1 6 1 2 3 4 5 6 M SDT 1 AAA -M SDD 1 10.2376 -2.0277 DAU ALL 1 1 +M SDD 1 9.9376 -2.0277 DAU ALL 1 1 M SED 1 BBBBB M END diff --git a/api/tests/integration/tests/layout/smiles_layout.py b/api/tests/integration/tests/layout/smiles_layout.py index 8473a0348d..7e1f6b1adf 100644 --- a/api/tests/integration/tests/layout/smiles_layout.py +++ b/api/tests/integration/tests/layout/smiles_layout.py @@ -16,6 +16,7 @@ def find_diff(a, b): indigo = Indigo() indigo.setOption("json-saving-pretty", True) +indigo.setOption("json-use-native-precision", True) print("*** SMILES LAYOUT ***") diff --git a/api/tests/integration/tests/reaction/reactions/issue_1205.ket b/api/tests/integration/tests/reaction/reactions/issue_1205.ket index d5d8a1777c..c12051172b 100644 --- a/api/tests/integration/tests/reaction/reactions/issue_1205.ket +++ b/api/tests/integration/tests/reaction/reactions/issue_1205.ket @@ -1 +1,258 @@ -{"root":{"nodes":[{"$ref":"mol0"},{"$ref":"mol1"},{"$ref":"mol2"},{"$ref":"mol3"},{"type":"arrow","data":{"mode":"open-angle","pos":[{"x":10.515000343322754,"y":-8.324899673461914,"z":0.0},{"x":15.03459930419922,"y":-8.274900436401368,"z":0.0}]}}]},"mol0":{"type":"molecule","atoms":[{"label":"C","location":[7.7846999168396,-7.824999809265137,0.0]},{"label":"C","location":[9.515000343322754,-7.82450008392334,0.0]},{"label":"C","location":[8.65149974822998,-7.324900150299072,0.0]},{"label":"C","location":[9.515000343322754,-8.825400352478028,0.0]},{"label":"C","location":[7.7846999168396,-8.829899787902832,0.0]},{"label":"C","location":[8.65369987487793,-9.324899673461914,0.0]}],"bonds":[{"type":2,"atoms":[2,0]},{"type":2,"atoms":[3,1]},{"type":1,"atoms":[0,4]},{"type":1,"atoms":[1,2]},{"type":2,"atoms":[4,5]},{"type":1,"atoms":[5,3]}]},"mol1":{"type":"molecule","atoms":[{"label":"C","location":[16.03459930419922,-7.775000095367432,0.0]},{"label":"C","location":[17.76499938964844,-7.774499893188477,0.0]},{"label":"C","location":[16.90139961242676,-7.274899959564209,0.0]},{"label":"C","location":[17.76499938964844,-8.775400161743164,0.0]},{"label":"C","location":[16.03459930419922,-8.779899597167969,0.0]},{"label":"C","location":[16.903600692749025,-9.274900436401368,0.0]}],"bonds":[{"type":2,"atoms":[2,0]},{"type":2,"atoms":[3,1]},{"type":1,"atoms":[0,4]},{"type":1,"atoms":[1,2]},{"type":2,"atoms":[4,5]},{"type":1,"atoms":[5,3]}]},"mol2":{"type":"molecule","atoms":[{"label":"Cl","location":[12.974800109863282,-8.824899673461914,0.0]}],"bonds":[]},"mol3":{"type":"molecule","atoms":[{"label":"N","location":[12.549799919128418,-7.724899768829346,0.0]}],"bonds":[]}} \ No newline at end of file +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + }, + { + "$ref": "mol3" + }, + { + "type": "arrow", + "data": { + "mode": "open-angle", + "pos": [ + { + "x": 11.115001, + "y": -8.3249, + "z": 0.0 + }, + { + "x": 14.434599, + "y": -8.2749, + "z": 0.0 + } + ] + } + } + ] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 7.7847, + -7.825, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 9.515, + -7.8245, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 8.6515, + -7.3249, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 9.515, + -8.8254, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 7.7847, + -8.8299, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 8.6537, + -9.3249, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 2, + "atoms": [ + 2, + 0 + ] + }, + { + "type": 2, + "atoms": [ + 3, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 16.034599, + -7.775, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 17.764999, + -7.7745, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 16.9014, + -7.2749, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 17.764999, + -8.7754, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 16.034599, + -8.7799, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 16.903601, + -9.2749, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 2, + "atoms": [ + 2, + 0 + ] + }, + { + "type": 2, + "atoms": [ + 3, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "Cl", + "location": [ + 12.9748, + -8.8249, + 0.0 + ] + } + ], + "bonds": [] + }, + "mol3": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + 12.5498, + -7.7249, + 0.0 + ] + } + ], + "bonds": [] + } +} \ No newline at end of file diff --git a/api/tests/integration/tests/reaction/save_ket_layout_1205.py b/api/tests/integration/tests/reaction/save_ket_layout_1205.py index 1988a7ea3c..1a52b511ac 100644 --- a/api/tests/integration/tests/reaction/save_ket_layout_1205.py +++ b/api/tests/integration/tests/reaction/save_ket_layout_1205.py @@ -15,6 +15,9 @@ def find_diff(a, b): from env_indigo import * indigo = Indigo() +indigo.setOption("json-saving-pretty", True) +indigo.setOption("json-use-native-precision", True) + r1 = indigo.loadReactionFromFile( joinPathPy("reactions/issue_1205.rxn", __file__) ) diff --git a/api/tests/integration/tests/todo/bingo_get_indigo_object_bug.py b/api/tests/integration/tests/todo/bingo_get_indigo_object_bug.py index 36b5a11bb3..39db5001eb 100644 --- a/api/tests/integration/tests/todo/bingo_get_indigo_object_bug.py +++ b/api/tests/integration/tests/todo/bingo_get_indigo_object_bug.py @@ -10,7 +10,7 @@ indigo = Indigo() bingo = Bingo.createDatabaseFile( - indigo, joiinPathPy("out/get_indigo_object_bug", __file__), "molecule" + indigo, joinPathPy("out/get_indigo_object_bug", __file__), "molecule" ) for item in ("C1=CC=CC=C1", "C1=CN=CC=C1"): bingo.insert(indigo.loadMolecule(item)) diff --git a/core/indigo-core/common/math/algebra.h b/core/indigo-core/common/math/algebra.h index d966f976b2..a4b607313b 100644 --- a/core/indigo-core/common/math/algebra.h +++ b/core/indigo-core/common/math/algebra.h @@ -218,7 +218,7 @@ namespace indigo DLLEXPORT float calc_angle_pos(Vec2f a, Vec2f b); - inline void scale(float s) + inline void scale(const float s) { x *= s; y *= s; diff --git a/core/indigo-core/layout/metalayout.h b/core/indigo-core/layout/metalayout.h index 08ab53a2de..e92803c89f 100644 --- a/core/indigo-core/layout/metalayout.h +++ b/core/indigo-core/layout/metalayout.h @@ -21,7 +21,9 @@ #include "base_cpp/obj_array.h" #include "base_cpp/reusable_obj_array.h" + #include "math/algebra.h" +#include #ifdef _WIN32 #pragma warning(push) @@ -44,6 +46,11 @@ namespace indigo ETop, EBottom }; + enum class Type + { + EMolecule = 0, + ESpace = 1 + }; LayoutItem() { @@ -53,9 +60,9 @@ namespace indigo void clear() { verticalAlign = ItemVerticalAlign::ECenter; - type = 0; + type = Type::EMolecule; id = 0; - fragment = false; + isMoleculeFragment = false; min.zero(); max.zero(); scaledSize.zero(); @@ -63,9 +70,9 @@ namespace indigo scaleFactor.zero(); minScaledSize.zero(); } - int type; + Type type; int id; - bool fragment; + bool isMoleculeFragment; ItemVerticalAlign verticalAlign; Vec2f min, max; @@ -93,16 +100,15 @@ namespace indigo Metalayout(); void clear(); bool isEmpty() const; - void prepare(); + void prepare(); // calculates averageBondLength and scaleFactor float getAverageBondLength() const; float getScaleFactor() const; const Vec2f& getContentSize() const; - void setScaleFactor(); void process(); LayoutLine& newLine(); static void getBoundRect(Vec2f& min, Vec2f& max, BaseMolecule& mol); void calcContentSize(); - void scaleSz(); + void scaleMoleculesSize(); void* context; void (*cb_process)(LayoutItem& item, const Vec2f& pos, void* context); @@ -112,9 +118,9 @@ namespace indigo static float getTotalMoleculeClosestDist(BaseMolecule& mol); // utility function to use in MoleculeLayout & ReactionLayout - void adjustMol(BaseMolecule& mol, const Vec2f& min, const Vec2f& pos); + void adjustMol(BaseMolecule& mol, const Vec2f& min, const Vec2f& pos) const; - float horizontalIntervalFactor; + float reactionComponentMarginSize; float verticalIntervalFactor; float bondLength; @@ -129,6 +135,120 @@ namespace indigo ReusableObjArray _layout; }; + struct UnitsOfMeasure + { + enum TYPE + { + PT, + PX, + INCH, + CM + }; + + static constexpr float INCH_TO_CM = 2.54f; + static constexpr float INCH_TO_PT = 72.0f; + + static float convertInchesToPx(const float inches, const int32_t ppi) + { + return inches * ppi; + } + static float convertPxToInches(const float pixels, const int32_t ppi) + { + return pixels / ppi; + } + static float convertToPx(const float input, const TYPE units, const int32_t ppi) + { + switch (units) + { + case (PT): + return convertInchesToPx(input / INCH_TO_PT, ppi); + break; + case (INCH): + return convertInchesToPx(input, ppi); + break; + case (CM): + return convertInchesToPx(input / INCH_TO_CM, ppi); + break; + default: + return input; + } + } + + static float convertToPt(const float input, const TYPE units, const int32_t ppi) + { + switch (units) + { + case (PX): + return convertPxToInches(input, ppi) * INCH_TO_PT; + break; + case (INCH): + return input * INCH_TO_PT; + break; + case (CM): + return (input * INCH_TO_PT) / INCH_TO_CM; + break; + default: + return input; + } + } + + static float convertToInches(const float input, const TYPE units, const int32_t ppi) + { + switch (units) + { + case (PT): + return input / INCH_TO_PT; + break; + case (PX): + return convertPxToInches(input, ppi); + break; + case (CM): + return input / INCH_TO_CM; + break; + default: + return input; + } + } + + static float convertToCm(const float input, const TYPE units, const int32_t ppi) + { + switch (units) + { + case (PT): + return (input * INCH_TO_CM) / INCH_TO_PT; + break; + case (INCH): + return input * INCH_TO_CM; + break; + case (PX): + return convertPxToInches(input, ppi) * INCH_TO_CM; + break; + default: + return input; + } + } + }; + + struct LayoutOptions + { + // FIXME: The value is 1.6 instead of 1.0 due to backward compatibility, needs to be refactored + static constexpr float DEFAULT_BOND_LENGTH = 1.6f; // default length of inter-chemical bonds + static constexpr float DEFAULT_PLUS_SIZE = 1.0f; + + float bondLength{DEFAULT_BOND_LENGTH}; + UnitsOfMeasure::TYPE bondLengthUnit{UnitsOfMeasure::TYPE::PX}; + float reactionComponentMarginSize{DEFAULT_BOND_LENGTH / 2}; + UnitsOfMeasure::TYPE reactionComponentMarginSizeUnit{UnitsOfMeasure::TYPE::PX}; + int32_t ppi{72}; + float getMarginSizeInAngstroms() const + { + auto marginSizePt = UnitsOfMeasure::convertToPt(reactionComponentMarginSize, reactionComponentMarginSizeUnit, ppi); + auto bondLengthPt = UnitsOfMeasure::convertToPt(bondLength, bondLengthUnit, ppi); + + return (DEFAULT_BOND_LENGTH * marginSizePt) / bondLengthPt; + } + }; + } // namespace indigo #ifdef _WIN32 diff --git a/core/indigo-core/layout/molecule_layout.h b/core/indigo-core/layout/molecule_layout.h index d52920acce..ce1f71ecf1 100644 --- a/core/indigo-core/layout/molecule_layout.h +++ b/core/indigo-core/layout/molecule_layout.h @@ -40,7 +40,6 @@ namespace indigo { LAYOUT_MAX_ITERATION = 20 }; - static constexpr float DEFAULT_BOND_LENGTH = 1.6f; explicit MoleculeLayout(BaseMolecule& molecule, bool smart_layout = false); diff --git a/core/indigo-core/layout/reaction_layout.h b/core/indigo-core/layout/reaction_layout.h index 223e319693..58386894aa 100644 --- a/core/indigo-core/layout/reaction_layout.h +++ b/core/indigo-core/layout/reaction_layout.h @@ -33,6 +33,7 @@ namespace indigo { public: explicit ReactionLayout(BaseReaction& r, bool smart_layout = false); + explicit ReactionLayout(BaseReaction& r, bool smart_layout, const LayoutOptions& options); static constexpr float DEFAULT_HOR_INTERVAL_FACTOR = 1.4f; @@ -42,23 +43,21 @@ namespace indigo void fixLayout(); void processSideBoxes(std::vector& pluses, Rect2f& type_box, int side); - float bond_length; - float atom_label_width; - float plus_interval_factor; - float arrow_interval_factor; - float horizontal_interval_factor; - bool preserve_molecule_layout; - int max_iterations; - bool _smart_layout; - layout_orientation_value layout_orientation; + const float bond_length; + const float atom_label_margin; + const float default_plus_size; + const float default_arrow_size; + const float reaction_margin_size; + bool preserve_molecule_layout = false; + int max_iterations = 0; + bool _smart_layout = false; + layout_orientation_value layout_orientation = UNCPECIFIED; private: void _updateMetadata(); void _pushMol(Metalayout::LayoutLine& line, int id, bool is_agent = false); void _pushSpace(Metalayout::LayoutLine& line, float size); BaseMolecule& _getMol(int id); - void _shiftMol(const Metalayout::LayoutItem& item, const Vec2f& pos); - void _make(); static BaseMolecule& cb_getMol(int id, void* context); static void cb_process(Metalayout::LayoutItem& item, const Vec2f& pos, void* context); diff --git a/core/indigo-core/layout/src/metalayout.cpp b/core/indigo-core/layout/src/metalayout.cpp index 743b2b9808..8e39588f63 100644 --- a/core/indigo-core/layout/src/metalayout.cpp +++ b/core/indigo-core/layout/src/metalayout.cpp @@ -39,7 +39,7 @@ void Metalayout::LayoutLine::clear() IMPL_ERROR(Metalayout, "metalayout"); -Metalayout::Metalayout() : horizontalIntervalFactor(0.5f), verticalIntervalFactor(0.8f), bondLength(1.0f), _avel(1.0f), _scaleFactor(1.0f) +Metalayout::Metalayout() : reactionComponentMarginSize(0.5f), verticalIntervalFactor(0.8f), bondLength(1.0f), _avel(1.0f), _scaleFactor(1.0f) { clear(); } @@ -86,6 +86,7 @@ Metalayout::LayoutLine& Metalayout::newLine() void Metalayout::process() { Vec2f pos; + static const auto atomLabelMarginVertical = bondLength / 2; for (int i = 0; i < _layout.size(); ++i) { LayoutLine& line = _layout[i]; @@ -95,12 +96,14 @@ void Metalayout::process() { LayoutItem& item = line.items[j]; Vec2f offset(pos); + auto shiftToAlignAboveVerticalCenter = line.top_height / 2; switch (item.verticalAlign) { case LayoutItem::ItemVerticalAlign::ECenter: break; case LayoutItem::ItemVerticalAlign::ETop: - offset.y += (bondLength + line.top_height) / 2; + // catalyst + offset.y += reactionComponentMarginSize + atomLabelMarginVertical + shiftToAlignAboveVerticalCenter; break; case LayoutItem::ItemVerticalAlign::EBottom: offset.y -= (bondLength + line.bottom_height) / 2; @@ -138,7 +141,7 @@ void Metalayout::calcContentSize() break; } } - line.width += horizontalIntervalFactor * bondLength * (line.items.size() - 1); + line.width += reactionComponentMarginSize * bondLength * (line.items.size() - 1); _contentSize.x = std::max(_contentSize.x, line.width); _contentSize.y += line.height; if (regularWidth < line.width) @@ -147,19 +150,21 @@ void Metalayout::calcContentSize() _contentSize.y += verticalIntervalFactor * bondLength * (_layout.size() - 1); } -void Metalayout::scaleSz() +void Metalayout::scaleMoleculesSize() { for (int i = 0; i < _layout.size(); ++i) + { for (int j = 0; j < _layout[i].items.size(); ++j) { LayoutItem& item = _layout[i].items[j]; - if (item.fragment) + if (item.isMoleculeFragment) { item.scaledSize.diff(item.max, item.min); item.scaledSize.scale(_scaleFactor); item.scaledSize.max(item.minScaledSize); } } + } } float Metalayout::_getAverageBondLength() @@ -173,7 +178,7 @@ float Metalayout::_getAverageBondLength() for (int j = 0; j < line.items.size(); ++j) { LayoutItem& item = line.items[j]; - if (item.fragment) + if (item.isMoleculeFragment) { BaseMolecule& mol = cb_getMol(item.id, context); totalBondCount += mol.edgeCount(); @@ -195,7 +200,7 @@ float Metalayout::_getAverageBondLength() for (int j = 0; j < line.items.size(); ++j) { LayoutItem& item = line.items[j]; - if (item.fragment) + if (item.isMoleculeFragment) { BaseMolecule& mol = cb_getMol(item.id, context); int atomCnt = mol.vertexCount(); @@ -280,10 +285,8 @@ float Metalayout::getTotalMoleculeClosestDist(BaseMolecule& mol) return sum; } -void Metalayout::adjustMol(BaseMolecule& mol, const Vec2f& min, const Vec2f& pos) +void Metalayout::adjustMol(BaseMolecule& mol, const Vec2f& min, const Vec2f& pos) const { - float scaleFactor = getScaleFactor(); - // Compute center points for the data sgroups QS_DEF(Array, data_centers); data_centers.resize(mol.sgroups.getSGroupCount()); @@ -303,7 +306,7 @@ void Metalayout::adjustMol(BaseMolecule& mol, const Vec2f& min, const Vec2f& pos Vec2f v; Vec2f::projectZ(v, mol.getAtomXyz(i)); v.sub(min); - v.scale(scaleFactor); + v.scale(_scaleFactor); v.add(pos); mol.setAtomXyz(i, v.x, v.y, 0); } diff --git a/core/indigo-core/layout/src/molecule_layout.cpp b/core/indigo-core/layout/src/molecule_layout.cpp index 1dc96c6b6e..9daf2002aa 100644 --- a/core/indigo-core/layout/src/molecule_layout.cpp +++ b/core/indigo-core/layout/src/molecule_layout.cpp @@ -398,8 +398,8 @@ void MoleculeLayout::_make() Metalayout::LayoutItem& MoleculeLayout::_pushMol(Metalayout::LayoutLine& line, BaseMolecule& mol) { Metalayout::LayoutItem& item = line.items.push(); - item.type = 0; - item.fragment = true; + item.type = Metalayout::LayoutItem::Type::EMolecule; + item.isMoleculeFragment = true; item.id = _map.size(); _map.push(&mol); Metalayout::getBoundRect(item.min, item.max, mol); @@ -452,7 +452,7 @@ void MoleculeLayout::make() _ml.cb_getMol = cb_getMol; _ml.cb_process = cb_process; _ml.prepare(); - _ml.scaleSz(); + _ml.scaleMoleculesSize(); _ml.calcContentSize(); _ml.process(); } diff --git a/core/indigo-core/layout/src/reaction_layout.cpp b/core/indigo-core/layout/src/reaction_layout.cpp index 7b81e1c58d..22316b1bdd 100644 --- a/core/indigo-core/layout/src/reaction_layout.cpp +++ b/core/indigo-core/layout/src/reaction_layout.cpp @@ -21,14 +21,24 @@ #include "molecule/ket_commons.h" #include "molecule/molecule.h" #include "reaction/reaction.h" +#include #include #include +using namespace std::placeholders; using namespace indigo; ReactionLayout::ReactionLayout(BaseReaction& r, bool smart_layout) - : bond_length(MoleculeLayout::DEFAULT_BOND_LENGTH), plus_interval_factor(1), arrow_interval_factor(2), preserve_molecule_layout(false), _r(r), - _smart_layout(smart_layout), horizontal_interval_factor(DEFAULT_HOR_INTERVAL_FACTOR), atom_label_width(1.3f), layout_orientation(UNCPECIFIED), + : bond_length(LayoutOptions::DEFAULT_BOND_LENGTH), default_plus_size(1), default_arrow_size(2), preserve_molecule_layout(false), _r(r), + _smart_layout(smart_layout), reaction_margin_size(DEFAULT_HOR_INTERVAL_FACTOR), atom_label_margin(1.3f), layout_orientation(UNCPECIFIED), + max_iterations(0) +{ +} + +ReactionLayout::ReactionLayout(BaseReaction& r, bool smart_layout, const LayoutOptions& options) + : bond_length(LayoutOptions::DEFAULT_BOND_LENGTH), default_plus_size(LayoutOptions::DEFAULT_PLUS_SIZE), + default_arrow_size(LayoutOptions::DEFAULT_BOND_LENGTH * 2), preserve_molecule_layout(false), _r(r), _smart_layout(smart_layout), + reaction_margin_size(options.getMarginSizeInAngstroms()), atom_label_margin(LayoutOptions::DEFAULT_BOND_LENGTH / 2), layout_orientation(UNCPECIFIED), max_iterations(0) { } @@ -122,28 +132,27 @@ void ReactionLayout::_updateMetadata() for (const auto& plus_offset : pluses) _r.meta().addMetaObject(new KETReactionPlus(plus_offset)); + // calculate arrow size and position Vec2f arrow_head(0, 0); Vec2f arrow_tail(0, 0); - - constexpr float shift = 1.0f; if (_r.productsCount() == 0) { - arrow_tail.x = react_box.right() + shift; + arrow_tail.x = react_box.right() + reaction_margin_size + atom_label_margin; arrow_tail.y = react_box.middleY(); - arrow_head.x = arrow_tail.x + shift; + arrow_head.x = arrow_tail.x + default_arrow_size + atom_label_margin; arrow_head.y = arrow_tail.y; } else if (_r.reactantsCount() == 0) { - arrow_head.x = product_box.left() - shift; + arrow_head.x = product_box.left() - reaction_margin_size - atom_label_margin; arrow_head.y = product_box.middleY(); - arrow_tail.x = arrow_head.x - shift; + arrow_tail.x = arrow_head.x - default_arrow_size - atom_label_margin; arrow_tail.y = arrow_head.y; } else { - const float ptab = first_single_product ? 2.0f : 1.0f; - const float rtab = last_single_reactant ? 2.0f : 1.0f; + const float ptab = /*first_single_product ? reaction_margin_size * 2 :*/ reaction_margin_size + atom_label_margin; + const float rtab = /*last_single_reactant ? reaction_margin_size * 2 :*/ reaction_margin_size + atom_label_margin; arrow_head.y = product_box.middleY(); arrow_tail.y = react_box.middleY(); @@ -199,9 +208,7 @@ void ReactionLayout::make() if (arrows_count > 1 || simple_count) return; // not implemented yet - const auto kHalfBondLength = bond_length / 2; - const auto kDoubleBondLength = bond_length * 2; - // update layout of molecules, if needed + // update layout of molecules, if needed if (!preserve_molecule_layout) { for (int i = _r.begin(); i < _r.end(); i = _r.next(i)) @@ -216,62 +223,66 @@ void ReactionLayout::make() // layout molecules in a row with the intervals specified Metalayout::LayoutLine& line = _ml.newLine(); - for (int i = _r.reactantBegin(); i < _r.reactantEnd(); i = _r.reactantNext(i)) - { - bool single_atom = _getMol(i).vertexCount() == 1; - if (i != _r.reactantBegin()) - _pushSpace(line, plus_interval_factor); - _pushMol(line, i); - } + auto processReactionElements = [this, &line](int begin, int end, std::function next) { + for (int i = begin; i < end; i = next(_r, i)) + { + bool single_atom = _getMol(i).vertexCount() == 1; + if (i != begin) + { + _pushSpace(line, reaction_margin_size); + _pushSpace(line, default_plus_size); + } + _pushMol(line, i); + } + }; + + processReactionElements(_r.reactantBegin(), _r.reactantEnd(), &BaseReaction::reactantNext); if (_r.catalystCount()) { + + _pushSpace(line, reaction_margin_size); + _pushSpace(line, reaction_margin_size); for (int i = _r.catalystBegin(); i < _r.catalystEnd(); i = _r.catalystNext(i)) { auto& mol = _getMol(i); Rect2f bbox; - mol.getBoundingBox(bbox, Vec2f(kDoubleBondLength, kDoubleBondLength)); - _pushSpace(line, bbox.width() / 2); + mol.getBoundingBox(bbox, Vec2f(bond_length, bond_length)); + if (i != _r.catalystBegin()) + _pushSpace(line, reaction_margin_size); _pushMol(line, i, true); } - _pushSpace(line, bond_length); + _pushSpace(line, reaction_margin_size); + _pushSpace(line, reaction_margin_size); } else - _pushSpace(line, arrow_interval_factor); + _pushSpace(line, default_arrow_size + reaction_margin_size * 2); - _pushSpace(line, bond_length); - - for (int i = _r.productBegin(); i < _r.productEnd(); i = _r.productNext(i)) - { - bool single_atom = _getMol(i).vertexCount() == 1; - if (i != _r.productBegin()) - _pushSpace(line, plus_interval_factor); - _pushMol(line, i); - } + processReactionElements(_r.productBegin(), _r.productEnd(), &BaseReaction::productNext); _ml.bondLength = bond_length; - _ml.horizontalIntervalFactor = horizontal_interval_factor; + _ml.reactionComponentMarginSize = reaction_margin_size; _ml.cb_getMol = cb_getMol; _ml.cb_process = cb_process; _ml.context = this; _ml.prepare(); - _ml.scaleSz(); + _ml.scaleMoleculesSize(); _ml.calcContentSize(); _ml.process(); _updateMetadata(); } -void ReactionLayout::_pushMol(Metalayout::LayoutLine& line, int id, bool is_agent) +void ReactionLayout::_pushMol(Metalayout::LayoutLine& line, int id, bool is_catalyst) { // Molecule label alligned to atom center by non-hydrogen // Hydrogen may be at left or at right H2O, PH3 - so add space before and after molecule - _pushSpace(line, atom_label_width); + _pushSpace(line, atom_label_margin); Metalayout::LayoutItem& item = line.items.push(); - item.type = 0; - item.fragment = true; + item.type = Metalayout::LayoutItem::Type::EMolecule; + item.isMoleculeFragment = true; item.id = id; auto& mol = _getMol(id); - if (is_agent) + if (is_catalyst) { item.verticalAlign = Metalayout::LayoutItem::ItemVerticalAlign::ETop; } @@ -280,14 +291,14 @@ void ReactionLayout::_pushMol(Metalayout::LayoutLine& line, int id, bool is_agen mol.getBoundingBox(bbox); item.min.copy(bbox.leftBottom()); item.max.copy(bbox.rightTop()); - _pushSpace(line, atom_label_width); + _pushSpace(line, atom_label_margin); } void ReactionLayout::_pushSpace(Metalayout::LayoutLine& line, float size) { Metalayout::LayoutItem& item = line.items.push(); - item.type = 1; - item.fragment = false; + item.type = Metalayout::LayoutItem::Type::ESpace; + item.isMoleculeFragment = false; item.scaledSize.set(size, 0); } @@ -303,12 +314,12 @@ BaseMolecule& ReactionLayout::cb_getMol(int id, void* context) void ReactionLayout::cb_process(Metalayout::LayoutItem& item, const Vec2f& pos, void* context) { - Vec2f pos2; - pos2.copy(pos); - pos2.y -= item.scaledSize.y / 2; - if (item.fragment) + if (item.isMoleculeFragment) { - ReactionLayout* layout = (ReactionLayout*)context; + Vec2f pos2; + pos2.copy(pos); + pos2.y -= item.scaledSize.y / 2; + auto layout = (ReactionLayout*)context; layout->_ml.adjustMol(layout->_getMol(item.id), item.min, pos2); } } diff --git a/core/indigo-core/layout/src/sequence_layout.cpp b/core/indigo-core/layout/src/sequence_layout.cpp index 3975daa12f..4a244ffc4f 100644 --- a/core/indigo-core/layout/src/sequence_layout.cpp +++ b/core/indigo-core/layout/src/sequence_layout.cpp @@ -178,7 +178,7 @@ void SequenceLayout::calculateCoordinates(SequenceLayoutMap& layout_sequence) for (auto& col : row.second) { int x_int = col.first - base_col; - Vec3f v(MoleculeLayout::DEFAULT_BOND_LENGTH * x_int, -MoleculeLayout::DEFAULT_BOND_LENGTH * y_int, 0); + Vec3f v(LayoutOptions::DEFAULT_BOND_LENGTH * x_int, -LayoutOptions::DEFAULT_BOND_LENGTH * y_int, 0); _molecule.setAtomXyz(col.second, v); } } diff --git a/core/indigo-core/molecule/src/molfile_loader.cpp b/core/indigo-core/molecule/src/molfile_loader.cpp index 9206660d5a..424b582672 100644 --- a/core/indigo-core/molecule/src/molfile_loader.cpp +++ b/core/indigo-core/molecule/src/molfile_loader.cpp @@ -2244,10 +2244,10 @@ bool MolfileLoader::_expandNucleotide(int nuc_atom_idx, int tg_idx, std::unorder if (!_bmol->getMiddlePoint(nuc_atom_idx, right_idx, sugar_pos)) { sugar_pos.copy(_bmol->getAtomXyz(nuc_atom_idx)); - sugar_pos.x += MoleculeLayout::DEFAULT_BOND_LENGTH; + sugar_pos.x += LayoutOptions::DEFAULT_BOND_LENGTH; } base_pos.copy(sugar_pos); - base_pos.y -= MoleculeLayout::DEFAULT_BOND_LENGTH; + base_pos.y -= LayoutOptions::DEFAULT_BOND_LENGTH; _bmol->setAtomXyz(sugar_idx, sugar_pos); _bmol->setAtomXyz(base_idx, base_pos); // set seqid diff --git a/core/indigo-core/molecule/src/sequence_loader.cpp b/core/indigo-core/molecule/src/sequence_loader.cpp index e24291123c..1437ab45a5 100644 --- a/core/indigo-core/molecule/src/sequence_loader.cpp +++ b/core/indigo-core/molecule/src/sequence_loader.cpp @@ -257,7 +257,7 @@ bool SequenceLoader::addMonomer(BaseMolecule& mol, char ch, SeqType seq_type) void SequenceLoader::addAminoAcid(BaseMolecule& mol, char ch) { - Vec3f pos(_col * MoleculeLayout::DEFAULT_BOND_LENGTH, -MoleculeLayout::DEFAULT_BOND_LENGTH * _row, 0); + Vec3f pos(_col * LayoutOptions::DEFAULT_BOND_LENGTH, -LayoutOptions::DEFAULT_BOND_LENGTH * _row, 0); std::string aa(1, ch); int amino_idx = mol.asMolecule().addAtom(-1); mol.asMolecule().setTemplateAtom(amino_idx, monomerNameByAlias(kMonomerClassAA, aa).c_str()); @@ -297,7 +297,7 @@ void SequenceLoader::addMonomerConnection(KetDocument& document, std::size_t lef Vec3f SequenceLoader::getBackboneMonomerPosition() { - return Vec3f(_col * MoleculeLayout::DEFAULT_BOND_LENGTH, -MoleculeLayout::DEFAULT_BOND_LENGTH * _row, 0); + return Vec3f(_col * LayoutOptions::DEFAULT_BOND_LENGTH, -LayoutOptions::DEFAULT_BOND_LENGTH * _row, 0); } void SequenceLoader::addNucleotide(BaseMolecule& mol, std::string base, const std::string& sugar_alias, const std::string& phosphate_alias, @@ -314,7 +314,7 @@ void SequenceLoader::addNucleotide(BaseMolecule& mol, std::string base, const st if (base.size() > 0) { int nuc_base_idx = addTemplateAtom(mol, base.c_str(), kMonomerClassBASE, _seq_id); - Vec3f base_coord(pos.x, pos.y - MoleculeLayout::DEFAULT_BOND_LENGTH, 0); + Vec3f base_coord(pos.x, pos.y - LayoutOptions::DEFAULT_BOND_LENGTH, 0); mol.asMolecule().setAtomXyz(nuc_base_idx, base_coord); // connect nucleobase to the sugar @@ -330,7 +330,7 @@ void SequenceLoader::addNucleotide(BaseMolecule& mol, std::string base, const st // add phosphate int phosphate_idx = addTemplateAtom(mol, phosphate_alias.c_str(), kMonomerClassPHOSPHATE, _seq_id - 1); - Vec3f phosphate_coord(pos.x - MoleculeLayout::DEFAULT_BOND_LENGTH, pos.y, 0); + Vec3f phosphate_coord(pos.x - LayoutOptions::DEFAULT_BOND_LENGTH, pos.y, 0); mol.asMolecule().setAtomXyz(phosphate_idx, phosphate_coord); addTemplateBond(mol, _last_monomer_idx, phosphate_idx); // connect phosphate to the previous monomer @@ -342,7 +342,7 @@ void SequenceLoader::addNucleotide(BaseMolecule& mol, std::string base, const st // add phosphate int phosphate_idx = addTemplateAtom(mol, phosphate_alias.c_str(), kMonomerClassPHOSPHATE, _seq_id); - Vec3f phosphate_coord(pos.x + MoleculeLayout::DEFAULT_BOND_LENGTH, pos.y, 0); + Vec3f phosphate_coord(pos.x + LayoutOptions::DEFAULT_BOND_LENGTH, pos.y, 0); mol.asMolecule().setAtomXyz(phosphate_idx, phosphate_coord); if (_last_monomer_idx >= 0) @@ -437,7 +437,7 @@ void SequenceLoader::addMonomer(KetDocument& document, const std::string& monome void SequenceLoader::addAminoAcid(KetDocument& document, const std::string& monomer, bool variant) { - Vec3f pos(_col * MoleculeLayout::DEFAULT_BOND_LENGTH, -MoleculeLayout::DEFAULT_BOND_LENGTH * _row, 0); + Vec3f pos(_col * LayoutOptions::DEFAULT_BOND_LENGTH, -LayoutOptions::DEFAULT_BOND_LENGTH * _row, 0); auto amino_idx = document.monomers().size(); auto& amino_acid = variant ? document.addVariantMonomer(monomer, _var_alias_to_id.at(monomer)) : document.addMonomer(monomer, _alias_to_id.at(monomer)); if (variant) @@ -474,7 +474,7 @@ void SequenceLoader::addNucleotide(KetDocument& document, const std::string& bas else base->setAttachmentPoints(document.templates().at(_alias_to_id.at(base_alias)).attachmentPoints()); base->setIntProp("seqid", _seq_id); - Vec3f base_coord(pos.x, pos.y - MoleculeLayout::DEFAULT_BOND_LENGTH, 0); + Vec3f base_coord(pos.x, pos.y - LayoutOptions::DEFAULT_BOND_LENGTH, 0); base->setPosition(base_coord); // connect nucleobase to the sugar @@ -492,7 +492,7 @@ void SequenceLoader::addNucleotide(KetDocument& document, const std::string& bas auto& phosphate = document.addMonomer(phosphate_alias, _alias_to_id.at(phosphate_alias)); phosphate->setAttachmentPoints(document.templates().at(_alias_to_id.at(phosphate_alias)).attachmentPoints()); phosphate->setIntProp("seqid", _seq_id - 1); - Vec3f phosphate_coord(pos.x - MoleculeLayout::DEFAULT_BOND_LENGTH, pos.y, 0); + Vec3f phosphate_coord(pos.x - LayoutOptions::DEFAULT_BOND_LENGTH, pos.y, 0); phosphate->setPosition(phosphate_coord); addMonomerConnection(document, _last_monomer_idx, phosphate_idx); // connect phosphate to the previous monomer @@ -506,7 +506,7 @@ void SequenceLoader::addNucleotide(KetDocument& document, const std::string& bas auto& phosphate = document.addMonomer(phosphate_alias, _alias_to_id.at(phosphate_alias)); phosphate->setAttachmentPoints(document.templates().at(_alias_to_id.at(phosphate_alias)).attachmentPoints()); phosphate->setIntProp("seqid", _seq_id); - Vec3f phosphate_coord(pos.x + MoleculeLayout::DEFAULT_BOND_LENGTH, pos.y, 0); + Vec3f phosphate_coord(pos.x + LayoutOptions::DEFAULT_BOND_LENGTH, pos.y, 0); phosphate->setPosition(phosphate_coord); if (_last_monomer_idx >= 0) @@ -1687,7 +1687,7 @@ void SequenceLoader::loadHELM(KetDocument& document) else if (ch != '}') { monomer_idx++; - Vec3f pos(_col * MoleculeLayout::DEFAULT_BOND_LENGTH, -MoleculeLayout::DEFAULT_BOND_LENGTH * _row, 0); + Vec3f pos(_col * LayoutOptions::DEFAULT_BOND_LENGTH, -LayoutOptions::DEFAULT_BOND_LENGTH * _row, 0); _col++; if (simple_polymer_type == kHELMPolymerTypeUnknown) { @@ -1747,7 +1747,7 @@ void SequenceLoader::loadHELM(KetDocument& document) monomer_idx++; auto base_info = readHelmMonomer(document, MonomerClass::Base); ch = _scanner.lookNext(); - Vec3f base_pos(pos.x, pos.y - MoleculeLayout::DEFAULT_BOND_LENGTH, 0); + Vec3f base_pos(pos.x, pos.y - LayoutOptions::DEFAULT_BOND_LENGTH, 0); auto base_idx = addKetMonomer(document, base_info, MonomerClass::Base, base_pos); cur_polymer_map->second[monomer_idx] = base_idx; if (monomer_idx > 1) @@ -1761,7 +1761,7 @@ void SequenceLoader::loadHELM(KetDocument& document) continue; auto phosphate_info = readHelmMonomer(document, MonomerClass::Phosphate); monomer_idx++; - Vec3f phosphate_pos(_col * MoleculeLayout::DEFAULT_BOND_LENGTH, -MoleculeLayout::DEFAULT_BOND_LENGTH * _row, 0); + Vec3f phosphate_pos(_col * LayoutOptions::DEFAULT_BOND_LENGTH, -LayoutOptions::DEFAULT_BOND_LENGTH * _row, 0); _col++; auto phosphate_idx = addKetMonomer(document, phosphate_info, MonomerClass::Phosphate, phosphate_pos); cur_polymer_map->second[monomer_idx] = phosphate_idx; diff --git a/core/indigo-core/reaction/reaction_json_saver.h b/core/indigo-core/reaction/reaction_json_saver.h index 413c1b84fa..feadd9aa97 100644 --- a/core/indigo-core/reaction/reaction_json_saver.h +++ b/core/indigo-core/reaction/reaction_json_saver.h @@ -23,6 +23,7 @@ #include #include "base_cpp/exception.h" +#include "layout/metalayout.h" #include "molecule/ket_commons.h" namespace indigo @@ -44,6 +45,7 @@ namespace indigo bool add_stereo_desc; bool pretty_json; bool use_native_precision; + indigo::LayoutOptions layout_options; DECL_ERROR; protected: diff --git a/core/indigo-core/reaction/src/reaction_json_saver.cpp b/core/indigo-core/reaction/src/reaction_json_saver.cpp index 9a825562e9..f227741952 100644 --- a/core/indigo-core/reaction/src/reaction_json_saver.cpp +++ b/core/indigo-core/reaction/src/reaction_json_saver.cpp @@ -70,7 +70,7 @@ void ReactionJsonSaver::saveReaction(BaseReaction& rxn) std::unique_ptr reaction(rxn.neu()); reaction->clone(rxn); - ReactionLayout rl(*reaction); + ReactionLayout rl(*reaction, false, layout_options); rl.fixLayout(); // merge diff --git a/core/render2d/render_common.h b/core/render2d/render_common.h index f1a59e4b30..1263168186 100644 --- a/core/render2d/render_common.h +++ b/core/render2d/render_common.h @@ -519,6 +519,7 @@ namespace indigo int xOffset; int yOffset; float bondLength; + UnitsOfMeasure::TYPE bondLengthUnit; int gridMarginX; int gridMarginY; int marginX; @@ -578,6 +579,9 @@ namespace indigo bool agentsBelowArrow; Array atomColorProp; std::unique_ptr cdxml_context; + float reactionComponentMarginSize; + UnitsOfMeasure::TYPE reactionComponentMarginSizeUnit; + int32_t ppi; private: RenderOptions(const RenderOptions&); diff --git a/data/molecules/basic/after_layout_default_margin.ket b/data/molecules/basic/after_layout_default_margin.ket new file mode 100644 index 0000000000..574b2dd3dd --- /dev/null +++ b/data/molecules/basic/after_layout_default_margin.ket @@ -0,0 +1,406 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + }, + { + "$ref": "mol3" + }, + { + "$ref": "mol4" + }, + { + "type": "plus", + "location": [ + 5.271281, + 0.0, + 0.0 + ] + }, + { + "type": "plus", + "location": [ + 29.75157, + 0.0, + 0.0 + ] + }, + { + "type": "arrow", + "data": { + "mode": "open-angle", + "pos": [ + { + "x": 12.728203, + "y": 0.0, + "z": 0.0 + }, + { + "x": 19.523369, + "y": 0.0, + "z": 0.0 + } + ] + } + } + ] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 2.185641, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 2.185641, + 0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 0.8, + 1.2, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 3.571281, + 1.2, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 3 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 6.971282, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 8.356922, + 0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 9.742562, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 11.128202, + 0.4, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 21.123369, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 22.50901, + -0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 23.89465, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 25.280291, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 26.665932, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 28.051571, + -0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 22.50901, + 1.2, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 6 + ] + } + ] + }, + "mol3": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 31.451569, + 0.0, + 0.0 + ] + } + ], + "bonds": [] + }, + "mol4": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + 16.925787, + 5.10503, + 0.0 + ] + }, + { + "label": "N", + "location": [ + 15.325788, + 5.10503, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 14.328203, + 3.8541, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 14.684236, + 2.294215, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 17.923372, + 3.854097, + 0.0 + ] + }, + { + "label": "N", + "location": [ + 16.125786, + 1.6, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 17.567337, + 2.294213, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 1, + 0 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 6 + ] + }, + { + "type": 1, + "atoms": [ + 6, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 1 + ] + } + ] + } +} \ No newline at end of file diff --git a/data/molecules/basic/after_layout_zero_margin.ket b/data/molecules/basic/after_layout_zero_margin.ket new file mode 100644 index 0000000000..33b2f3ea27 --- /dev/null +++ b/data/molecules/basic/after_layout_zero_margin.ket @@ -0,0 +1,406 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + }, + { + "$ref": "mol3" + }, + { + "$ref": "mol4" + }, + { + "type": "plus", + "location": [ + 4.871281, + 0.0, + 0.0 + ] + }, + { + "type": "plus", + "location": [ + 25.351574, + 0.0, + 0.0 + ] + }, + { + "type": "arrow", + "data": { + "mode": "open-angle", + "pos": [ + { + "x": 11.128203, + "y": 0.0, + "z": 0.0 + }, + { + "x": 16.323372, + "y": 0.0, + "z": 0.0 + } + ] + } + } + ] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 2.185641, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 2.185641, + 0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 0.8, + 1.2, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 3.571281, + 1.2, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 3 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 6.171281, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 7.556922, + 0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 8.942562, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 10.328203, + 0.4, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 17.123371, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 18.509012, + -0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 19.894651, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 21.280293, + -0.4, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 22.665934, + -1.2, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 24.051575, + -0.4, + 0.0 + ] + }, + { + "label": "O", + "location": [ + 18.509012, + 1.2, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 6 + ] + } + ] + }, + "mol3": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 26.651573, + 0.0, + 0.0 + ] + } + ], + "bonds": [] + }, + "mol4": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + 14.525787, + 4.30503, + 0.0 + ] + }, + { + "label": "N", + "location": [ + 12.925788, + 4.30503, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 11.928204, + 3.0541, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 12.284236, + 1.494215, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 15.523372, + 3.054097, + 0.0 + ] + }, + { + "label": "N", + "location": [ + 13.725786, + 0.8, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 15.167336, + 1.494213, + 0.0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 1, + 0 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 6 + ] + }, + { + "type": 1, + "atoms": [ + 6, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 1 + ] + } + ] + } +} \ No newline at end of file diff --git a/data/molecules/basic/before_layout.ket b/data/molecules/basic/before_layout.ket new file mode 100644 index 0000000000..97bbf9023f --- /dev/null +++ b/data/molecules/basic/before_layout.ket @@ -0,0 +1,409 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + }, + { + "$ref": "mol3" + }, + { + "$ref": "mol4" + }, + { + "type": "arrow", + "data": { + "mode": "open-angle", + "pos": [ + { + "x": -7.394363028677862, + "y": -6.362093778161939, + "z": 0 + }, + { + "x": -5.694363028677859, + "y": -7.18709377816194, + "z": 0 + } + ] + } + }, + { + "type": "plus", + "location": [ + -12.377241893411822, + -7.324774847536024, + 0 + ], + "prop": {} + }, + { + "type": "plus", + "location": [ + 1.775960072742631, + -6.424774847536024, + 0 + ], + "prop": {} + } + ], + "connections": [], + "templates": [] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + -13.768267539670937, + -6.949774873495124, + 0 + ] + }, + { + "label": "C", + "location": [ + -13.768267390659325, + -5.949774863718258, + 0 + ] + }, + { + "label": "O", + "location": [ + -14.63429292347398, + -5.4497749705885346, + 0 + ] + }, + { + "label": "O", + "location": [ + -12.90224200685628, + -5.449774821576923, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 3 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + -11.002241779967369, + -5.599774887233143, + 0 + ] + }, + { + "label": "C", + "location": [ + -10.136216694187546, + -5.099774807838904, + 0 + ] + }, + { + "label": "C", + "location": [ + -9.270191012361279, + -5.599774812727337, + 0 + ] + }, + { + "label": "C", + "location": [ + -8.404165926581456, + -5.099774807838904, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + -3.904166661693825, + -7.524774873495127, + 0 + ] + }, + { + "label": "C", + "location": [ + -3.03814097986756, + -7.024774794100886, + 0 + ] + }, + { + "label": "O", + "location": [ + -2.1721152980412946, + -7.524774798989321, + 0 + ] + }, + { + "label": "C", + "location": [ + -1.3060908083079177, + -7.024774794100886, + 0 + ] + }, + { + "label": "C", + "location": [ + -0.4400651264816453, + -7.524774798989321, + 0 + ] + }, + { + "label": "C", + "location": [ + 0.4259605553446235, + -7.024774794100886, + 0 + ] + }, + { + "label": "O", + "location": [ + -3.03814097986756, + -6.024774821576924, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 6 + ] + } + ] + }, + "mol3": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 3.300959590140639, + -7.574774847536024, + 0 + ] + } + ] + }, + "mol4": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + -6.339747371437873, + -4.792796796383729, + 0 + ] + }, + { + "label": "N", + "location": [ + -5.555813985618887, + -4.175225152463979, + 0 + ] + }, + { + "label": "C", + "location": [ + -4.582783087033036, + -4.397775297256338, + 0 + ] + }, + { + "label": "C", + "location": [ + -4.148700131348928, + -5.293584700956992, + 0 + ] + }, + { + "label": "C", + "location": [ + -6.334238704487571, + -5.799981430061476, + 0 + ] + }, + { + "label": "N", + "location": [ + -4.582081983966631, + -6.200611753720088, + 0 + ] + }, + { + "label": "C", + "location": [ + -5.555813985618887, + -6.423161898512448, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 1, + 0 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 4, + 6 + ] + }, + { + "type": 1, + "atoms": [ + 6, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 1 + ] + } + ] + } +} \ No newline at end of file diff --git a/utils/indigo-service/backend/service/tests/api/indigo_test.py b/utils/indigo-service/backend/service/tests/api/indigo_test.py index 193276cdff..897a5c445d 100644 --- a/utils/indigo-service/backend/service/tests/api/indigo_test.py +++ b/utils/indigo-service/backend/service/tests/api/indigo_test.py @@ -1093,12 +1093,12 @@ def test_layout_selective_reaction(self): -INDIGO-01000000002D 6 6 0 0 0 0 0 0 0 0999 V2000 - 2.6856 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 1.3000 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 1.3000 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 2.6856 -1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 4.0713 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 4.0713 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.1856 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.8000 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.8000 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.1856 -1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.5713 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.5713 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 2 0 0 0 0 3 4 1 0 0 0 0 @@ -1111,18 +1111,18 @@ def test_layout_selective_reaction(self): -INDIGO-01000000002D 12 13 0 0 0 0 0 0 0 0999 V2000 - 7.6713 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 8.4713 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 10.0713 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 10.8713 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 10.0713 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 8.4713 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 12.4713 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 13.2713 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 14.8713 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 15.6713 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 14.8713 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 13.2713 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.9713 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.7713 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.3713 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.1713 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.3713 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.7713 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.7713 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5713 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1713 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.9713 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1713 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5713 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 2 0 0 0 0 3 4 1 0 0 0 0 @@ -1142,12 +1142,12 @@ def test_layout_selective_reaction(self): -INDIGO-01000000002D 6 6 0 0 0 0 0 0 0 0999 V2000 - 23.2569 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 21.8713 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 21.8713 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 23.2569 -1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 24.6426 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 - 24.6426 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.7569 1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.3713 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.3713 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.7569 -1.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.1426 -0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.1426 0.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 2 3 2 0 0 0 0 3 4 1 0 0 0 0