ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/openbabel/oopseformat.cpp
Revision: 2469
Committed: Fri Dec 2 15:38:03 2005 UTC (18 years, 9 months ago) by tim
File size: 9888 byte(s)
Log Message:
End of the Link --> List
Return of the Oject-Oriented
replace yacc/lex parser with antlr parser

File Contents

# User Rev Content
1 tim 2440 /**********************************************************************
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 tim 2445 #include "oopseformat.hpp"
17 tim 2455 #include <fstream>
18 tim 2440 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 tim 2455 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);
83 tim 2440
84     for(vector<OBMol*>::iterator i = mdMols.begin(); i != mdMols.end(); ++i)
85     {
86     delete *i;
87     }
88    
89     //
90     WriteINFile(*pmol, *pConv->GetOutStream(), indices);
91    
92    
93    
94     return(true);
95     }
96    
97     bool OOPSEFormat::AreSameFragments(OBMol& mol, vector<int>& frag1, vector<int>& frag2)
98     {
99     if (frag1.size() != frag2.size())
100     {
101     return false;
102     }
103    
104 tim 2469 //exact graph matching is a NP complete problem
105     /** @todo using sparse matrix to store the connectivities*/
106 tim 2440 for (unsigned int i =0 ; i < frag1.size(); ++i)
107     {
108 tim 2469 OBAtom* atom1 = mol.GetAtom(frag1[i]);
109     OBAtom* atom2 = mol.GetAtom(frag2[i]);
110    
111     if (atom1->GetAtomicNum() != atom2->GetAtomicNum())
112 tim 2440 {
113     return false;
114     }
115     }
116     return true;
117     }
118    
119     struct SameAngle
120     {
121     bool operator()(const triple<OBAtom*,OBAtom*,OBAtom*> t1, const triple<OBAtom*,OBAtom*,OBAtom*> t2) const
122     {
123     return (t1.second == t2.second) && ( (t1.first == t2.first && t1.third == t2.third) || (t1.first == t2.third && t1.third == t2.first));
124     }
125     };
126    
127     void OOPSEFormat::findAngles(OBMol& mol)
128     {
129     /*
130     //if already has data return
131     if(mol.HasData(OBGenericDataType::AngleData))
132     return;
133    
134     vector<OBEdgeBase*>::iterator bi1,bi2;
135     OBBond* bond;
136     OBAtom *a,*b,*c;
137    
138     set<triple<OBAtom*,OBAtom*,OBAtom*>, SameAngle> uniqueAngles;
139     //loop through all bonds generating torsions
140     for(bond = mol.BeginBond(bi1);bond;bond = mol.NextBond(bi1))
141     {
142     b = bond->GetBeginAtom();
143     c = bond->GetEndAtom();
144     if(b->IsHydrogen())
145     continue;
146    
147     for(a = b->BeginNbrAtom(bi2);a;a = b->NextNbrAtom(bi2))
148     {
149     if(a == c)
150     continue;
151    
152     uniqueAngles.insert(triple<OBAtom*,OBAtom*,OBAtom*>(a, b, c));
153     }
154     }
155    
156     //get new data and attach it to molecule
157     OBAngleData *angles = new OBAngleData;
158     mol.SetData(angles);
159     set<triple<OBAtom*,OBAtom*,OBAtom*>, SameAngle>::iterator i;
160    
161     for (i = uniqueAngles.begin(); i != uniqueAngles.end(); ++i) {
162     OBAngle angle;
163     angle.SetAtoms(i->first, i->second, i->second);
164     angles->SetData(angle);
165     }
166     */
167     }
168     OBMol* OOPSEFormat::createMolFromFragment(OBMol& mol, vector<int>& fragment)
169     {
170     OBMol* newMol = new OBMol();
171     newMol->ReserveAtoms(fragment.size());
172     newMol->BeginModify();
173     for(vector<int>::iterator i = fragment.begin(); i != fragment.end(); ++i)
174     {
175     OBAtom* newAtom = newMol->NewAtom();
176     *newAtom = *mol.GetAtom(*i);
177     }
178     newMol->EndModify();
179     newMol->ConnectTheDots();
180     findAngles(*newMol);
181     newMol->FindTorsions();
182     return newMol;
183     }
184 tim 2455 void OOPSEFormat::WriteMDFile(vector<OBMol*> mols, vector<int> numMols, ostream& os)
185 tim 2440 {
186     std::string identLevel1("\t");
187     std::string identLevel2("\t\t");
188     std::string molPrefix("MolName");
189     const int BUFFLEN = 1024;
190     char buffer[BUFFLEN];
191    
192     for(unsigned int i = 0; i < mols.size(); ++i)
193     {
194     OBMol* pmol = mols[i];
195     map<OBAtom*, int> atomMap;
196 tim 2455 os << "molecule {\n";
197 tim 2440 sprintf(buffer, "%d", i);
198 tim 2455 os << identLevel1 << "name = " << "\"" << molPrefix << buffer << "\"" << ";\n";
199 tim 2440
200    
201     //atom
202     int ai = 0;
203     FOR_ATOMS_OF_MOL(atom, *pmol ) {
204 tim 2455 os << identLevel1 << "atom[" << ai << "] {\n";
205 tim 2469 os << identLevel2 << "type = " << "\"" << etab.GetSymbol(atom->GetAtomicNum()) << "\"" << ";\n";
206 tim 2455 os << identLevel1 << "}\n";
207 tim 2440 atomMap[&(*atom)] = ai++;
208     }
209 tim 2458 os << "\n";
210 tim 2440
211     //bond
212     FOR_BONDS_OF_MOL(bond, *pmol ) {
213 tim 2455 os << identLevel1 << "bond {\n";
214     os << identLevel2 << "members(" << atomMap[bond->GetBeginAtom()] << ", " << atomMap[bond->GetEndAtom()] << ");\n";
215     os << identLevel1 << "}\n";
216 tim 2440 }
217     /*
218     //bend
219     OBGenericData* pGenericData = pmol->GetData(OBGenericDataType::AngleData);
220     OBAngleData* pAngleData = dynamic_cast<OBAngleData*>(pGenericData);
221     vector<OBAngle> angles = pAngleData->GetData();
222    
223 tim 2455 os << identLevel1 << "nBends = " << angles.size() << ";\n";
224 tim 2440 int bendIndex = 0;
225     for (vector<OBAngle>::iterator ti = angles.begin(); ti != angles.end(); ++ti)
226     {
227     triple<OBAtom*, OBAtom*, OBAtom*> bendAtoms = ti->getAtoms();
228 tim 2455 os << identLevel1 << "bend[" << bendIndex++ << "] {\n";
229     os << identLevel2 << "member(" << atomMap[bendAtoms.first] << ", " << atomMap[bendAtoms.second] << atomMap[bendAtoms.third] <<");\n";
230     os << identLevel1 << "}\n";
231 tim 2440 }
232    
233     //torsion
234     pGenericData = pmol->GetData(OBGenericDataType::TorsionData);
235     OBTorsionData* pTorsionData = dynamic_cast<OBTorsionData*>(pGenericData);
236     vector<OBTorsion> torsions = pTorsionData->GetData();
237     vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> > torsionArray;
238     for (vector<OBTorsion>::iterator ti = torsions.begin(); ti != torsions.end(); ++ti)
239     {
240     vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> > tmpTorsions = ti->getTorsions();
241     torsionArray.insert(torsionArray.end(), tmpTorsions.begin(), tmpTorsions.end());
242     }
243    
244 tim 2455 os << identLevel1 << "nTorsions = " << torsionArray.size() << ";\n";
245 tim 2440 int torsionIndex = 0;
246     for (vector<quad<OBAtom*,OBAtom*,OBAtom*,OBAtom*> >::iterator ti = torsionArray.begin(); ti != torsionArray.end(); ++ti)
247     {
248 tim 2455 os << identLevel1 << "torsion[" << torsionIndex++ << "] {\n";
249     os << identLevel2 << "member(" << atomMap[ti->first] << ", " << atomMap[ti->second] <<", " << atomMap[ti->third] <<", " << atomMap[ti->forth] << ");\n";
250     os << identLevel1 << "}\n";
251 tim 2440 }
252     */
253 tim 2455 os << "}\n";
254 tim 2458 os << "\n";
255    
256 tim 2440 }
257    
258 tim 2458 os << "\n";
259 tim 2455 os << "nComponents = " << mols.size() << ";\n";
260 tim 2440
261     for(unsigned int i =0; i < mols.size(); ++i)
262     {
263 tim 2455 os << "component{\n";
264 tim 2440 sprintf(buffer, "%d", i);
265 tim 2455 os << "type = " << molPrefix << buffer << ";\n";
266     os << "nMol = " << numMols[i]<< ";\n";
267     os << "}\n";
268 tim 2440 }
269     }
270     void OOPSEFormat::WriteINFile(OBMol& mol, ostream& ofs, vector<int>& indices)
271     {
272     unsigned int i;
273     char buffer[BUFF_SIZE];
274    
275     sprintf(buffer,"%d", mol.NumAtoms());
276     ofs << buffer << endl;
277     //sprintf(buffer,"0;%f, 0, 0; 0, %15.7f, 0; 0, 0, %15.7f;", boxx, boxy, boxz);
278     sprintf(buffer, "0;%f, 0, 0; 0, %15.7f, 0; 0, 0, %15.7f;", 100.0, 100.0, 100.0);
279     ofs << buffer << endl;
280    
281     OBAtom *atom;
282     string str,str1;
283    
284     for(vector<int>::iterator i = indices.begin();i != indices.end(); ++i)
285     {
286     atom = mol.GetAtom(*i);
287 tim 2469 sprintf(buffer,"%-10s%-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",
288     etab.GetSymbol(atom->GetAtomicNum()),
289 tim 2440 atom->GetX(), atom->GetY(), atom->GetZ(),
290     0.0, 0.0, 0.0,
291     0.0, 0.0, 0.0, 0.0,
292     0.0, 0.0, 0.0
293     );
294     ofs << buffer << endl;
295     }
296    
297     }
298    
299     } //namespace OpenBabel
300