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