1 // XDrawChem 2 // Copyright (C) 2004-2005 Bryan Herger <bherger@users.sourceforge.net> 3 // Copyright (C) 2020 Yaman Qalieh <ybq987@gmail.com> 4 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 15 // You should have received a copy of the GNU General Public License 16 // along with this program. If not, see <https://www.gnu.org/licenses/>. 17 18 // molecule.h -- subclass of Drawable which contains a molecule 19 20 #ifndef MOLECULE_H 21 #define MOLECULE_H 22 23 #include <openbabel/atom.h> 24 #include <openbabel/bond.h> 25 #include <openbabel/elements.h> 26 #include <openbabel/math/vector3.h> 27 #include <openbabel/mol.h> 28 #include <openbabel/obconversion.h> 29 30 using namespace OpenBabel; 31 32 #include "bond.h" 33 #include "chemdata.h" 34 #include "dpoint.h" 35 #include "drawable.h" 36 #include "molecule_sssr.h" 37 #include "peak.h" 38 #include "render2d.h" 39 #include "symbol.h" 40 #include "text.h" 41 #include "tooldialog.h" 42 43 class Molecule : public Drawable { 44 public: 45 Molecule(Render2D *, QObject *parent = 0); 46 Molecule *CloneTo(Drawable *target = nullptr) const; 47 ~Molecule(); getRender2D()48 Render2D *getRender2D() { return r; } SetChemdata(ChemData * cd1)49 void SetChemdata(ChemData *cd1) { cd = cd1; } 50 void Render(); // draw this object 51 int Type(); // return type of object 52 bool Find(DPoint *); // is this DPoint present in this Molecule? 53 DPoint *FindNearestPoint(DPoint *, double &); 54 Drawable *FindNearestObject(DPoint *, double &); 55 void addBond(DPoint *, DPoint *, int, int, QColor, bool hl = false); 56 void addBond(Bond *); 57 void addText(Text *); 58 void addSymbol(Symbol *); 59 void CopyTextToDPoint(); 60 void CalcOffsets(); 61 void addMolecule(Drawable *); bondsFirst()62 Bond *bondsFirst() { return bonds.first(); } 63 // Bond *bondsNext() { return bonds.next(); } 64 labelsFirst()65 Text *labelsFirst() { 66 if (!labels.isEmpty()) 67 return labels.first(); 68 else 69 return 0; 70 } 71 72 // Text *labelsNext() { return labels.next(); } 73 bool Erase(Drawable *); 74 void EraseSelected(); 75 bool isWithinRect(QRect, bool); 76 bool WithinBounds(DPoint *); 77 void SelectAll(); 78 void DeselectAll(); 79 void SetColorIfHighlighted(QColor); 80 void Move(double, double); 81 void Rotate(DPoint *, double); 82 void Rotate(double); 83 void Flip(DPoint *, int); 84 void Resize(DPoint *, double); 85 QRect BoundingBox(); 86 QRect BoundingBoxAll(); 87 QList<DPoint *> AllPoints(); 88 QList<Drawable *> AllObjects(); 89 QList<Bond *> AllBonds(); 90 QList<Text *> AllLabels(); 91 QList<Molecule *> MakeSplit(); Members()92 int Members() { return bonds.count(); } 93 QString ToXML(QString); 94 QString ToCDXML(QString); 95 QString ToMDLMolfile(int coords = 0); 96 void FromXML(QString); 97 void Changed(); 98 // defined in molecule_tools.cpp 99 Bond *FindBond(DPoint *, DPoint *); 100 int OrderOfBond(DPoint *, DPoint *); 101 void Reactivity(int); // molecule_tools_2.cpp for now 102 QList<DPoint *> BreakRingBonds(DPoint *); 103 DPoint *GetRingAttachPoint(); 104 DPoint *GetAttachPoint(QString); 105 double CalculateRingAttachAngle(DPoint *); 106 void FindHybridization(); 107 void setGroupType(int); 108 Text *CalcMW(bool from_change = false); 109 Text *CalcEmpiricalFormula(bool from_mw = false); 110 Text *CalcElementalAnalysis(bool show_dialog = true); 111 QStringList Calc13CNMR(bool show_dialog = true); 112 void CalcIR(); 113 QString CalcName(); // actually returns canonical SMILES 114 // QString GetCASNumber(); 115 // QString IUPAC_Name(); 116 void AllNeighbors(); 117 void MakeSSSR(); 118 void AddHydrogens(bool to_carbon = false); 119 double SumBondEnthalpy(); 120 void Scale(double bond_length = -1.0); 121 void AddPeak(double, QString, QString); 122 void Make3DVersion(QString fn3d = ""); 123 void CalcpKa(); 124 double CalcPartialCharge(QString); 125 double CalcKOW(); 126 // defined in molecule_1h_nmr.cpp 127 QStringList Calc1HNMR(bool show_dialog = true); 128 void AddNMRprotons(); 129 void RemoveNMRprotons(); 130 void ProtonEnvironment(); 131 void Multiplicity_1HNMR(); 132 void Calc1HMultiplicityAndIntensity(); 133 double Calc1HShift(QString); 134 // defined in molecule_smiles.cpp 135 void CleanUp(); 136 void SDG(bool); 137 QString ToSMILES(); 138 void FromSMILES(QString); 139 QString ToInChI(); 140 void FromInChI(QString); 141 // defined in retro.cpp 142 QString BuildReactionList(QString); 143 int Retro(); 144 QString RetroTraverseBonds(DPoint *, DPoint *, Bond *, int); 145 QString RetroAtomName(DPoint *); 146 QString RetroBondName(Bond *, bool runsssr = false); 147 bool RetroMatch(QString, QString); 148 bool RetroTreeMatch(QString, QString, QString, QString); 149 // defined here: isInGroup()150 bool isInGroup() { 151 if (group_type != GROUP_NONE) 152 return true; 153 return false; 154 } groupType()155 int groupType() { return group_type; } FormulaLabelDeleted()156 void FormulaLabelDeleted() { 157 qDebug() << "FLD"; 158 text_formula = 0; 159 } MWLabelDeleted()160 void MWLabelDeleted() { text_mw = 0; } Angle(Bond * a1,Bond * b1)161 double Angle(Bond *a1, Bond *b1) { 162 // from Bond a1 to Bond b1 163 // determine endpoints 164 DPoint *a, *c, *b; 165 if (a1->Start() == b1->Start()) { 166 c = a1->Start(); 167 a = a1->End(); 168 b = b1->End(); 169 } 170 if (a1->Start() == b1->End()) { 171 c = a1->Start(); 172 a = a1->End(); 173 b = b1->Start(); 174 } 175 if (a1->End() == b1->Start()) { 176 c = a1->End(); 177 b = a1->Start(); 178 a = b1->End(); 179 } 180 if (a1->End() == b1->End()) { 181 c = a1->End(); 182 b = a1->Start(); 183 a = b1->Start(); 184 } 185 double ang1 = getAngle(c, a); 186 double ang2 = getAngle(c, b); 187 double ang3 = ang1 - ang2; 188 if (ang3 < 0.0) 189 ang3 += 360.0; 190 return ang3; 191 } 192 193 OBMol *convertToOBMol(); 194 bool convertFromOBMol(OBMol *); 195 static const char symbol[110][4]; 196 197 // not appropriate but best way to handle ToolDialog requests. 198 QList<Peak *> peaklist; 199 200 private: 201 // Renderer 202 Render2D *r; 203 // ChemData 204 ChemData *cd; 205 // list of elements which make up this molecule 206 QList<Bond *> bonds; 207 QList<Text *> labels; 208 QList<Symbol *> symbols; 209 // Text objects which hold MW and formula 210 Text *text_mw, *text_formula; 211 // list of unique points used by Move(), Resize(), Rotate(), and 212 // function to fill it 213 void MakeTomoveList(); 214 QList<DPoint *> tomove; 215 // used for elemental analysis (set by CalcEmpiricalFormula) 216 double nc, nh, no, nn, nmw; 217 // Molecule's SSSR 218 SSSR this_sssr; 219 // point list for SDG, etc. 220 QList<DPoint *> up; 221 // group data 222 int group_type; 223 int group_id; 224 // proton magnetic environment list(s) 225 QStringList protonMagEnvList; 226 QStringList protonFinalList; 227 // render partial charges? 228 bool showPC; 229 // reactivity info 230 QStringList atomRxns, bondRxns; 231 }; 232 233 #endif 234