core/indigo-core/reaction/pathway_reaction.h (223 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. ***************************************************************************/ #pragma once #ifdef _WIN32 #pragma warning(push) #pragma warning(disable : 4251) #endif #include "base_cpp/array.h" #include "reaction/reaction.h" #include <deque> namespace indigo { class Reaction; class DLLEXPORT PathwayReaction : public BaseReaction { public: struct SimpleReaction { struct Plus { int metaIndex; int componentIndex1; int componentIndex2; }; SimpleReaction() : arrowMetaIndex(-1) { } SimpleReaction(const SimpleReaction& other) : arrowMetaIndex(other.arrowMetaIndex) { reactantIndexes.copy(other.reactantIndexes); productIndexes.copy(other.productIndexes); pluses.copy(other.pluses); properties.copy(other.properties); } Array<int> reactantIndexes; Array<int> productIndexes; Array<Plus> pluses; int arrowMetaIndex; RedBlackStringObjMap<Array<char>> properties; }; struct ReactionNode { ReactionNode() : reactionIdx(-1), multiTailMetaIndex(-1), text_width(0) { } ReactionNode(const ReactionNode& other) { reactionIdx = other.reactionIdx; multiTailMetaIndex = other.multiTailMetaIndex; text_width = other.text_width; for (int i = 0; i < other.successorReactionIndexes.size(); ++i) successorReactionIndexes.push(other.successorReactionIndexes[i]); precursorReactionIndexes.copy(other.precursorReactionIndexes); for (int i = 0; i < other.name_text.size(); ++i) name_text.push().copy(other.name_text[i]); for (int i = 0; i < other.conditions_text.size(); ++i) conditions_text.push().copy(other.conditions_text[i]); } int reactionIdx; // vector of successor reactions indexes and their corresponding reactant indexes Array<int> successorReactionIndexes; // vector of precursor reactions indexes Array<int> precursorReactionIndexes; // utility information RedBlackMap<int, int> connectedReactants; // where the precursors' products are connected to int multiTailMetaIndex; ObjArray<Array<char>> name_text; ObjArray<Array<char>> conditions_text; float text_width; }; PathwayReaction(); ~PathwayReaction() override; std::unique_ptr<BaseReaction> getBaseReaction(int index) override { std::unique_ptr<BaseReaction> reaction(new Reaction()); auto& sr = _reactions[index]; for (auto pidx : sr.productIndexes) reaction->addProductCopy(*_molecules[pidx], 0, 0); for (auto ridx : sr.reactantIndexes) reaction->addReactantCopy(*_molecules[ridx], 0, 0); reaction->properties().copy(sr.properties); return reaction; } std::vector<int> getRootReactions() const; auto& getReactionNode(int node_idx) { return _reactionNodes[node_idx]; } int getReactionNodeCount() const { return static_cast<int>(_reactionNodes.size()); } auto& getMolecule(int mol_idx) { return *_molecules[mol_idx]; } int getMoleculeCount() const { return static_cast<int>(_molecules.size()); } auto& getReaction(int reaction_idx) { return _reactions[reaction_idx]; } int getReactionCount() const { return static_cast<int>(_reactions.size()); } int reactionsCount() override { return _reactions.size(); } Reaction& asReaction() override { _rootReaction.clone(*this); return _rootReaction; } void copyToReaction(BaseReaction& reaction) { reaction.clear(); reaction.meta().clone(meta()); // collect roles std::map<int, int> mol_roles; for (int i = 0; i < _reactions.size(); ++i) { auto& reac = _reactions[i]; for (auto mol_idx : reac.productIndexes) { auto product_it = mol_roles.find(mol_idx); if (product_it != mol_roles.end()) { if (product_it->second == REACTANT) product_it->second = INTERMEDIATE; } else mol_roles.emplace(mol_idx, PRODUCT); } for (auto mol_idx : reac.reactantIndexes) { auto reactant_it = mol_roles.find(mol_idx); if (reactant_it != mol_roles.end()) { if (reactant_it->second == PRODUCT) reactant_it->second = INTERMEDIATE; } else mol_roles.emplace(mol_idx, REACTANT); } } // copy molecules into Reaction for (auto& kvp : mol_roles) { switch (kvp.second) { case PRODUCT: reaction.addProductCopy(*_molecules[kvp.first], 0, 0); break; case REACTANT: reaction.addReactantCopy(*_molecules[kvp.first], 0, 0); break; case INTERMEDIATE: reaction.addIntermediateCopy(*_molecules[kvp.first], 0, 0); break; case CATALYST: reaction.addCatalystCopy(*_molecules[kvp.first], 0, 0); break; case UNDEFINED: reaction.addUndefinedCopy(*_molecules[kvp.first], 0, 0); break; } } } bool isPathwayReaction() override { return true; } PathwayReaction& asPathwayReaction() override { return *this; } ReactionNode& addReactionNode() { ReactionNode rn; rn.reactionIdx = static_cast<int>(_reactionNodes.size()); _reactionNodes.push(rn); return _reactionNodes[_reactionNodes.size() - 1]; } int addMolecule(BaseMolecule& mol) { std::unique_ptr<BaseMolecule> mol_copy(mol.neu()); mol_copy->clone(mol); _molecules.add(mol_copy.release()); return static_cast<int>(_molecules.size() - 1); } std::pair<int, SimpleReaction&> addReaction() { SimpleReaction sr; _reactions.push(sr); return {static_cast<int>(_reactions.size() - 1), _reactions[_reactions.size() - 1]}; } BaseReaction* neu() override; bool aromatize(const AromaticityOptions& options) override; bool dearomatize(const AromaticityOptions& options) override; int reactionBegin() override { return _reactions.size() ? 0 : 1; } int reactionEnd() override { return _reactions.size(); } int reactionNext(int i) override { return ++i; } void clear() override; DECL_ERROR; protected: int _addBaseMolecule(int side) override; void _cloneSub(BaseReaction& other) override; private: ObjArray<ReactionNode> _reactionNodes; PtrArray<BaseMolecule> _molecules; ObjArray<SimpleReaction> _reactions; Reaction _rootReaction; // copy of root reaction }; } // namespace indigo #ifdef _WIN32 #pragma warning(pop) #endif