/src/openbabel/src/formats/boxformat.cpp
Line | Count | Source |
1 | | /********************************************************************** |
2 | | Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc. |
3 | | Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison |
4 | | Some portions Copyright (C) 2004 by Chris Morley |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation version 2 of the License. |
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 | | #include <openbabel/babelconfig.h> |
16 | | |
17 | | #include <openbabel/obmolecformat.h> |
18 | | #include <openbabel/mol.h> |
19 | | #include <openbabel/atom.h> |
20 | | #include <openbabel/elements.h> |
21 | | #include <cstdlib> |
22 | | |
23 | | using namespace std; |
24 | | namespace OpenBabel |
25 | | { |
26 | | |
27 | | class BoxFormat : public OBMoleculeFormat |
28 | | { |
29 | | public: |
30 | | //Register this format type ID |
31 | | BoxFormat() |
32 | 6 | { |
33 | 6 | OBConversion::RegisterFormat("box",this); |
34 | 6 | } |
35 | | |
36 | | const char* Description() override // required |
37 | 0 | { |
38 | 0 | return |
39 | 0 | "Dock 3.5 Box format\n" |
40 | 0 | "No comments yet\n"; |
41 | 0 | } |
42 | | |
43 | | const char* SpecificationURL() override |
44 | 0 | { return "http://dock.compbio.ucsf.edu/"; } // optional |
45 | | |
46 | | //Flags() can return be any the following combined by | or be omitted if none apply |
47 | | // NOTREADABLE READONEONLY NOTWRITABLE WRITEONEONLY |
48 | | unsigned int Flags() override |
49 | 6 | { |
50 | 6 | return READONEONLY | WRITEONEONLY; |
51 | 6 | } |
52 | | |
53 | | //*** This section identical for most OBMol conversions *** |
54 | | //////////////////////////////////////////////////// |
55 | | /// The "API" interface functions |
56 | | bool ReadMolecule(OBBase* pOb, OBConversion* pConv) override; |
57 | | bool WriteMolecule(OBBase* pOb, OBConversion* pConv) override; |
58 | | }; |
59 | | //*** |
60 | | |
61 | | //Make an instance of the format class |
62 | | BoxFormat theBoxFormat; |
63 | | |
64 | | ///////////////////////////////////////////////////////////////// |
65 | | bool BoxFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) |
66 | 0 | { |
67 | |
|
68 | 0 | OBMol* pmol = pOb->CastAndClear<OBMol>(); |
69 | 0 | if (pmol == nullptr) |
70 | 0 | return false; |
71 | | |
72 | | //Define some references so we can use the old parameter names |
73 | 0 | istream &ifs = *pConv->GetInStream(); |
74 | 0 | OBMol &mol = *pmol; |
75 | 0 | const char* title = pConv->GetTitle(); |
76 | |
|
77 | 0 | char buffer[BUFF_SIZE]; |
78 | 0 | vector<string> vs; |
79 | 0 | vector<string>::iterator i; |
80 | 0 | OBAtom atom; |
81 | |
|
82 | 0 | mol.BeginModify(); |
83 | |
|
84 | 0 | while (ifs.getline(buffer,BUFF_SIZE) && !EQn(buffer,"END",3)) |
85 | 0 | { |
86 | 0 | if (EQn(buffer,"ATOM",4)) |
87 | 0 | { |
88 | 0 | string sbuf = &buffer[6]; |
89 | | /* X, Y, Z */ |
90 | 0 | string x = sbuf.substr(24,8); |
91 | 0 | string y = sbuf.substr(32,8); |
92 | 0 | string z = sbuf.substr(40,8); |
93 | 0 | vector3 v(atof(x.c_str()),atof(y.c_str()),atof(z.c_str())); |
94 | 0 | atom.SetVector(v); |
95 | 0 | if (!mol.AddAtom(atom)) |
96 | 0 | return(false); |
97 | 0 | } |
98 | | |
99 | 0 | if (EQn(buffer,"CONECT",6)) |
100 | 0 | { |
101 | 0 | tokenize(vs,buffer); |
102 | 0 | if (!vs.empty() && vs.size() > 2) |
103 | 0 | for (i = vs.begin(),i+=2;i != vs.end();++i) |
104 | 0 | mol.AddBond(atoi(vs[1].c_str()),atoi((*i).c_str()),1); |
105 | 0 | } |
106 | 0 | } |
107 | | |
108 | 0 | mol.EndModify(); |
109 | 0 | mol.SetTitle(title); |
110 | 0 | return(true); |
111 | 0 | } |
112 | | |
113 | | //////////////////////////////////////////////////////////////// |
114 | | |
115 | | bool BoxFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) |
116 | 0 | { |
117 | 0 | OBMol* pmol = dynamic_cast<OBMol*>(pOb); |
118 | 0 | if (pmol == nullptr) |
119 | 0 | return false; |
120 | | |
121 | | //Define some references so we can use the old parameter names |
122 | 0 | ostream &ofs = *pConv->GetOutStream(); |
123 | 0 | OBMol &mol = *pmol; |
124 | | |
125 | | //margin hardwired in new framework. Also was in old fileformat |
126 | 0 | double margin=1.0; |
127 | |
|
128 | 0 | char buffer[BUFF_SIZE]; |
129 | 0 | vector3 vcenter,vmin,vmax,vmid,vdim; |
130 | |
|
131 | 0 | OBAtom *atom; |
132 | 0 | vector<OBAtom*>::iterator i; |
133 | 0 | vmax.Set(-10E10,-10E10,-10E10); |
134 | 0 | vmin.Set( 10E10, 10E10, 10E10); |
135 | |
|
136 | 0 | for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) |
137 | 0 | { |
138 | 0 | vcenter += atom->GetVector(); |
139 | 0 | if (atom->x() < vmin.x()) |
140 | 0 | vmin.SetX(atom->x()); |
141 | 0 | if (atom->y() < vmin.y()) |
142 | 0 | vmin.SetY(atom->y()); |
143 | 0 | if (atom->z() < vmin.z()) |
144 | 0 | vmin.SetZ(atom->z()); |
145 | |
|
146 | 0 | if (atom->x() > vmax.x()) |
147 | 0 | vmax.SetX(atom->x()); |
148 | 0 | if (atom->y() > vmax.y()) |
149 | 0 | vmax.SetY(atom->y()); |
150 | 0 | if (atom->z() > vmax.z()) |
151 | 0 | vmax.SetZ(atom->z()); |
152 | 0 | } |
153 | 0 | vcenter /= (double)mol.NumAtoms(); |
154 | |
|
155 | 0 | vector3 vmarg(margin,margin,margin); |
156 | 0 | vmin -= vmarg; |
157 | 0 | vmax += vmarg; |
158 | 0 | vdim = vmax - vmin; |
159 | 0 | vmid = vmin+vmax; |
160 | 0 | vmid /= 2.0; |
161 | |
|
162 | 0 | ofs << "HEADER CORNERS OF BOX" << endl; |
163 | 0 | snprintf(buffer, BUFF_SIZE, "REMARK CENTER (X Y Z) %10.3f %10.3f %10.3f", |
164 | 0 | vmid.x(),vmid.y(),vmid.z()); |
165 | 0 | ofs << buffer << endl; |
166 | 0 | snprintf(buffer, BUFF_SIZE, "REMARK DIMENSIONS (X Y Z) %10.3f %10.3f %10.3f", |
167 | 0 | vdim.x(),vdim.y(),vdim.z()); |
168 | 0 | ofs << buffer << endl; |
169 | 0 | vdim /= 2.0; |
170 | |
|
171 | 0 | vector3 vtmp; |
172 | 0 | int j; |
173 | 0 | for (j = 1;j <= 8;j++) |
174 | 0 | { |
175 | 0 | switch(j) |
176 | 0 | { |
177 | 0 | case 1: |
178 | 0 | vtmp = vmid-vdim; |
179 | 0 | break; |
180 | 0 | case 2: |
181 | 0 | vtmp.SetX(vmid.x()+vdim.x()); |
182 | 0 | break; |
183 | 0 | case 3: |
184 | 0 | vtmp.SetZ(vmid.z()+vdim.z()); |
185 | 0 | break; |
186 | 0 | case 4: |
187 | 0 | vtmp.SetX(vmid.x()-vdim.x()); |
188 | 0 | break; |
189 | 0 | case 5: |
190 | 0 | vtmp = vmid-vdim; |
191 | 0 | vtmp.SetY(vmid.y()+vdim.y()); |
192 | 0 | break; |
193 | 0 | case 6: |
194 | 0 | vtmp = vmid+vdim; |
195 | 0 | vtmp.SetZ(vmid.z()-vdim.z()); |
196 | 0 | break; |
197 | 0 | case 7: |
198 | 0 | vtmp = vmid+vdim; |
199 | 0 | break; |
200 | 0 | case 8: |
201 | 0 | vtmp.SetX(vmid.x()-vdim.x()); |
202 | 0 | break; |
203 | 0 | } |
204 | 0 | snprintf(buffer, BUFF_SIZE, "ATOM %d DUA BOX 1 %8.3f%8.3f%8.3f", |
205 | 0 | j,vtmp.x(),vtmp.y(),vtmp.z()); |
206 | 0 | ofs << buffer << endl; |
207 | 0 | } |
208 | | |
209 | 0 | ofs << "CONECT 1 2 4 5" << endl; |
210 | 0 | ofs << "CONECT 2 1 3 6" << endl; |
211 | 0 | ofs << "CONECT 3 2 4 7" << endl; |
212 | 0 | ofs << "CONECT 4 1 3 8" << endl; |
213 | 0 | ofs << "CONECT 5 1 6 8" << endl; |
214 | 0 | ofs << "CONECT 6 2 5 7" << endl; |
215 | 0 | ofs << "CONECT 7 3 6 8" << endl; |
216 | 0 | ofs << "CONECT 8 4 5 7" << endl; |
217 | |
|
218 | 0 | return(true); |
219 | 0 | } |
220 | | |
221 | | } //namespace OpenBabel |