Skip to content

Commit

Permalink
2176: add ACS style reaction layout
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksandrParamonoff committed Aug 28, 2024
1 parent 9ff19ad commit 2ea71b2
Show file tree
Hide file tree
Showing 85 changed files with 12,171 additions and 11,168 deletions.
19 changes: 8 additions & 11 deletions api/c/indigo-renderer/src/indigo_render2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -720,7 +720,6 @@ void IndigoRenderer::setOptionsHandlers()
mgr->setOptionHandlerBool("render-highlighted-labels-visible", SETTER_GETTER_BOOL_OPTION(rp.rOpt.highlightedLabelsVisible));
mgr->setOptionHandlerBool("render-bold-bond-detection", SETTER_GETTER_BOOL_OPTION(rp.rOpt.boldBondDetection));

mgr->setOptionHandlerFloat("render-bond-length", SETTER_GETTER_FLOAT_OPTION(rp.cnvOpt.bondLength));
mgr->setOptionHandlerFloat("render-relative-thickness", SET_POSITIVE_FLOAT_OPTION(rp.relativeThickness, "relative thickness must be positive"));
mgr->setOptionHandlerFloat("render-bond-line-width", SET_POSITIVE_FLOAT_OPTION(rp.bondLineWidthFactor, "bond line width factor must be positive"));
mgr->setOptionHandlerFloat("render-comment-font-size", SETTER_GETTER_FLOAT_OPTION(rp.rOpt.commentFontFactor));
Expand Down Expand Up @@ -757,7 +756,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;
}
}
2 changes: 1 addition & 1 deletion api/c/indigo-renderer/src/indigo_renderer_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class IndigoRenderer : public IndigoPluginContext
private:
void setOptionsHandlers();

bool options_set = false;
std::atomic<bool> options_set = false;
};

class IndigoHDCOutput : public IndigoObject
Expand Down
4 changes: 3 additions & 1 deletion api/c/indigo/src/indigo_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -366,6 +366,8 @@ class DLLEXPORT Indigo

bool scsr_ignore_chem_templates;

indigo::LayoutOptions layout_options;

static const Array<char>& getErrorMessage();
static void clearErrorMessage();
static void setErrorMessage(const char* message);
Expand Down
4 changes: 1 addition & 3 deletions api/c/indigo/src/indigo_layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,9 @@ CEXPORT int indigoLayout(int object)
bool no_layout = rxn.intermediateCount() || rxn.specialConditionsCount() || rxn.meta().getNonChemicalMetaCount();
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;
if (self.layout_preserve_existing)
rl.preserve_molecule_layout = true;
rl.make();
Expand Down
97 changes: 97 additions & 0 deletions api/c/indigo/src/indigo_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,94 @@ void indigoProductEnumeratorGetOneTubeMode(Array<char>& 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, "inches"))
{
result = UnitsOfMeasure::TYPE::INCHES;
}
else if (isEqual(mode, "cm"))
{
result = UnitsOfMeasure::TYPE::CM;
}
else
{
throw IndigoError("Invalid label mode, should be 'none', 'hetero', 'terminal-hetero' 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<char>& result) {
switch (input)
{
case UnitsOfMeasure::TYPE::PT:
result.readString("pt", true);
break;
case UnitsOfMeasure::TYPE::PX:
result.readString("px", true);
break;
case UnitsOfMeasure::TYPE::INCHES:
result.readString("inches", true);
break;
case UnitsOfMeasure::TYPE::CM:
result.readString("cm", true);
break;
}
};

return [](Array<char>& res) -> void { return func(res); };
}

void indigoRenderSetImageResolution(const char* mode)
{
Indigo& self = indigoGetInstance();
auto& result = self.layout_options.ppi;
std::string mode_string(mode);
if (isEqual(mode, "high"))
{
result = 600.0;
}
else if (isEqual(mode, "low"))
{
result = 72.0;
}
else
{
throw IndigoError("Invalid label mode, should be 'none', 'hetero', 'terminal-hetero' or 'all'");
}
}

void indigoRenderGetImageResolution(Array<char>& result)
{
const Indigo& self = indigoGetInstance();
if (self.layout_options.ppi == 600.0)
{
result.readString("high", true);
}
else if (self.layout_options.ppi == 72.0)
{
result.readString("low", true);
}
}

void IndigoOptionHandlerSetter::setBasicOptionHandlers(const qword id)
{
auto mgr = sf::xlock_safe_ptr(indigoGetOptionManager(id));
Expand Down Expand Up @@ -384,4 +472,13 @@ 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("render-bond-length", SETTER_GETTER_FLOAT_OPTION(indigo.layout_options.bondLength));
mgr->setOptionHandlerString("render-bond-length-units", indigoSetUnitsOfMeasure(indigo.layout_options.bondLengthUnit),
indigoGetUnitsOfMeasure(indigo.layout_options.bondLengthUnit));
mgr->setOptionHandlerFloat("render-reaction-component-margin-size",
SET_POSITIVE_FLOAT_OPTION(indigo.layout_options.reactionComponentMarginSize, "reaction component margin size must be positive"));
mgr->setOptionHandlerString("render-reaction-component-margin-units", indigoSetUnitsOfMeasure(indigo.layout_options.reactionComponentMarginSizeUnit),
indigoGetUnitsOfMeasure(indigo.layout_options.reactionComponentMarginSizeUnit));
mgr->setOptionHandlerString("render-image-resolution", indigoRenderSetImageResolution, indigoRenderGetImageResolution);
}
8 changes: 8 additions & 0 deletions api/c/indigo/src/option_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ 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; }

class DLLEXPORT IndigoOptionManager
{
public:
Expand Down
84 changes: 84 additions & 0 deletions api/c/tests/unit/tests/layout.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/****************************************************************************
* 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 <thread>

#include <gtest/gtest.h>

#include <base_cpp/exception.h>

#include <algorithm>
#include <fstream>
#include <indigo-renderer.h>
#include <indigo.h>

#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();
}
};

TEST_F(IndigoApiLayoutTest, one_reactant_one_product)
{
indigoSetErrorHandler(errorHandler, nullptr);

indigoSetOption("render-coloring", "true");
indigoSetOption("render-stereo-style", "none");
indigoSetOptionXY("render-image-size", 400, 400);
indigoSetOption("render-output-format", "png");

indigoSetOptionBool("json-saving-pretty", true);
try
{
auto rc = indigoLoadReactionFromFile(dataPath("molecules/basic/before_layout.ket").c_str());

indigoLayout(rc);

const char* res = indigoJson(rc);
// printf("res=%s", res);
std::ifstream is(dataPath("molecules/basic/after_layout.ket"), std::ios::binary | std::ios::ate);
auto size = is.tellg();
std::string str(size, '\0'); // construct string to stream size
is.seekg(0);
is.read(&str[0], size);
str.erase(std::remove(str.begin(), str.end(), '\r'), str.end());

ASSERT_STREQ(res, str.c_str());
// indigoSaveJsonToFile(rc, "res_after_layout.ket");

indigoFree(rc);
}
catch (Exception& e)
{
ASSERT_STREQ("", e.message());
}
}
42 changes: 21 additions & 21 deletions api/tests/integration/ref/arom/basic.py.out
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,14 @@ NC1=NC=NC2NC=NC=21
-INDIGO-01000000002D

8 8 0 0 0 0 0 0 0 0999 V2000
0.8000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.5000 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.6000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-2.4000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.8000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.4000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.2000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.4000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1.5000 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 4 0 0 0 0
2 3 1 0 0 0 0
3 4 2 0 0 0 0
Expand All @@ -424,14 +424,14 @@ M END
-INDIGO-01000000002D

8 8 0 0 0 0 0 0 0 0999 V2000
0.8000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.5000 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.6000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-2.4000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.8000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.4000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.2000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.4000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1.5000 0.8660 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
Expand All @@ -446,14 +446,14 @@ M END
-INDIGO-01000000002D

8 8 0 0 0 0 0 0 0 0999 V2000
0.8000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.5000 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.6000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-2.4000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.8000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.4000 -1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.2000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.4000 1.3856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1.5000 -0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
2.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1.5000 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 4 0 0 0 0
2 3 1 0 0 0 0
3 4 2 0 0 0 0
Expand Down
Loading

0 comments on commit 2ea71b2

Please sign in to comment.