core/indigo-core/molecule/molecule_layered_molecules.h (155 lines of code) (raw):

/**************************************************************************** * 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_layered_molecules_h__ #define __molecule_layered_molecules_h__ #include "common/base_cpp/d_bitset.h" #include "molecule/base_molecule.h" #include "molecule/molecule.h" #ifdef _WIN32 #pragma warning(push) #pragma warning(disable : 4251) #endif namespace indigo { class DLLEXPORT LayeredMolecules : public BaseMolecule { public: enum { BOND_TYPES_NUMBER = 5, MAX_CYCLE_LENGTH = 22 }; LayeredMolecules(BaseMolecule& molecule); ~LayeredMolecules() override; // This method returns a bitmask of all layers that contain a bond idx of a specific order: const Dbitset& getBondMask(int idx, int order) const; // These methods are used for tracking if the atom is a possible position for a mobile hydrogen: bool isMobilePosition(int idx) const; void setMobilePosition(int idx, bool value); // These methods are used for tracking if the mobile position is occupied already. // The bitmask is the layers where the position is occupied. const Dbitset& getMobilePositionOccupiedMask(int idx) const; void setMobilePositionOccupiedMask(int idx, Dbitset& mask, bool value); // mask: the mask of layers used as prototypes; // edgesPath: the path of single-double bonds to be inverted // beg, end: the mobile positions of hydrogen to swap // forward: the direction to move the hydrogen // returns true if at least one new layer was added, false otherwise bool addLayersWithInvertedPath(const Dbitset& mask, const Array<int>& path, int beg, int end, bool forward); bool addLayerFromMolecule(const Molecule& molecule, Array<int>& aam); bool aromatize(int layerFrom, int layerTo, const AromaticityOptions& options); // construct a molecule that is represented as a layer void constructMolecule(Molecule& molecule, int layer, bool aromatized) const; unsigned getHash(int layer, bool aromatized) { if (aromatized) return _hashsAromatized[layer]; return _hashs[layer]; } void clear() override; BaseMolecule* neu() override; int getAtomNumber(int idx) override; int getAtomCharge(int idx) override; int getAtomIsotope(int idx) override; int getAtomRadical(int idx) override; int getAtomAromaticity(int idx) override; int getExplicitValence(int idx) override; int getAtomValence(int idx) override; int getAtomSubstCount(int idx) override; int getAtomRingBondsCount(int idx) override; int getAtomConnectivity(int idx) override; int getAtomMaxH(int idx) override; int getAtomMinH(int idx) override; int getAtomTotalH(int idx) override; bool isPseudoAtom(int idx) override; const char* getPseudoAtom(int idx) override; int addTemplateAtom(const char* text) override; bool isTemplateAtom(int idx) override; int getTemplateAtomOccurrence(int idx) override; bool isRSite(int atom_idx) override; dword getRSiteBits(int atom_idx) override; void allowRGroupOnRSite(int atom_idx, int rg_idx) override; int getBondOrder(int idx) const override; int getBondTopology(int idx) override; bool atomNumberBelongs(int idx, const int* numbers, int count) override; bool possibleAtomNumber(int idx, int number) override; bool possibleAtomNumberAndCharge(int idx, int number, int charge) override; bool possibleAtomNumberAndIsotope(int idx, int number, int isotope) override; bool possibleAtomIsotope(int idx, int isotope) override; bool possibleAtomCharge(int idx, int charge) override; void getAtomDescription(int idx, Array<char>& description) override; void getBondDescription(int idx, Array<char>& description) override; bool possibleBondOrder(int idx, int order) override; bool isSaturatedAtom(int idx) override; bool bondStereoCare(int idx) override; bool aromatize(const AromaticityOptions& options) override; bool dearomatize(const AromaticityOptions& options) override; int addAtom(int label) override; int addBond(int beg, int end, int order) override; int addBond_Silent(int beg, int end, int order) override; int getImplicitH(int idx, bool impl_h_no_throw) override; void setImplicitH(int idx, int impl_h) override; int layers; protected: struct AromatizationContext { LayeredMolecules* self; int layerFrom; int layerTo; bool result; }; Molecule _proto; ObjArray<Dbitset> _bond_masks[BOND_TYPES_NUMBER]; Array<bool> _mobilePositions; ObjArray<Dbitset> _mobilePositionsOccupied; void _mergeWithSubmolecule(BaseMolecule& bmol, const Array<int>& vertices, const Array<int>* edges, const Array<int>& mapping, int skip_flags) override; static bool _cb_handle_cycle(Graph& graph, const Array<int>& vertices, const Array<int>& edges, void* context); void _resizeLayers(int newSize); void _calcConnectivity(int layerFrom, int layerTo); void _calcPiLabels(int layerFrom, int layerTo); bool _handleCycle(int layerFrom, int layerTo, const Array<int>& path); bool _isCycleAromaticInLayer(const int* cycle, int cycle_len, int layer); void _aromatizeCycle(const Array<int>& cycle, const Dbitset& mask); void _registerAromatizedLayers(int layerFrom, int layerTo); private: LayeredMolecules(const LayeredMolecules&); // no implicit copy ObjArray<Array<int>> _piLabels; ObjArray<Array<int>> _connectivity; int _layersAromatized; struct TrieNode { static const int ALPHABET_SIZE = 5; TrieNode() { for (auto& n : next) n = -1; } int next[ALPHABET_SIZE]; }; class Trie { public: Trie() { // Adding root (index == 0) _nodes->add(); } unsigned getRoot() { return 0; } unsigned follow(unsigned nodeInd, unsigned key) { return _nodes->at(nodeInd).next[key]; } unsigned add(unsigned nodeInd, unsigned key, bool& newlyAdded) { if (_nodes->at(nodeInd).next[key] != -1) { newlyAdded = false; return _nodes->at(nodeInd).next[key]; } newlyAdded = true; int ind = _nodes->add(); _nodes->at(nodeInd).next[key] = ind; return ind; } private: std::unique_ptr<ObjPool<TrieNode>> _nodes = std::make_unique<ObjPool<TrieNode>>(); }; Trie _trie; Array<unsigned> _hashs; Array<unsigned> _hashsAromatized; }; } // namespace indigo #ifdef _WIN32 #pragma warning(pop) #endif #endif