ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/openbabel/oopseformat.cpp
Revision: 3056
Committed: Thu Oct 19 19:51:34 2006 UTC (18 years, 6 months ago) by gezelter
File size: 10226 byte(s)
Log Message:
Slight changes to oopseformat to allow importing of openbabel's
perceived atom types into OOPSE md files

File Contents

# Content
1 /**********************************************************************
2 Copyright (C) 2000 by OpenEye Scientific Software, Inc.
3 Some portions Copyright (C) 2001-2005 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
16 #include "oopseformat.hpp"
17 #include <fstream>
18 namespace OpenBabel
19 {
20
21 bool OOPSEFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
22 {
23 OBMol* pmol = dynamic_cast<OBMol*>(pOb);
24 if(pmol==NULL)
25 return false;
26
27 vector<vector<int> > fragmentLists;
28 pmol->ContigFragList(fragmentLists);
29 OBBitVec unused;
30 vector<bool> used(fragmentLists.size(), 0);
31 vector<vector<int> > molecules;
32 vector<int> indices;
33 for(int i =0; i < used.size(); ++i) {
34 if (used[i])
35 {
36 continue;
37 }
38 used[i] = true;
39 vector<int> sameMolTypes;
40 sameMolTypes.push_back(i);
41 indices.insert(indices.end(), fragmentLists[i].begin(), fragmentLists[i].end());
42 for (int j = i + 1;j < used.size(); ++j)
43 {
44 if (used[j])
45 {
46 continue;
47 }
48
49 if (AreSameFragments(*pmol, fragmentLists[i], fragmentLists[j]))
50 {
51 sameMolTypes.push_back(j);
52 indices.insert(indices.end(), fragmentLists[j].begin(), fragmentLists[j].end());
53 used[j]=true;
54 }
55 }
56 molecules.push_back(sameMolTypes);
57
58 }
59
60 //
61 vector<OBMol*> mdMols;
62 vector<int> numMols;
63 for(vector<vector<int> >::iterator i = molecules.begin(); i != molecules.end(); ++i)
64 {
65 mdMols.push_back(createMolFromFragment(*pmol, fragmentLists[i->front()]));
66 numMols.push_back((*i).size());
67 }
68
69 string OutputFileName = pConv->GetInFilename();
70 unsigned int pos = OutputFileName.rfind(".");
71 if(pos==string::npos)
72 OutputFileName += ".md";
73 else
74 OutputFileName = OutputFileName.substr(0, pos) + ".md";
75 ofstream ofs(OutputFileName.c_str());
76 if(!ofs)
77 {
78 cerr << "Cannot write to " << OutputFileName <<endl;
79 return false;
80 }
81
82 WriteMDFile(mdMols, numMols, ofs, *pmol, indices);
83
84 for(vector<OBMol*>::iterator i = mdMols.begin(); i != mdMols.end(); ++i)
85 {
86 delete *i;
87 }
88
89 //
90
91 return(true);
92 }
93
94 bool OOPSEFormat::AreSameFragments(OBMol& mol, vector<int>& frag1, vector<int>& frag2)
95 {
96 if (frag1.size() != frag2.size())
97 {
98 return false;
99 }
100
101 //exact graph matching is a NP complete problem
102 /** @todo using sparse matrix to store the connectivities*/
103 for (unsigned int i =0 ; i < frag1.size(); ++i)
104 {
105 OBAtom* atom1 = mol.GetAtom(frag1[i]);
106 OBAtom* atom2 = mol.GetAtom(frag2[i]);
107
108 if (atom1->GetAtomicNum() != atom2->GetAtomicNum())
109 {
110 return false;
111 }
112 }
113 return true;
114 }
115
116 struct SameAngle
117 {
118 bool operator()(const triple<OBAtom*,OBAtom*,OBAtom*> t1, const triple<OBAtom*,OBAtom*,OBAtom*> t2) const
119 {
120 return (t1.second == t2.second) && ( (t1.first == t2.first && t1.third == t2.third) || (t1.first == t2.third && t1.third == t2.first));
121 }
122 };
123
124 void OOPSEFormat::findAngles(OBMol& mol) {
125 /*
126 //if already has data return
127 if(mol.HasData(OBGenericDataType::AngleData))
128 return;
129
130 vector<OBEdgeBase*>::iterator bi1,bi2;
131 OBBond* bond;
132 OBAtom *a,*b,*c;
133
134 set<triple<OBAtom*,OBAtom*,OBAtom*>, SameAngle> uniqueAngles;
135 //loop through all bonds generating torsions
136 for(bond = mol.BeginBond(bi1);bond;bond = mol.NextBond(bi1))
137 {
138 b = bond->GetBeginAtom();
139 c = bond->GetEndAtom();
140 if(b->IsHydrogen())
141 continue;
142
143 for(a = b->BeginNbrAtom(bi2);a;a = b->NextNbrAtom(bi2))
144 {
145 if(a == c)
146 continue;
147
148 uniqueAngles.insert(triple<OBAtom*,OBAtom*,OBAtom*>(a, b, c));
149 }
150 }
151
152 //get new data and attach it to molecule
153 OBAngleData *angles = new OBAngleData;
154 mol.SetData(angles);
155 set<triple<OBAtom*,OBAtom*,OBAtom*>, SameAngle>::iterator i;
156
157 for (i = uniqueAngles.begin(); i != uniqueAngles.end(); ++i) {
158 OBAngle angle;
159 angle.SetAtoms(i->first, i->second, i->second);
160 angles->SetData(angle);
161 }
162 */
163 }
164
165 OBMol* OOPSEFormat::createMolFromFragment(OBMol& mol, vector<int>& fragment) {
166
167 OBMol* newMol = new OBMol();
168 newMol->ReserveAtoms(fragment.size());
169 newMol->BeginModify();
170 for(vector<int>::iterator i = fragment.begin(); i != fragment.end(); ++i) {
171 OBAtom* newAtom = newMol->NewAtom();
172 *newAtom = *mol.GetAtom(*i);
173 }
174 newMol->EndModify();
175 newMol->ConnectTheDots();
176 findAngles(*newMol);
177 newMol->FindTorsions();
178 return newMol;
179 }
180
181 void OOPSEFormat::WriteMDFile(vector<OBMol*> mols, vector<int> numMols, ostream& os, OBMol& mol, vector<int>& indices) {
182 std::string indentLevel1(" ");
183 std::string indentLevel2(" ");
184 std::string molPrefix("MolName");
185 unsigned int i;
186 const int BUFFLEN = 1024;
187 char buffer[BUFFLEN];
188 string str, str1;
189
190
191 os << "<OOPSE version=4>" << endl;
192 os << " <MetaData>" << endl << endl;
193
194 for(i = 0; i < mols.size(); ++i) {
195 OBMol* pmol = mols[i];
196
197 pmol->ConnectTheDots();
198 pmol->PerceiveBondOrders();
199 //pmol->FindSSSR();
200 //pmol->SetAromaticPerceived();
201 //pmol->Kekulize();
202
203 map<OBAtom*, int> atomMap;
204 os << "molecule {\n";
205 sprintf(buffer, "%d", i);
206 os << indentLevel1 << "name = " << "\"" << molPrefix << buffer << "\"" << ";\n";
207
208 //atom
209 int ai = 0;
210 FOR_ATOMS_OF_MOL(atom, *pmol ) {
211 str = atom->GetType();
212 ttab.SetFromType("INT");
213 ttab.SetToType("INT");
214 ttab.Translate(str1,str);
215 os << indentLevel1 << "atom[" << ai << "] {\n";
216 // os << indentLevel2 << "type = " << "\"" << etab.GetSymbol(atom->GetAtomicNum()) << "\"" << ";\n";
217 os << indentLevel2 << "type = " << "\"" << str1 << "\"" << ";\n";
218 os << indentLevel1 << "}\n";
219 atomMap[&(*atom)] = ai++;
220 }
221 os << "\n";
222
223 //bond
224 FOR_BONDS_OF_MOL(bond, *pmol ) {
225 os << indentLevel1 << "bond {\n";
226 os << indentLevel2 << "members(" << atomMap[bond->GetBeginAtom()] << ", " << atomMap[bond->GetEndAtom()] << ");\n";
227 os << indentLevel1 << "}\n";
228 }
229 /*
230 //bend
231 OBGenericData* pGenericData = pmol->GetData(OBGenericDataType::AngleData);
232 OBAngleData* pAngleData = dynamic_cast<OBAngleData*>(pGenericData);
233 vector<OBAngle> angles = pAngleData->GetData();
234
235 os << indentLevel1 << "nBends = " << angles.size() << ";\n";
236 int bendIndex = 0;
237 for (vector<OBAngle>::iterator ti = angles.begin(); ti != angles.end(); ++ti)
238 {
239 triple<OBAtom*, OBAtom*, OBAtom*> bendAtoms = ti->getAtoms();
240 os << indentLevel1 << "bend[" << bendIndex++ << "] {\n";
241 os << indentLevel2 << "member(" << atomMap[bendAtoms.first] << ", " << atomMap[bendAtoms.second] << atomMap[bendAtoms.third] <<");\n";
242 os << indentLevel1 << "}\n";
243 }
244
245 //torsion
246 pGenericData = pmol->GetData(OBGenericDataType::TorsionData);
247 OBTorsionData* pTorsionData = dynamic_cast<OBTorsionData*>(pGenericData);
248 vector<OBTorsion> torsions = pTorsionData->GetData();
249 vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> > torsionArray;
250 for (vector<OBTorsion>::iterator ti = torsions.begin(); ti != torsions.end(); ++ti)
251 {
252 vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> > tmpTorsions = ti->getTorsions();
253 torsionArray.insert(torsionArray.end(), tmpTorsions.begin(), tmpTorsions.end());
254 }
255
256 os << indentLevel1 << "nTorsions = " << torsionArray.size() << ";\n";
257 int torsionIndex = 0;
258 for (vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> >::iterator ti = torsionArray.begin(); ti != torsionArray.end(); ++ti)
259 {
260 os << indentLevel1 << "torsion[" << torsionIndex++ << "] {\n";
261 os << indentLevel2 << "member(" << atomMap[ti->first] << ", " << atomMap[ti->second] <<", " << atomMap[ti->third] <<", " << atomMap[ti->forth] << ");\n";
262 os << indentLevel1 << "}\n";
263 }
264 */
265 os << "}" << endl;
266 os << endl;
267
268 }
269
270 os << endl;
271
272
273 for(i=0; i < mols.size(); ++i) {
274 os << "component{" << endl;
275 sprintf(buffer, "%d", i);
276 os << indentLevel1 << "type = " << molPrefix << buffer << ";" << endl;
277 os << indentLevel1 << "nMol = " << numMols[i]<< ";" << endl;
278 os << "}" << endl;
279 }
280
281 os << " </MetaData>" << endl;
282 os << " <Snapshot>" << endl;
283 os << " <FrameData>" << endl;
284
285 sprintf(buffer, " Time: %.10g", 0.0);
286
287 os << buffer << endl;
288
289 sprintf(buffer, " Hmat: {{ %.10g, %.10g, %.10g }, { %.10g, %.10g, %.10g }, { %.10g, %.10g, %.10g }}", 100.0, 0.0, 0.0, 0.0, 100.0, 0.0, 0.0, 0.0, 100.0);
290
291 os << buffer << endl;
292 os << " </FrameData>" << endl;
293 os << " <StuntDoubles>" << endl;
294
295 OBAtom *atom;
296
297 for(vector<int>::iterator i = indices.begin();i != indices.end(); ++i) {
298 atom = mol.GetAtom(*i);
299 sprintf(buffer, "%10d %7s %18.10g %18.10g %18.10g %13e %13e %13e", *i - 1, "pv", atom->GetX(), atom->GetY(), atom->GetZ(), 0.0, 0.0, 0.0);
300 os << buffer << endl;
301 }
302 os << " </StuntDoubles>" << endl;
303 os << " </Snapshot>" << endl;
304 os << "</OOPSE>" << endl;
305 }
306
307 } //namespace OpenBabel
308