core/indigo-core/molecule/ket_objects.h (865 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 __ket_objects__ #define __ket_objects__ #include <map> #include <memory> #include <optional> #include <string> #include <vector> #include <rapidjson/document.h> #include "common/base_c/defs.h" #include "common/base_cpp/exception.h" #include "common/math/algebra.h" #include "molecule/idt_alias.h" #include "molecule/monomers_defs.h" #ifdef _WIN32 #pragma warning(push) #pragma warning(disable : 4251) #endif namespace indigo { class MonomerTemplate; class JsonWriter; template <typename T> constexpr auto toUType(T enumerator) noexcept { return static_cast<std::underlying_type_t<T>>(enumerator); } using ket_connections_type = std::map<std::string, std::pair<std::string, std::string>>; class DLLEXPORT KetObjWithProps { public: DECL_ERROR; inline void setBoolProp(int idx, bool value) { _bool_props[idx] = value; }; inline void setIntProp(int idx, int value) { _int_props[idx] = value; }; inline void setIntProp(int idx, std::size_t value) { _int_props[idx] = static_cast<int>(value); }; inline void setStringProp(int idx, std::string value) { _string_props[idx] = value; }; void setBoolProp(std::string name, bool value); void setIntProp(std::string name, int value); void setStringProp(std::string name, std::string value); virtual const std::map<std::string, int>& getBoolPropStrToIdx() const; virtual const std::map<std::string, int>& getIntPropStrToIdx() const; virtual const std::map<std::string, int>& getStringPropStrToIdx() const; inline bool hasBoolProp(int idx) const { return _bool_props.count(idx) > 0; }; inline bool hasIntProp(int idx) const { return _int_props.count(idx) > 0; }; inline bool hasStringProp(int idx) const { return _string_props.count(idx) > 0; }; bool getBoolProp(int idx) const; int getIntProp(int idx) const; const std::string& getStringProp(int idx) const; std::pair<bool, int> getBoolPropIdx(const std::string& name) const; std::pair<bool, int> getIntPropIdx(const std::string& name) const; std::pair<bool, int> getStringPropIdx(const std::string& name) const; bool hasBoolProp(const std::string& name) const { auto res = getBoolPropIdx(name); if (res.first) return hasBoolProp(res.second); return false; } bool hasIntProp(const std::string& name) const { auto res = getIntPropIdx(name); if (res.first) return hasIntProp(res.second); return false; }; bool hasStringProp(const std::string& name) const { auto res = getStringPropIdx(name); if (res.first) return hasStringProp(res.second); return false; }; bool getBoolProp(const std::string& name) const; int getIntProp(const std::string& name) const; const std::string& getStringProp(const std::string& name) const; void parseOptsFromKet(const rapidjson::Value& json); void saveOptsToKet(JsonWriter& writer) const; void copy(const KetObjWithProps& other) { _bool_props = other._bool_props; _int_props = other._int_props; _string_props = other._string_props; } private: std::map<int, bool> _bool_props; std::map<int, int> _int_props; std::map<int, std::string> _string_props; }; class KetQueryProperties : public KetObjWithProps { public: DECL_ERROR; const std::map<std::string, int>& getIntPropStrToIdx() const override; const std::map<std::string, int>& getStringPropStrToIdx() const override; private: enum class IntProps { degree, ringMembership, ringSize, connectivity, ringConnectivity, atomicMass, }; enum class StringProps { aromaticity, chirality, }; }; class DLLEXPORT KetBaseAtomType : public KetObjWithProps { public: DECL_ERROR; enum class atype { atom, atom_list, rg_label, }; explicit KetBaseAtomType() = delete; static atype stringToAtype(std::string atom_type); inline atype getType() const { return _type; }; inline void setLocation(Vec3f location) { _location = location; } inline const std::optional<Vec3f>& location() const { return _location; }; protected: KetBaseAtomType(atype atype) : _type(atype){}; atype _type; std::optional<Vec3f> _location; }; class DLLEXPORT KetBaseAtom : public KetBaseAtomType { public: DECL_ERROR; explicit KetBaseAtom() = delete; const std::map<std::string, int>& getIntPropStrToIdx() const override; const std::map<std::string, int>& getStringPropStrToIdx() const override; void setQueryProperties(KetQueryProperties& query_properties) { _query_properties = query_properties; }; const std::optional<KetQueryProperties>& queryProperties() const { return _query_properties; }; protected: KetBaseAtom(atype atype) : KetBaseAtomType(atype){}; private: enum class IntProps { charge, explicitValence, isotope, radical, attachmentPoints, stereoParity, ringBondCount, substitutionCount, hCount, implicitHCount, mapping, invRet }; enum class StringProps { alias, stereoLabel, cip }; std::optional<KetQueryProperties> _query_properties; }; class DLLEXPORT KetAtom : public KetBaseAtom { public: DECL_ERROR; KetAtom(const std::string& label) : KetBaseAtom(atype::atom), _label(label){}; KetAtom(const std::string& label, const std::string& custom_query) : KetBaseAtom(atype::atom), _label(label), _custom_query(custom_query){}; const std::map<std::string, int>& getBoolPropStrToIdx() const override; const std::map<std::string, int>& getIntPropStrToIdx() const override; const std::map<std::string, int>& getStringPropStrToIdx() const override; const std::string& label() const { return _label; }; const std::optional<std::string>& customQuery() const { return _custom_query; }; private: enum class BoolProps { unsaturatedAtom, exactChangeFlag }; std::string _label; std::optional<std::string> _custom_query; }; class DLLEXPORT KetAtomList : public KetBaseAtom { public: DECL_ERROR; KetAtomList(std::vector<std::string> atom_list) : KetBaseAtom(atype::atom), _atom_list(atom_list){}; inline const std::vector<std::string>& atomList() const { return _atom_list; } const std::map<std::string, int>& getBoolPropStrToIdx() const override; private: enum class BoolProps { unsaturatedAtom, exactChangeFlag, notlist }; std::vector<std::string> _atom_list; }; class DLLEXPORT KetRgLabel : public KetBaseAtomType { public: using AttachemntOrder = std::vector<std::pair<int, int>>; KetRgLabel() : KetBaseAtomType(atype::atom), _attachmentOrder(), _refs(){}; inline void setAttachmentOrder(AttachemntOrder& attOrder) { _attachmentOrder = attOrder; }; inline const std::optional<AttachemntOrder>& attachmentOrder() const { return _attachmentOrder; }; inline void setRefs(std::vector<std::string>& refs) { _refs = refs; }; inline const std::optional<std::vector<std::string>>& refs() const { return _refs; }; private: std::optional<AttachemntOrder> _attachmentOrder; std::optional<std::vector<std::string>> _refs; }; class DLLEXPORT KetBond : public KetObjWithProps { public: DECL_ERROR; enum class bond_types { single = 1, double_bond, triple, aromatic, single_or_double, single_or_aromatic, double_or_aromatic, any, coordination, hydrogen }; KetBond(int bond_type, int atom1, int atom2); KetBond(const KetBond& other) : KetObjWithProps(other), _type(other._type), _atoms(other._atoms){}; const std::map<std::string, int>& getIntPropStrToIdx() const override; const std::map<std::string, int>& getStringPropStrToIdx() const override; inline bond_types getType() const { return _type; }; inline const std::pair<int, int>& atoms() const { return _atoms; }; inline void setStereoFlagPosition(float x, float y, float z = 0) { _stereo_flag_position.emplace(x, y, z); }; inline bool hasStereoFlagPosition() { return _stereo_flag_position.has_value(); }; inline const Vec3f& stereoFlagPosition() { return _stereo_flag_position.value(); } private: enum class IntProps { stereo, topology, center, stereobox }; enum class StringProps { cip }; bond_types _type; std::pair<int, int> _atoms; std::optional<Vec3f> _stereo_flag_position; }; class DLLEXPORT KetBaseSGroup : public KetObjWithProps { public: DECL_ERROR; enum class SGroupType { multiple, repetition_unit, superatom, data, queryComponent }; protected: KetBaseSGroup(SGroupType sg_type, std::vector<int>& atoms) : _type(sg_type), _atoms(atoms){}; private: SGroupType _type; std::vector<int> _atoms; }; class DLLEXPORT KetMulSGroup : public KetBaseSGroup { public: DECL_ERROR; KetMulSGroup(std::vector<int>& atoms, int mul) : KetBaseSGroup(SGroupType::multiple, atoms), _mul(mul){}; private: int _mul; }; class DLLEXPORT KetRUSGroup : public KetBaseSGroup { public: DECL_ERROR; KetRUSGroup(std::vector<int>& atoms, std::string& connectivity) : KetBaseSGroup(SGroupType::repetition_unit, atoms), _connectivity(connectivity){}; const std::map<std::string, int>& getStringPropStrToIdx() const override; private: enum class StringProps { subscript }; std::string _connectivity; }; class DLLEXPORT KetSASGroupAttPoint : public KetObjWithProps { public: KetSASGroupAttPoint(int attachment_atom) : _attachment_atom(attachment_atom){}; const std::map<std::string, int>& getIntPropStrToIdx() const override; const std::map<std::string, int>& getStringPropStrToIdx() const override; private: enum class IntProps { leavingAtom }; enum class StringProps { attachmentId }; int _attachment_atom; }; class DLLEXPORT KetSASGroup : public KetBaseSGroup { public: DECL_ERROR; KetSASGroup(std::vector<int>& atoms, std::string& name) : KetBaseSGroup(SGroupType::superatom, atoms), _name(name){}; const std::map<std::string, int>& getBoolPropStrToIdx() const override; private: enum class BoolProps { expanded }; std::string _name; }; class DLLEXPORT KetDataSGroup : public KetBaseSGroup { public: DECL_ERROR; KetDataSGroup(std::vector<int>& atoms, std::string& name, std::string& data) : KetBaseSGroup(SGroupType::data, atoms), _name(name), _data(data){}; inline void setBonds(std::vector<int> bonds) { _bonds = bonds; }; inline bool hasBonds() { return _bonds.has_value(); }; inline const std::vector<int>& bonds() { return _bonds.value(); }; const std::map<std::string, int>& getBoolPropStrToIdx() const override; const std::map<std::string, int>& getStringPropStrToIdx() const override; private: enum class BoolProps { display, placement }; enum class StringProps { context }; std::string _name; std::string _data; std::optional<std::vector<int>> _bonds; }; class DLLEXPORT KetQueryComponentSGroup : public KetBaseSGroup { public: KetQueryComponentSGroup(std::vector<int>& atoms) : KetBaseSGroup(SGroupType::queryComponent, atoms){}; }; class DLLEXPORT KetMolecule { public: DECL_ERROR; static inline const std::string ref_prefix = "molecule"; KetMolecule() : _atoms(){}; KetMolecule(const KetMolecule& other) = delete; KetMolecule& operator=(const KetMolecule&) = delete; using atom_ptr = std::shared_ptr<KetBaseAtomType>; using atoms_type = std::vector<atom_ptr>; using sgroup_ptr = std::unique_ptr<KetBaseSGroup>; using sgroups_type = std::vector<sgroup_ptr>; KetMolecule(KetMolecule&& other) : _atoms(std::move(other._atoms)), _bonds(std::move(other._bonds)), _sgroups(std::move(other._sgroups)){}; atom_ptr& addAtom(const std::string& label); atom_ptr& addAtom(const std::string& label, const std::string& custom_query); atom_ptr& addAtomList(std::vector<std::string>& atom_list); atom_ptr& addRGLabel(); sgroup_ptr& addMulSGroup(std::vector<int>& atoms, int mul); sgroup_ptr& addRUSGroup(std::vector<int>& atoms, std::string& connectivity); sgroup_ptr& addSASGroup(std::vector<int>& atoms, std::string& name); sgroup_ptr& addDataSGroup(std::vector<int>& atoms, std::string& name, std::string& data); sgroup_ptr& addQueryComponentSGroup(std::vector<int>& atoms); inline void setAtoms(atoms_type& atoms) { _atoms = std::move(atoms); }; inline void addBond(KetBond& bond) { _bonds.emplace_back(bond); }; inline const atoms_type& atoms() const { return _atoms; }; inline atoms_type& writableAtoms() { return _atoms; }; inline const std::vector<KetBond>& bonds() const { return _bonds; }; inline std::vector<KetBond>& writableBonds() { return _bonds; }; static void parseKetAtoms(atoms_type& ket_atoms, const rapidjson::Value& atoms); static void parseKetBonds(std::vector<KetBond>& ket_bonds, const rapidjson::Value& bonds); void parseKetAtoms(const rapidjson::Value& atoms) { parseKetAtoms(_atoms, atoms); } void parseKetBonds(const rapidjson::Value& bonds) { parseKetBonds(_bonds, bonds); } void parseKetSGroups(rapidjson::Value& sgroups); private: atoms_type _atoms; std::vector<KetBond> _bonds; sgroups_type _sgroups; }; class DLLEXPORT KetAttachmentPoint : public KetObjWithProps { public: DECL_ERROR; KetAttachmentPoint(int attachment_atom) : _attachment_atom(attachment_atom){}; const std::map<std::string, int>& getStringPropStrToIdx() const override; int attachment_atom() const { return _attachment_atom; }; void setLeavingGroup(std::vector<int>& leaving_group) { _leaving_group = leaving_group; }; const std::optional<std::vector<int>> leavingGroup() const { return _leaving_group; }; private: enum class StringProps { type, label, }; int _attachment_atom; std::optional<std::vector<int>> _leaving_group; }; class DLLEXPORT KetBaseMonomer : public KetObjWithProps { public: DECL_ERROR; enum class MonomerType { Monomer, AmbiguousMonomer, }; KetBaseMonomer(MonomerType monomer_type, const std::string& id, const std::string& alias, const std::string& template_id) : _monomer_type(monomer_type), _id(id), _template_id(template_id), _alias(alias){}; void setRef(const std::string& ref) { _ref = ref; }; const std::string& ref() const { return _ref; }; inline void setPosition(const Vec2f& position) { _position = position; }; inline void setPosition(const Vec3f& position) { _position = Vec2f(position.x, position.y); }; const std::optional<Vec2f>& position() const { return _position; }; const std::string& id() const { return _id; }; const std::string& templateId() const { return _template_id; }; void setAttachmentPoints(const std::map<std::string, KetAttachmentPoint>& attachment_points) { _attachment_points = attachment_points; }; const std::map<std::string, KetAttachmentPoint>& attachmentPoints() const { return _attachment_points; }; void connectAttachmentPointTo(const std::string& ap_id, const std::string& monomer_ref, const std::string& other_ap_id); void disconnectAttachmentPoint(const std::string& ap_id) { _connections.erase(ap_id); }; const ket_connections_type& connections() const { return _connections; }; MonomerType monomerType() const { return _monomer_type; }; const std::string& alias() const { return _alias; }; protected: MonomerType _monomer_type; std::string _id; std::string _template_id; std::string _alias; std::optional<Vec2f> _position; std::map<std::string, KetAttachmentPoint> _attachment_points; ket_connections_type _connections; std::string _ref; }; class DLLEXPORT KetMonomer : public KetBaseMonomer { public: DECL_ERROR; static inline const std::string ref_prefix = "monomer"; KetMonomer(const std::string& id, const std::string& alias, const std::string& template_id) : KetBaseMonomer(MonomerType::Monomer, id, alias, template_id) { _ref = ref_prefix + _id; }; const std::map<std::string, int>& getIntPropStrToIdx() const override; private: enum class IntProps { seqid }; }; class DLLEXPORT KetConnectionEndPoint : public KetObjWithProps { public: DECL_ERROR; const std::map<std::string, int>& getStringPropStrToIdx() const override; private: enum class StringProps { groupId, monomerId, moleculeId, atomId, attachmentPointId }; }; class DLLEXPORT KetConnection : public KetObjWithProps { public: DECL_ERROR; enum class TYPE { SINGLE, HYDROGEN }; KetConnection(const std::string& conn_type, KetConnectionEndPoint ep1, KetConnectionEndPoint ep2) : _connection_type(conn_type), _ep1(ep1), _ep2(ep2){}; KetConnection(TYPE conn_type, KetConnectionEndPoint ep1, KetConnectionEndPoint ep2); KetConnection(KetConnectionEndPoint ep1, KetConnectionEndPoint ep2) : _connection_type("single"), _ep1(ep1), _ep2(ep2){}; const std::map<std::string, int>& getStringPropStrToIdx() const override; const TYPE connType() const; // connection type could be "single" or "hydrogen" inline const std::string connectionType() const { return _connection_type; }; const KetConnectionEndPoint& ep1() const { return _ep1; }; const KetConnectionEndPoint& ep2() const { return _ep2; }; const std::string id() { if (!_id.has_value()) { _id.emplace(_ep1.getStringProp("monomerId") + _ep1.getStringProp("attachmentPointId") + _ep2.getStringProp("monomerId") + _ep2.getStringProp("attachmentPointId")); } return _id.value(); }; private: enum class StringProps { label, }; std::string _connection_type; KetConnectionEndPoint _ep1; KetConnectionEndPoint _ep2; std::optional<std::string> _id; }; class DLLEXPORT KetAmbiguousMonomerOption : public KetObjWithProps { public: DECL_ERROR; KetAmbiguousMonomerOption(const std::string& templateId) : _templateId(templateId){}; const std::string& templateId() const { return _templateId; }; void setProbability(float probability) { _probability = probability; }; void setRatio(float ratio) { _ratio = ratio; }; const std::optional<float>& probability() const { return _probability; }; const std::optional<float>& ratio() const { return _ratio; }; private: std::string _templateId; std::optional<float> _probability; std::optional<float> _ratio; }; class DLLEXPORT KetBaseMonomerTemplate : public KetObjWithProps { public: DECL_ERROR; enum class TemplateType { MonomerTemplate, AmbiguousMonomerTemplate }; KetBaseMonomerTemplate(TemplateType template_type, const std::string& id, MonomerClass monomer_class, IdtAlias idt_alias) : _template_type(template_type), _id(id), _monomer_class(monomer_class), _idt_alias(idt_alias){}; const std::string& id() const { return _id; }; void setAttachmentPoints(const std::map<std::string, KetAttachmentPoint>& attachment_points) { _attachment_points = attachment_points; }; const std::map<std::string, KetAttachmentPoint>& attachmentPoints() const { return _attachment_points; }; void setMonomerClass(MonomerClass monomer_class) { _monomer_class = monomer_class; }; MonomerClass monomerClass() const { return _monomer_class; } inline const IdtAlias& idtAlias() const { return _idt_alias; } inline void setIdtAlias(const IdtAlias& idt_alias) { _idt_alias = idt_alias; } void copy(const KetBaseMonomerTemplate& other) { KetObjWithProps::copy(other); _id = other._id; _monomer_class = other._monomer_class; _attachment_points = other._attachment_points; _idt_alias = other._idt_alias; }; bool hasIdtAlias(const std::string& alias, IdtModification mod); bool hasIdtAliasBase(const std::string& alias_base); TemplateType templateType() const { return _template_type; }; protected: std::string _id; MonomerClass _monomer_class; std::map<std::string, KetAttachmentPoint> _attachment_points; private: TemplateType _template_type; IdtAlias _idt_alias; }; class DLLEXPORT KetAmbiguousMonomerTemplate : public KetBaseMonomerTemplate { public: DECL_ERROR; inline static std::string ref_prefix = "ambiguousMonomerTemplate-"; KetAmbiguousMonomerTemplate(const std::string& subtype, const std::string& id, const std::string& alias, IdtAlias idt_alias, const std::vector<KetAmbiguousMonomerOption>& options) : KetBaseMonomerTemplate(TemplateType::AmbiguousMonomerTemplate, id, MonomerClass::Unknown, idt_alias), _subtype(subtype), _alias(alias), _options(options){}; const std::string& subtype() const { return _subtype; }; const std::string& alias() const { return _alias; }; const std::vector<KetAmbiguousMonomerOption>& options() const { return _options; }; private: std::string _subtype; std::string _alias; std::vector<KetAmbiguousMonomerOption> _options; }; class DLLEXPORT KetAmbiguousMonomer : public KetBaseMonomer { public: DECL_ERROR; inline static std::string ref_prefix = "ambiguousMonomer-"; KetAmbiguousMonomer(const std::string& id, const std::string& alias, const std::string& template_id) : KetBaseMonomer(MonomerType::AmbiguousMonomer, id, alias, template_id) { _ref = ref_prefix + _id; }; const std::map<std::string, int>& getIntPropStrToIdx() const override; const std::map<std::string, int>& getStringPropStrToIdx() const override; private: enum class IntProps { seqid }; enum class StringProps { alias }; }; class DLLEXPORT SimplePolymer { public: private: }; class DLLEXPORT KetMonomerShape : public KetObjWithProps { public: DECL_ERROR; inline static std::string ref_prefix = "monomerShape-"; enum class shape_type { generic, antibody, double_helix, globular_protein }; KetMonomerShape(const std::string& id, bool collapsed, const std::string& shape, Vec2f position, const std::vector<std::string>& monomers); const std::string& id() const { return _id; } bool collapsed() const { return _collapsed; } shape_type shape() const { return _shape; } static shape_type strToShapeType(std::string shape); static std::string shapeTypeToStr(shape_type shape); Vec2f position() const { return _position; } const std::vector<std::string>& monomers() const { return _monomers; } private: std::string _id; bool _collapsed; shape_type _shape; Vec2f _position; std::vector<std::string> _monomers; }; } #ifdef _MSC_VER #pragma warning(pop) #endif #endif