Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Issue #520 Replace RedBlackMap in MoleculeStereocenters #857

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions api/c/indigo/src/indigo_stereo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "indigo_reaction.h"
#include "molecule/molecule_automorphism_search.h"
#include "molecule/molecule_exact_matcher.h"
#include "molecule/molecule_stereocenter_iterator.h"
#include "reaction/reaction.h"

CEXPORT int indigoStereocenterType(int atom)
Expand Down Expand Up @@ -373,7 +374,7 @@ static int _resetSymmetric(Molecule& mol, bool cistrans, bool stereo)
{
QS_DEF(Array<int>, to_remove);
to_remove.clear();
for (int i = mol.stereocenters.begin(); i != mol.stereocenters.end(); i = mol.stereocenters.next(i))
for (auto i = mol.stereocenters.begin(); i != mol.stereocenters.end(); i = mol.stereocenters.next(i))
{
int atom_index = mol.stereocenters.getAtomIndex(i);
if (am.invalidStereocenter(atom_index))
Expand Down Expand Up @@ -530,7 +531,7 @@ static void _indigoValidateMoleculeChirality(Molecule& mol)
QS_DEF(Molecule, mirror);
mirror.clone(mol, 0, 0);

for (int s = mirror.stereocenters.begin(); s != mirror.stereocenters.end(); s = mirror.stereocenters.next(s))
for (auto s = mirror.stereocenters.begin(); s != mirror.stereocenters.end(); s = mirror.stereocenters.next(s))
{
int atom = mirror.stereocenters.getAtomIndex(s);
if (mirror.stereocenters.getType(atom) == MoleculeStereocenters::ATOM_ABS)
Expand All @@ -544,7 +545,7 @@ static void _indigoValidateMoleculeChirality(Molecule& mol)
if (!matcher.find())
return;

for (int s = mol.stereocenters.begin(); s != mol.stereocenters.end(); s = mol.stereocenters.next(s))
for (auto s = mol.stereocenters.begin(); s != mol.stereocenters.end(); s = mol.stereocenters.next(s))
{
int atom = mol.stereocenters.getAtomIndex(s);
if (mol.stereocenters.getType(atom) == MoleculeStereocenters::ATOM_ABS)
Expand Down
11 changes: 8 additions & 3 deletions core/indigo-core/molecule/molecule_automorphism_search.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@
#ifndef __molecule_automorphism_search__
#define __molecule_automorphism_search__

#include <memory>

#include "graph/automorphism_search.h"
#include "molecule/molecule_stereocenter_iterator.h"

namespace indigo
{

class Molecule;
class MoleculeStereocenters;
class StereocenterIteratorr;
class CancellationHandler;

class MoleculeAutomorphismSearch : public AutomorphismSearch
Expand Down Expand Up @@ -65,7 +69,7 @@ namespace indigo
static bool _check_automorphism(Graph& graph, const Array<int>& mapping, const void* context);

static bool _isCisTransBondMappedRigid(Molecule& mol, int i, const int* mapping);
static bool _isStereocenterMappedRigid(Molecule& mol, int i, const int* mapping);
static bool _isStereocenterMappedRigid(Molecule& mol, const StereocenterIterator& it, const int* mapping);

static int _compare_mapped(Graph& graph, const Array<int>& mapping1, const Array<int>& mapping2, const void* context);

Expand All @@ -84,7 +88,7 @@ namespace indigo
void _getFirstApproximation(Molecule& mol);

int _validCisTransBond(int idx, const Array<int>& orbits);
int _validStereocenter(int idx, Array<int>& orbits, int* parity = 0);
int _validStereocenter(const StereocenterIterator& it, Array<int>& orbits, int* parity = 0);
int _validStereocenterByAtom(int atom_idx, Array<int>& orbits, int* parity = 0);

int _treat_undef_as;
Expand Down Expand Up @@ -130,7 +134,8 @@ namespace indigo
TL_CP_DECL(Array<int>, _cistrans_bond_state);

// Target stereocenters and cis-trans bond for checking permutation parity
int _target_stereocenter, _target_bond;
std::unique_ptr<StereocenterIterator> _target_stereocenter; // should be replaced with std::optional after switch to C++17
int _target_bond;
bool _target_stereocenter_parity_inv, _target_bond_parity_inv;
int _fixed_atom;

Expand Down
5 changes: 3 additions & 2 deletions core/indigo-core/molecule/molecule_cip_calculator.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace indigo
{
class BaseMolecule;
class Molecule;
class StereocenterIterator;

enum class CIPDesc : int
{
Expand Down Expand Up @@ -81,8 +82,8 @@ namespace indigo
{"(s)", CIPDesc::s}, {"(E)", CIPDesc::E}, {"(Z)", CIPDesc::Z}};

private:
void _calcRSStereoDescriptor(BaseMolecule& mol, BaseMolecule& unfolded_h_mol, int idx, Array<CIPDesc>& atom_cip_desc, Array<int>& stereo_passed,
bool use_stereo, Array<EquivLigand>& equiv_ligands, bool& digraph_cip_used);
void _calcRSStereoDescriptor(BaseMolecule& mol, BaseMolecule& unfolded_h_mol, const StereocenterIterator& id, Array<CIPDesc>& atom_cip_desc,
Array<StereocenterIterator>& stereo_passed, bool use_stereo, Array<EquivLigand>& equiv_ligands, bool& digraph_cip_used);
void _calcEZStereoDescriptor(BaseMolecule& mol, BaseMolecule& unfolded_h_mol, int idx, Array<CIPDesc>& bond_cip_desc);
bool _checkLigandsEquivalence(Array<int>& ligands, Array<EquivLigand>& equiv_ligands, CIPContext& context);
static int _getNumberOfStereoDescritors(const Array<CIPDesc>& atom_cip_desc);
Expand Down
19 changes: 12 additions & 7 deletions core/indigo-core/molecule/molecule_ionize.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
#ifndef __molecule_ionize_h__
#define __molecule_ionize_h__

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base_cpp/obj_array.h"
#include "base_cpp/red_black.h"
#include "base_cpp/tlscont.h"
Expand Down Expand Up @@ -82,16 +87,16 @@ namespace indigo
static void _checkCanonicalOrder(Molecule& mol, Molecule& can_mol, Array<int>& order);
static void _removeExtraHydrogens(Molecule& mol);

ObjArray<QueryMolecule> acids;
ObjArray<QueryMolecule> basics;
Array<float> a_pkas;
Array<float> b_pkas;
std::vector<std::unique_ptr<QueryMolecule>> acids; // consider replacement to std::vector<QueryMolecule> after QueryMolecule will become movable
std::vector<std::unique_ptr<QueryMolecule>> basics;
std::vector<float> a_pkas;
std::vector<float> b_pkas;
bool simple_model_ready = false;

RedBlackStringObjMap<Array<float>> adv_a_pkas;
RedBlackStringObjMap<Array<float>> adv_b_pkas;
std::map<std::string, std::vector<float>, std::less<>> adv_a_pkas;
std::map<std::string, std::vector<float>, std::less<>> adv_b_pkas;
int level;
Array<float> max_deviations;
std::vector<float> max_deviations;
bool advanced_model_ready = false;
};

Expand Down
53 changes: 53 additions & 0 deletions core/indigo-core/molecule/molecule_stereocenter_iterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/****************************************************************************
* 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.
***************************************************************************/

#ifndef __molecule_stereocenter_iterator__
#define __molecule_stereocenter_iterator__

#include "base_c/defs.h"
#include "molecule/molecule_stereocenters.h"

#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable : 4251)
#endif

namespace indigo
{

class DLLEXPORT StereocenterIterator
{
StereocenterIterator(MoleculeStereocenters::Container::const_iterator it);

MoleculeStereocenters::Container::const_iterator _iterator;

friend class MoleculeStereocenters;

public:
bool operator==(const StereocenterIterator& rhs) const;

bool operator!=(const StereocenterIterator& rhs) const;
};

} // namespace indigo

#ifdef _WIN32
#pragma warning(pop)
#endif

#endif // __molecule_stereocenter_iterator__
47 changes: 28 additions & 19 deletions core/indigo-core/molecule/molecule_stereocenters.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#ifndef __molecule_stereocenters__
#define __molecule_stereocenters__

#include "base_cpp/red_black.h"
#include <map>

#include "base_cpp/array.h"
#include "math/algebra.h"

#ifdef _WIN32
Expand All @@ -31,10 +33,21 @@ namespace indigo
{
class Filter;
class StereocentersOptions;
class StereocenterIterator;
class BaseMolecule;

class DLLEXPORT MoleculeStereocenters
{
struct _Atom
{
int type; // ANY, AND, OR, ABS
int group; // stereogroup index
// [X, Y, Z, W] -- atom indices or -1 for implicit hydrogen
// (X, Y, Z) go counterclockwise when looking from W.
// if there are pure (implicit) hydrogen, it is W
int pyramid[4];
};

public:
enum
{
Expand All @@ -45,6 +58,11 @@ namespace indigo
};

explicit MoleculeStereocenters();
MoleculeStereocenters(const MoleculeStereocenters&) = delete; // no implicit copy
MoleculeStereocenters(MoleculeStereocenters&&) = default;

MoleculeStereocenters& operator=(const MoleculeStereocenters&) = delete; // no implicit copy
MoleculeStereocenters& operator=(MoleculeStereocenters&&) = default;

void clear();

Expand All @@ -69,7 +87,6 @@ namespace indigo
void add_ignore(BaseMolecule& baseMolecule, int atom_idx, int type, int group, bool inverse_pyramid);
void add_ignore(BaseMolecule& baseMolecule, int atom_idx, int type, int group, const int pyramid[4]);

void get(int i, int& atom_idx, int& type, int& group, int* pyramid) const;
void remove(int idx);

bool exists(int atom_idx) const;
Expand Down Expand Up @@ -102,11 +119,12 @@ namespace indigo

void flipBond(int atom_parent, int atom_from, int atom_to);

int begin() const;
int end() const;
int next(int i) const;
StereocenterIterator begin() const;
StereocenterIterator end() const;
StereocenterIterator next(const StereocenterIterator& it) const;

int getAtomIndex(int i) const;
void get(const StereocenterIterator& it, int& atom_idx, int& type, int& group, int* pyramid) const;
int getAtomIndex(const StereocenterIterator& it) const;

bool isPossibleStereocenter(BaseMolecule& baseMolecule, int atom_idx, bool* possible_implicit_h = 0, bool* possible_lone_pair = 0);

Expand All @@ -121,7 +139,7 @@ namespace indigo
static void moveMinimalToEnd(int pyramid[4]);
static void moveElementToEnd(int pyramid[4], int element);

static bool isAutomorphism(BaseMolecule& mol, const Array<int>& mapping, const Filter* filter = NULL);
static bool isAutomorphism(BaseMolecule& mol, const Array<int>& mapping);

DECL_ERROR;

Expand All @@ -130,16 +148,6 @@ namespace indigo
static void rotatePyramid(int* pyramid);

private:
struct _Atom
{
int type; // ANY, AND, OR, ABS
int group; // stereogroup index
// [X, Y, Z, W] -- atom indices or -1 for implicit hydrogen
// (X, Y, Z) go counterclockwise when looking from W.
// if there are pure (implicit) hydrogen, it is W
int pyramid[4];
};

struct _EdgeIndVec
{
int edge_idx;
Expand All @@ -157,7 +165,8 @@ namespace indigo
int implicit_degree;
};

RedBlackMap<int, _Atom> _stereocenters;
using Container = std::map<int, _Atom>;
Container _stereocenters;

static int _sign(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3);
static int _xyzzy(const Vec3f& v1, const Vec3f& v2, const Vec3f& u);
Expand All @@ -178,7 +187,7 @@ namespace indigo

int _getDirection(BaseMolecule& mol, int atom_from, int atom_to, bool bidirectional_mode);

MoleculeStereocenters(const MoleculeStereocenters&); // no implicit copy
friend class StereocenterIterator;
};

} // namespace indigo
Expand Down
3 changes: 2 additions & 1 deletion core/indigo-core/molecule/src/inchi_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "molecule/elements.h"
#include "molecule/molecule.h"
#include "molecule/molecule_dearom.h"
#include "molecule/molecule_stereocenter_iterator.h"
// #include "mode.h"

using namespace indigo;
Expand Down Expand Up @@ -521,7 +522,7 @@ void InchiWrapper::generateInchiInput(Molecule& mol, inchi_Input& input, Array<i
}

// Process tetrahedral stereocenters
for (int i = mol.stereocenters.begin(); i != mol.stereocenters.end(); i = mol.stereocenters.next(i))
for (auto i = mol.stereocenters.begin(); i != mol.stereocenters.end(); i = mol.stereocenters.next(i))
{
int v = mol.stereocenters.getAtomIndex(i);

Expand Down
Loading