ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/openbabel/oopseformat.cpp
Revision: 2440
Committed: Wed Nov 16 19:42:11 2005 UTC (18 years, 9 months ago) by tim
File size: 10955 byte(s)
Log Message:
adding openbabel

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 <set>
17
18 #include "mol.hpp"
19 #include "obconversion.hpp"
20 #include "obmolecformat.hpp"
21
22 #ifdef HAVE_SSTREAM
23 #include <sstream>
24 #else
25 #include <strstream>
26 #endif
27
28 using namespace std;
29 namespace OpenBabel
30 {
31
32 class OOPSEFormat : public OBMoleculeFormat
33 {
34 public:
35 //Register this format type ID
36 OOPSEFormat()
37 {
38 OBConversion::RegisterFormat("in", this, "chemical/x-in");
39 }
40
41 virtual const char* Description() //required
42 {
43 return
44 "oopse cartesian coordinates format\n";
45 };
46
47 virtual const char* SpecificationURL()
48 { return "";}; //optional
49
50 virtual const char* GetMIMEType()
51 { return "chemical/x-in"; };
52
53 virtual unsigned int Flags() { return WRITEONEONLY;}
54
55 //*** This section identical for most OBMol conversions ***
56 ////////////////////////////////////////////////////
57 /// The "API" interface functions
58 //virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv);
59 virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
60
61 private:
62 bool AreSameFragments(OBMol& mol, vector<int>& frag1, vector<int>& frag2);
63 void findAngles(OBMol& mol);
64 OBMol* createMolFromFragment(OBMol& mol, vector<int>& fragment);
65 void WriteMDFile(vector<OBMol*> mols, vector<int> numMols);
66 void WriteINFile(OBMol& mol, ostream& ofs, vector<int>& indices);
67 };
68
69
70 //Make an instance of the format class
71 OOPSEFormat theOOPSEFormat;
72
73 ////////////////////////////////////////////////////////////////
74
75 bool OOPSEFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
76 {
77 OBMol* pmol = dynamic_cast<OBMol*>(pOb);
78 if(pmol==NULL)
79 return false;
80
81 vector<vector<int> > fragmentLists;
82 pmol->ContigFragList(fragmentLists);
83 OBBitVec unused;
84 vector<bool> used(fragmentLists.size(), 0);
85 vector<vector<int> > molecules;
86 vector<int> indices;
87 for(int i =0; i < used.size(); ++i) {
88 if (used[i])
89 {
90 continue;
91 }
92 used[i] = true;
93 vector<int> sameMolTypes;
94 sameMolTypes.push_back(i);
95 indices.insert(indices.end(), fragmentLists[i].begin(), fragmentLists[i].end());
96 for (int j = i + 1;j < used.size(); ++j)
97 {
98 if (used[j])
99 {
100 continue;
101 }
102
103 if (AreSameFragments(*pmol, fragmentLists[i], fragmentLists[j]))
104 {
105 sameMolTypes.push_back(j);
106 indices.insert(indices.end(), fragmentLists[j].begin(), fragmentLists[j].end());
107 used[j]=true;
108 }
109 }
110 molecules.push_back(sameMolTypes);
111
112 }
113
114 //
115 vector<OBMol*> mdMols;
116 vector<int> numMols;
117 for(vector<vector<int> >::iterator i = molecules.begin(); i != molecules.end(); ++i)
118 {
119 mdMols.push_back(createMolFromFragment(*pmol, fragmentLists[i->front()]));
120 numMols.push_back((*i).size());
121 }
122
123 WriteMDFile(mdMols, numMols);
124
125 for(vector<OBMol*>::iterator i = mdMols.begin(); i != mdMols.end(); ++i)
126 {
127 delete *i;
128 }
129
130 //
131 WriteINFile(*pmol, *pConv->GetOutStream(), indices);
132
133
134
135 return(true);
136 }
137
138 bool OOPSEFormat::AreSameFragments(OBMol& mol, vector<int>& frag1, vector<int>& frag2)
139 {
140 if (frag1.size() != frag2.size())
141 {
142 return false;
143 }
144
145 //exact graph matching is a NP complete problem,
146 for (unsigned int i =0 ; i < frag1.size(); ++i)
147 {
148 if (strcmp(mol.GetAtom(frag1[i])->GetType(), mol.GetAtom(frag2[i])->GetType()) )
149 {
150 return false;
151 }
152 }
153 return true;
154 }
155
156 struct SameAngle
157 {
158 bool operator()(const triple<OBAtom*,OBAtom*,OBAtom*> t1, const triple<OBAtom*,OBAtom*,OBAtom*> t2) const
159 {
160 return (t1.second == t2.second) && ( (t1.first == t2.first && t1.third == t2.third) || (t1.first == t2.third && t1.third == t2.first));
161 }
162 };
163
164 void OOPSEFormat::findAngles(OBMol& mol)
165 {
166 /*
167 //if already has data return
168 if(mol.HasData(OBGenericDataType::AngleData))
169 return;
170
171 vector<OBEdgeBase*>::iterator bi1,bi2;
172 OBBond* bond;
173 OBAtom *a,*b,*c;
174
175 set<triple<OBAtom*,OBAtom*,OBAtom*>, SameAngle> uniqueAngles;
176 //loop through all bonds generating torsions
177 for(bond = mol.BeginBond(bi1);bond;bond = mol.NextBond(bi1))
178 {
179 b = bond->GetBeginAtom();
180 c = bond->GetEndAtom();
181 if(b->IsHydrogen())
182 continue;
183
184 for(a = b->BeginNbrAtom(bi2);a;a = b->NextNbrAtom(bi2))
185 {
186 if(a == c)
187 continue;
188
189 uniqueAngles.insert(triple<OBAtom*,OBAtom*,OBAtom*>(a, b, c));
190 }
191 }
192
193 //get new data and attach it to molecule
194 OBAngleData *angles = new OBAngleData;
195 mol.SetData(angles);
196 set<triple<OBAtom*,OBAtom*,OBAtom*>, SameAngle>::iterator i;
197
198 for (i = uniqueAngles.begin(); i != uniqueAngles.end(); ++i) {
199 OBAngle angle;
200 angle.SetAtoms(i->first, i->second, i->second);
201 angles->SetData(angle);
202 }
203 */
204 }
205 OBMol* OOPSEFormat::createMolFromFragment(OBMol& mol, vector<int>& fragment)
206 {
207 OBMol* newMol = new OBMol();
208 newMol->ReserveAtoms(fragment.size());
209 newMol->BeginModify();
210 for(vector<int>::iterator i = fragment.begin(); i != fragment.end(); ++i)
211 {
212 OBAtom* newAtom = newMol->NewAtom();
213 *newAtom = *mol.GetAtom(*i);
214 }
215 newMol->EndModify();
216 newMol->ConnectTheDots();
217 findAngles(*newMol);
218 newMol->FindTorsions();
219 return newMol;
220 }
221 void OOPSEFormat::WriteMDFile(vector<OBMol*> mols, vector<int> numMols)
222 {
223 std::string identLevel1("\t");
224 std::string identLevel2("\t\t");
225 std::string molPrefix("MolName");
226 ostream& ofs = std::cout;
227 const int BUFFLEN = 1024;
228 char buffer[BUFFLEN];
229
230 for(unsigned int i = 0; i < mols.size(); ++i)
231 {
232 OBMol* pmol = mols[i];
233 map<OBAtom*, int> atomMap;
234 ofs << "molecule {\n";
235 sprintf(buffer, "%d", i);
236 ofs << identLevel1 << "name = " << "\"" << molPrefix << buffer << "\"" << ";\n";
237
238
239 //atom
240 ofs << identLevel1 << "nAtoms = " << pmol->NumAtoms() << ";\n";
241 int ai = 0;
242 FOR_ATOMS_OF_MOL(atom, *pmol ) {
243 ofs << identLevel1 << "atom[" << ai << "] {\n";
244 ofs << identLevel2 << "type = " << "\"" << atom->GetType() << "\"" << ";\n";
245 ofs << identLevel2 << "position(" << atom->GetX() << ", " << atom->GetY() << ", " << atom->GetZ() << ");\n";
246 ofs << identLevel1 << "}\n";
247 atomMap[&(*atom)] = ai++;
248 }
249
250 //bond
251 ofs << identLevel1 << "nBonds = " << pmol->NumBonds() << ";\n";
252 int bi = 0;
253 FOR_BONDS_OF_MOL(bond, *pmol ) {
254 ofs << identLevel1 << "bond[" << bi++ << "] {\n";
255 ofs << identLevel2 << "member(" << atomMap[bond->GetBeginAtom()] << ", " << atomMap[bond->GetEndAtom()] << ");\n";
256 ofs << identLevel1 << "}\n";
257 }
258 /*
259 //bend
260 OBGenericData* pGenericData = pmol->GetData(OBGenericDataType::AngleData);
261 OBAngleData* pAngleData = dynamic_cast<OBAngleData*>(pGenericData);
262 vector<OBAngle> angles = pAngleData->GetData();
263
264 ofs << identLevel1 << "nBends = " << angles.size() << ";\n";
265 int bendIndex = 0;
266 for (vector<OBAngle>::iterator ti = angles.begin(); ti != angles.end(); ++ti)
267 {
268 triple<OBAtom*, OBAtom*, OBAtom*> bendAtoms = ti->getAtoms();
269 ofs << identLevel1 << "bend[" << bendIndex++ << "] {\n";
270 ofs << identLevel2 << "member(" << atomMap[bendAtoms.first] << ", " << atomMap[bendAtoms.second] << atomMap[bendAtoms.third] <<");\n";
271 ofs << identLevel1 << "}\n";
272 }
273
274 //torsion
275 pGenericData = pmol->GetData(OBGenericDataType::TorsionData);
276 OBTorsionData* pTorsionData = dynamic_cast<OBTorsionData*>(pGenericData);
277 vector<OBTorsion> torsions = pTorsionData->GetData();
278 vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> > torsionArray;
279 for (vector<OBTorsion>::iterator ti = torsions.begin(); ti != torsions.end(); ++ti)
280 {
281 vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> > tmpTorsions = ti->getTorsions();
282 torsionArray.insert(torsionArray.end(), tmpTorsions.begin(), tmpTorsions.end());
283 }
284
285 ofs << identLevel1 << "nTorsions = " << torsionArray.size() << ";\n";
286 int torsionIndex = 0;
287 for (vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> >::iterator ti = torsionArray.begin(); ti != torsionArray.end(); ++ti)
288 {
289 ofs << identLevel1 << "torsion[" << torsionIndex++ << "] {\n";
290 ofs << identLevel2 << "member(" << atomMap[ti->first] << ", " << atomMap[ti->second] <<", " << atomMap[ti->third] <<", " << atomMap[ti->forth] << ");\n";
291 ofs << identLevel1 << "}\n";
292 }
293 */
294 ofs << "}\n";
295 }
296
297 ofs << "nComponents = " << mols.size() << ";\n";
298
299 for(unsigned int i =0; i < mols.size(); ++i)
300 {
301 ofs << "component{\n";
302 sprintf(buffer, "%d", i);
303 ofs << "type = " << molPrefix << buffer << ";\n";
304 ofs << "nMol = " << numMols[i]<< ";\n";
305 ofs << "}\n";
306 }
307 }
308 void OOPSEFormat::WriteINFile(OBMol& mol, ostream& ofs, vector<int>& indices)
309 {
310 unsigned int i;
311 char buffer[BUFF_SIZE];
312
313 sprintf(buffer,"%d", mol.NumAtoms());
314 ofs << buffer << endl;
315 //sprintf(buffer,"0;%f, 0, 0; 0, %15.7f, 0; 0, 0, %15.7f;", boxx, boxy, boxz);
316 sprintf(buffer, "0;%f, 0, 0; 0, %15.7f, 0; 0, 0, %15.7f;", 100.0, 100.0, 100.0);
317 ofs << buffer << endl;
318
319 OBAtom *atom;
320 string str,str1;
321
322 for(vector<int>::iterator i = indices.begin();i != indices.end(); ++i)
323 {
324 atom = mol.GetAtom(*i);
325 sprintf(buffer,"%15s%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f",
326 atom->GetType(),
327 atom->GetX(), atom->GetY(), atom->GetZ(),
328 0.0, 0.0, 0.0,
329 0.0, 0.0, 0.0, 0.0,
330 0.0, 0.0, 0.0
331 );
332 ofs << buffer << endl;
333 }
334
335 }
336
337 } //namespace OpenBabel
338