ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/openbabel/data.cpp
Revision: 3057
Committed: Thu Oct 19 20:49:05 2006 UTC (17 years, 11 months ago) by gezelter
File size: 22207 byte(s)
Log Message:
updated OpenBabel to version 2.0.2

File Contents

# User Rev Content
1 tim 2440 /**********************************************************************
2     data.cpp - Global data and resource file parsers.
3    
4     Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
5 gezelter 3057 Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison
6 tim 2440
7     This file is part of the Open Babel project.
8     For more information, see <http://openbabel.sourceforge.net/>
9    
10     This program is free software; you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation version 2 of the License.
13    
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17     GNU General Public License for more details.
18     ***********************************************************************/
19    
20     #ifdef WIN32
21     #pragma warning (disable : 4786)
22     #endif
23    
24 gezelter 2450 #include "config.h"
25 tim 2440 #include "data.hpp"
26     #include "mol.hpp"
27    
28     // data headers
29     #include "element.hpp"
30     #include "types.hpp"
31     #include "isotope.hpp"
32     #include "resdata.hpp"
33    
34    
35     #if !HAVE_STRNCASECMP
36     extern "C" int strncasecmp(const char *s1, const char *s2, size_t n);
37     #endif
38    
39     using namespace std;
40    
41     namespace OpenBabel
42     {
43    
44 gezelter 3057 OBElementTable etab;
45     OBTypeTable ttab;
46     OBIsotopeTable isotab;
47     OBResidueData resdat;
48 tim 2440
49 gezelter 3057 /** \class OBElementTable
50     \brief Periodic Table of the Elements
51 tim 2440
52 gezelter 3057 Translating element data is a common task given that many file
53     formats give either element symbol or atomic number information, but
54     not both. The OBElementTable class facilitates conversion between
55     textual and numeric element information. An instance of the
56     OBElementTable class (etab) is declared as external in data.cpp. Source
57     files that include the header file mol.h automatically have an extern
58     definition to etab. The following code sample demonstrates the use
59     of the OBElementTable class:
60     \code
61     cout << "The symbol for element 6 is " << etab.GetSymbol(6) << endl;
62     cout << "The atomic number for Sulfur is " << etab.GetAtomicNum(16) << endl;
63     cout << "The van der Waal radius for Nitrogen is " << etab.GetVdwRad(7);
64     \endcode
65 tim 2440
66 gezelter 3057 Stored information in the OBElementTable includes elemental:
67     - symbols
68     - covalent radii
69     - van der Waal radii
70     - expected maximum bonding valence
71     - molar mass (by IUPAC recommended atomic masses)
72     - electronegativity
73     - ionization potential
74     - electron affinity
75     - RGB colors for visualization programs
76     - names (by IUPAC recommendation)
77     */
78 tim 2440
79 gezelter 3057 OBElementTable::OBElementTable()
80     {
81 tim 2440 _init = false;
82 gezelter 3057 STR_DEFINE(_dir, FRC_PATH );
83 gezelter 2450 _envvar = "FORCE_PARAM_PATH";
84 tim 2440 _filename = "element.txt";
85     _subdir = "data";
86     _dataptr = ElementData;
87 gezelter 3057 }
88 tim 2440
89 gezelter 3057 OBElementTable::~OBElementTable()
90     {
91 tim 2440 vector<OBElement*>::iterator i;
92     for (i = _element.begin();i != _element.end();i++)
93 gezelter 3057 delete *i;
94     }
95 tim 2440
96 gezelter 3057 void OBElementTable::ParseLine(const char *buffer)
97     {
98 tim 2440 int num,maxbonds;
99     char symbol[5];
100 gezelter 3057 char name[256];
101 tim 2440 double Rcov,Rvdw,mass, elNeg, ionize, elAffin;
102     double red, green, blue;
103    
104     if (buffer[0] != '#') // skip comment line (at the top)
105 gezelter 3057 {
106     sscanf(buffer,"%d %5s %lf %*f %lf %d %lf %lf %lf %lf %lf %lf %lf %255s",
107     &num,
108     symbol,
109     &Rcov,
110     &Rvdw,
111     &maxbonds,
112     &mass,
113     &elNeg,
114     &ionize,
115     &elAffin,
116     &red,
117     &green,
118     &blue,
119     name);
120 tim 2440
121 gezelter 3057 OBElement *ele = new OBElement(num,symbol,Rcov,Rvdw,maxbonds,mass,elNeg,
122     ionize, elAffin, red, green, blue, name);
123     _element.push_back(ele);
124     }
125     }
126 tim 2440
127 gezelter 3057 unsigned int OBElementTable::GetNumberOfElements()
128     {
129 tim 2440 if (!_init)
130 gezelter 3057 Init();
131 tim 2440
132     return _element.size();
133 gezelter 3057 }
134 tim 2440
135 gezelter 3057 char *OBElementTable::GetSymbol(int atomicnum)
136     {
137 tim 2440 if (!_init)
138 gezelter 3057 Init();
139 tim 2440
140     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
141 gezelter 3057 return("\0");
142 tim 2440
143     return(_element[atomicnum]->GetSymbol());
144 gezelter 3057 }
145 tim 2440
146 gezelter 3057 int OBElementTable::GetMaxBonds(int atomicnum)
147     {
148 tim 2440 if (!_init)
149 gezelter 3057 Init();
150 tim 2440
151     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
152 gezelter 3057 return(0);
153 tim 2440
154     return(_element[atomicnum]->GetMaxBonds());
155 gezelter 3057 }
156 tim 2440
157 gezelter 3057 double OBElementTable::GetElectroNeg(int atomicnum)
158     {
159 tim 2440 if (!_init)
160 gezelter 3057 Init();
161 tim 2440
162     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
163 gezelter 3057 return(0.0);
164 tim 2440
165     return(_element[atomicnum]->GetElectroNeg());
166 gezelter 3057 }
167 tim 2440
168 gezelter 3057 double OBElementTable::GetIonization(int atomicnum)
169     {
170 tim 2440 if (!_init)
171 gezelter 3057 Init();
172 tim 2440
173     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
174 gezelter 3057 return(0.0);
175 tim 2440
176     return(_element[atomicnum]->GetIonization());
177 gezelter 3057 }
178 tim 2440
179    
180 gezelter 3057 double OBElementTable::GetElectronAffinity(int atomicnum)
181     {
182 tim 2440 if (!_init)
183 gezelter 3057 Init();
184 tim 2440
185     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
186 gezelter 3057 return(0.0);
187 tim 2440
188     return(_element[atomicnum]->GetElectronAffinity());
189 gezelter 3057 }
190 tim 2440
191 gezelter 3057 vector<double> OBElementTable::GetRGB(int atomicnum)
192     {
193 tim 2440 if (!_init)
194 gezelter 3057 Init();
195 tim 2440
196     vector <double> colors;
197     colors.reserve(3);
198    
199     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
200     {
201 gezelter 3057 colors.push_back(0.0f);
202     colors.push_back(0.0f);
203     colors.push_back(0.0f);
204 tim 2440 return(colors);
205     }
206    
207     colors.push_back(_element[atomicnum]->GetRed());
208     colors.push_back(_element[atomicnum]->GetGreen());
209     colors.push_back(_element[atomicnum]->GetBlue());
210    
211     return (colors);
212 gezelter 3057 }
213 tim 2440
214 gezelter 3057 string OBElementTable::GetName(int atomicnum)
215     {
216 tim 2440 if (!_init)
217 gezelter 3057 Init();
218 tim 2440
219     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
220 gezelter 3057 return("Unknown");
221 tim 2440
222     return(_element[atomicnum]->GetName());
223 gezelter 3057 }
224 tim 2440
225 gezelter 3057 double OBElementTable::GetVdwRad(int atomicnum)
226     {
227 tim 2440 if (!_init)
228 gezelter 3057 Init();
229 tim 2440
230     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
231 gezelter 3057 return(0.0);
232 tim 2440
233     return(_element[atomicnum]->GetVdwRad());
234 gezelter 3057 }
235 tim 2440
236 gezelter 3057 double OBElementTable::CorrectedBondRad(int atomicnum, int hyb)
237     {
238 tim 2440 double rad;
239     if (!_init)
240 gezelter 3057 Init();
241 tim 2440
242     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
243 gezelter 3057 return(1.0);
244 tim 2440
245     rad = _element[atomicnum]->GetCovalentRad();
246    
247     if (hyb == 2)
248 gezelter 3057 rad *= 0.95;
249 tim 2440 else if (hyb == 1)
250 gezelter 3057 rad *= 0.90;
251 tim 2440
252     return(rad);
253 gezelter 3057 }
254 tim 2440
255 gezelter 3057 double OBElementTable::CorrectedVdwRad(int atomicnum, int hyb)
256     {
257 tim 2440 double rad;
258     if (!_init)
259 gezelter 3057 Init();
260 tim 2440
261     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
262 gezelter 3057 return(1.95);
263 tim 2440
264     rad = _element[atomicnum]->GetVdwRad();
265    
266     if (hyb == 2)
267 gezelter 3057 rad *= 0.95;
268 tim 2440 else if (hyb == 1)
269 gezelter 3057 rad *= 0.90;
270 tim 2440
271     return(rad);
272 gezelter 3057 }
273 tim 2440
274 gezelter 3057 double OBElementTable::GetCovalentRad(int atomicnum)
275     {
276 tim 2440 if (!_init)
277 gezelter 3057 Init();
278 tim 2440
279     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
280 gezelter 3057 return(0.0);
281 tim 2440
282     return(_element[atomicnum]->GetCovalentRad());
283 gezelter 3057 }
284 tim 2440
285 gezelter 3057 double OBElementTable::GetMass(int atomicnum)
286     {
287 tim 2440 if (!_init)
288 gezelter 3057 Init();
289 tim 2440
290     if (atomicnum < 0 || atomicnum > static_cast<int>(_element.size()))
291 gezelter 3057 return(0.0);
292 tim 2440
293     return(_element[atomicnum]->GetMass());
294 gezelter 3057 }
295 tim 2440
296 gezelter 3057 int OBElementTable::GetAtomicNum(const char *sym)
297     {
298     int temp;
299     return GetAtomicNum(sym, temp);
300     }
301 tim 2440
302 gezelter 3057 int OBElementTable::GetAtomicNum(const char *sym, int &iso)
303     {
304 tim 2440 if (!_init)
305 gezelter 3057 Init();
306 tim 2440
307     vector<OBElement*>::iterator i;
308     for (i = _element.begin();i != _element.end();i++)
309 gezelter 3057 if (!strncasecmp(sym,(*i)->GetSymbol(),2))
310     return((*i)->GetAtomicNum());
311 tim 2440 if (strcasecmp(sym, "D") == 0)
312 gezelter 3057 {
313 tim 2440 iso = 2;
314     return(1);
315 gezelter 3057 }
316 tim 2440 else if (strcasecmp(sym, "T") == 0)
317 gezelter 3057 {
318 tim 2440 iso = 3;
319     return(1);
320 gezelter 3057 }
321     else
322     iso = 0;
323 tim 2440 return(0);
324 gezelter 3057 }
325 tim 2440
326 gezelter 3057 /** \class OBIsotopeTable
327     \brief Table of atomic isotope masses
328 tim 2440
329 gezelter 3057 */
330 tim 2440
331 gezelter 3057 OBIsotopeTable::OBIsotopeTable()
332     {
333 tim 2440 _init = false;
334 gezelter 3057 STR_DEFINE(_dir, FRC_PATH );
335 gezelter 2450 _envvar = "FORCE_PARAM_PATH";
336 tim 2440 _filename = "isotope.txt";
337     _subdir = "data";
338     _dataptr = IsotopeData;
339 gezelter 3057 }
340 tim 2440
341 gezelter 3057 void OBIsotopeTable::ParseLine(const char *buffer)
342     {
343 tim 2440 unsigned int atomicNum;
344     unsigned int i;
345     vector<string> vs;
346    
347     pair <unsigned int, double> entry;
348     vector <pair <unsigned int, double> > row;
349    
350     if (buffer[0] != '#') // skip comment line (at the top)
351 gezelter 3057 {
352 tim 2440 tokenize(vs,buffer);
353     if (vs.size() > 3) // atomic number, 0, most abundant mass (...)
354 gezelter 3057 {
355 tim 2440 atomicNum = atoi(vs[0].c_str());
356     for (i = 1; i < vs.size() - 1; i += 2) // make sure i+1 still exists
357 gezelter 3057 {
358 tim 2440 entry.first = atoi(vs[i].c_str()); // isotope
359     entry.second = atof(vs[i + 1].c_str()); // exact mass
360     row.push_back(entry);
361 gezelter 3057 }
362 tim 2440 _isotopes.push_back(row);
363 gezelter 3057 }
364     else
365     obErrorLog.ThrowError(__func__, " Could not parse line in isotope table isotope.txt", obInfo);
366     }
367     }
368 tim 2440
369 gezelter 3057 double OBIsotopeTable::GetExactMass(const unsigned int ele,
370     const unsigned int isotope)
371     {
372 tim 2440 if (!_init)
373 gezelter 3057 Init();
374 tim 2440
375     if (ele > _isotopes.size())
376 gezelter 3057 return 0.0;
377 tim 2440
378     unsigned int iso;
379     for (iso = 0; iso < _isotopes[ele].size(); iso++)
380 gezelter 3057 if (isotope == _isotopes[ele][iso].first)
381     return _isotopes[ele][iso].second;
382 tim 2440
383     return 0.0;
384 gezelter 3057 }
385 tim 2440
386 gezelter 3057 /** \class OBTypeTable
387     \brief Atom Type Translation Table
388 tim 2440
389 gezelter 3057 Molecular file formats frequently store information about atoms in an
390     atom type field. Some formats store only the element for each atom,
391     while others include hybridization and local environments, such as the
392     Sybyl mol2 atom type field. The OBTypeTable class acts as a translation
393     table to convert atom types between a number of different molecular
394     file formats. The constructor for OBTypeTable automatically reads the
395     text file types.txt. Just as OBElementTable, an instance of
396     OBTypeTable (ttab) is declared external in data.cpp and is referenced as
397     extern OBTypeTable ttab in mol.h. The following code demonstrates how
398     to use the OBTypeTable class to translate the internal representation
399     of atom types in an OBMol Internal to Sybyl Mol2 atom types.
400 tim 2440
401 gezelter 3057 \code
402     ttab.SetFromType("INT");
403     ttab.SetToType("SYB");
404     OBAtom *atom;
405     vector<OBAtom*>::iterator i;
406     string src,dst;
407     for (atom = mol.BeginAtom(i);atom;atom = mol.EndAtom(i))
408     {
409     src = atom->GetType();
410     ttab.Translate(dst,src);
411     cout << "atom number " << atom->GetIdx() << "has mol2 type " << dst << endl;
412     }
413     \endcode
414 tim 2440
415 gezelter 3057 Current atom types include (defined in the top line of the data file types.txt):
416     - INT (Open Babel internal codes)
417     - ATN (atomic numbers)
418     - HYB (hybridization)
419     - MMD
420     - MM2 (MM2 force field)
421     - XYZ (element symbols from XYZ file format)
422     - ALC (Alchemy file)
423     - HAD
424     - MCML
425     - C3D (Chem3D)
426     - SYB (Sybyl mol2)
427     - MOL
428     - MAP
429     - DRE
430     - XED (XED format)
431     - DOK (Dock)
432     - M3D
433     */
434 tim 2440
435 gezelter 3057 OBTypeTable::OBTypeTable()
436     {
437 tim 2440 _init = false;
438 gezelter 3057 STR_DEFINE(_dir, FRC_PATH );
439 gezelter 2450 _envvar = "FORCE_PARAM_PATH";
440 tim 2440 _filename = "types.txt";
441     _subdir = "data";
442     _dataptr = TypesData;
443     _linecount = 0;
444     _from = _to = -1;
445 gezelter 3057 }
446 tim 2440
447 gezelter 3057 void OBTypeTable::ParseLine(const char *buffer)
448     {
449 tim 2440 if (buffer[0] == '#')
450 gezelter 3057 return; // just a comment line
451 tim 2440
452     if (_linecount == 0)
453 gezelter 3057 sscanf(buffer,"%d%d",&_nrows,&_ncols);
454 tim 2440 else if (_linecount == 1)
455 gezelter 3057 tokenize(_colnames,buffer);
456 tim 2440 else
457 gezelter 3057 {
458 tim 2440 vector<string> vc;
459     tokenize(vc,buffer);
460     if (vc.size() == (unsigned)_ncols)
461 gezelter 3057 _table.push_back(vc);
462     else
463     {
464     stringstream errorMsg;
465     errorMsg << " Could not parse line in type translation table types.txt -- incorect number of columns";
466     errorMsg << " found " << vc.size() << " expected " << _ncols << ".";
467     obErrorLog.ThrowError(__func__, errorMsg.str(), obInfo);
468     }
469     }
470 tim 2440 _linecount++;
471 gezelter 3057 }
472 tim 2440
473 gezelter 3057 bool OBTypeTable::SetFromType(const char* from)
474     {
475 tim 2440 if (!_init)
476 gezelter 3057 Init();
477 tim 2440
478     string tmp = from;
479    
480     unsigned int i;
481     for (i = 0;i < _colnames.size();i++)
482 gezelter 3057 if (tmp == _colnames[i])
483 tim 2440 {
484 gezelter 3057 _from = i;
485     return(true);
486 tim 2440 }
487    
488 tim 2518 obErrorLog.ThrowError(__func__, "Requested type column not found", obInfo);
489 tim 2440
490     return(false);
491 gezelter 3057 }
492 tim 2440
493 gezelter 3057 bool OBTypeTable::SetToType(const char* to)
494     {
495 tim 2440 if (!_init)
496 gezelter 3057 Init();
497 tim 2440
498     string tmp = to;
499    
500     unsigned int i;
501     for (i = 0;i < _colnames.size();i++)
502 gezelter 3057 if (tmp == _colnames[i])
503 tim 2440 {
504 gezelter 3057 _to = i;
505     return(true);
506 tim 2440 }
507    
508 tim 2518 obErrorLog.ThrowError(__func__, "Requested type column not found", obInfo);
509 tim 2440
510     return(false);
511 gezelter 3057 }
512 tim 2440
513 gezelter 3057 //! Translates atom types (to, from), checking for size of destination
514     //! string and null-terminating as needed
515     //! \deprecated Because there is no guarantee on the length of an atom type
516     //! you should consider using std::string instead
517     bool OBTypeTable::Translate(char *to, const char *from)
518     {
519 tim 2440 if (!_init)
520 gezelter 3057 Init();
521 tim 2440
522     bool rval;
523     string sto,sfrom;
524     sfrom = from;
525     rval = Translate(sto,sfrom);
526 gezelter 3057 strncpy(to,(char*)sto.c_str(), sizeof(to) - 1);
527     to[sizeof(to) - 1] = '\0';
528 tim 2440
529     return(rval);
530 gezelter 3057 }
531 tim 2440
532 gezelter 3057 bool OBTypeTable::Translate(string &to, const string &from)
533     {
534 tim 2440 if (!_init)
535 gezelter 3057 Init();
536 tim 2440
537     if (from == "")
538 gezelter 3057 return(false);
539 tim 2440
540     if (_from >= 0 && _to >= 0 &&
541 gezelter 3057 _from < _table.size() && _to < _table.size())
542 tim 2440 {
543 gezelter 3057 vector<vector<string> >::iterator i;
544     for (i = _table.begin();i != _table.end();i++)
545     if ((signed)(*i).size() > _from && (*i)[_from] == from)
546     {
547     to = (*i)[_to];
548     return(true);
549     }
550 tim 2440 }
551    
552     // Throw an error, copy the string and return false
553 tim 2518 obErrorLog.ThrowError(__func__, "Cannot perform atom type translation: table cannot find requested types.", obWarning);
554 tim 2440 to = from;
555     return(false);
556 gezelter 3057 }
557 tim 2440
558 gezelter 3057 std::string OBTypeTable::GetFromType()
559     {
560 tim 2440 if (!_init)
561 gezelter 3057 Init();
562 tim 2440
563     if (_from > 0 && _from < _table.size())
564     return( _colnames[_from] );
565     else
566     return( _colnames[0] );
567 gezelter 3057 }
568 tim 2440
569 gezelter 3057 std::string OBTypeTable::GetToType()
570     {
571 tim 2440 if (!_init)
572 gezelter 3057 Init();
573 tim 2440
574     if (_to > 0 && _to < _table.size())
575     return( _colnames[_to] );
576     else
577     return( _colnames[0] );
578 gezelter 3057 }
579 tim 2440
580 gezelter 3057 void Toupper(string &s)
581     {
582 tim 2440 unsigned int i;
583     for (i = 0;i < s.size();i++)
584 gezelter 3057 s[i] = toupper(s[i]);
585     }
586 tim 2440
587 gezelter 3057 void Tolower(string &s)
588     {
589 tim 2440 unsigned int i;
590     for (i = 0;i < s.size();i++)
591 gezelter 3057 s[i] = tolower(s[i]);
592     }
593 tim 2440
594 gezelter 3057 ///////////////////////////////////////////////////////////////////////
595     OBResidueData::OBResidueData()
596     {
597 tim 2440 _init = false;
598 gezelter 3057 STR_DEFINE(_dir, FRC_PATH );
599 gezelter 2450 _envvar = "FORCE_PARAM_PATH";
600 tim 2440 _filename = "resdata.txt";
601     _subdir = "data";
602     _dataptr = ResidueData;
603 gezelter 3057 }
604 tim 2440
605 gezelter 3057 bool OBResidueData::AssignBonds(OBMol &mol,OBBitVec &bv)
606     {
607     if (!_init)
608     Init();
609    
610 tim 2440 OBAtom *a1,*a2;
611     OBResidue *r1,*r2;
612     vector<OBNodeBase*>::iterator i,j;
613     vector3 v;
614    
615     int bo;
616     unsigned int skipres=0;
617     string rname = "";
618     //assign residue bonds
619     for (a1 = mol.BeginAtom(i);a1;a1 = mol.NextAtom(i))
620 gezelter 3057 {
621 tim 2440 r1 = a1->GetResidue();
622     if (skipres && r1->GetNum() == skipres)
623 gezelter 3057 continue;
624 tim 2440
625     if (r1->GetName() != rname)
626 gezelter 3057 {
627 tim 2440 skipres = SetResName(r1->GetName()) ? 0 : r1->GetNum();
628     rname = r1->GetName();
629 gezelter 3057 }
630 tim 2440 //assign bonds for each atom
631     for (j=i,a2 = mol.NextAtom(j);a2;a2 = mol.NextAtom(j))
632 gezelter 3057 {
633 tim 2440 r2 = a2->GetResidue();
634     if (r1->GetNum() != r2->GetNum())
635 gezelter 3057 break;
636 tim 2440 if (r1->GetName() != r2->GetName())
637 gezelter 3057 break;
638 tim 2440
639     if ((bo = LookupBO(r1->GetAtomID(a1),r2->GetAtomID(a2))))
640 gezelter 3057 {
641 tim 2440 v = a1->GetVector() - a2->GetVector();
642     if (v.length_2() < 3.5) //check by distance
643 gezelter 3057 mol.AddBond(a1->GetIdx(),a2->GetIdx(),bo);
644     }
645     }
646     }
647 tim 2440
648     int hyb;
649     string type;
650    
651     //types and hybridization
652 gezelter 3057 rname = ""; // name of current residue
653     skipres = 0; // don't skip any residues right now
654 tim 2440 for (a1 = mol.BeginAtom(i);a1;a1 = mol.NextAtom(i))
655 gezelter 3057 {
656 tim 2440 if (a1->IsOxygen() && !a1->GetValence())
657 gezelter 3057 {
658 tim 2440 a1->SetType("O3");
659     continue;
660 gezelter 3057 }
661 tim 2440 if (a1->IsHydrogen())
662 gezelter 3057 {
663 tim 2440 a1->SetType("H");
664     continue;
665 gezelter 3057 }
666 tim 2440
667     //***valence rule for O-
668     if (a1->IsOxygen() && a1->GetValence() == 1)
669 gezelter 3057 {
670 tim 2440 OBBond *bond;
671     bond = (OBBond*)*(a1->BeginBonds());
672     if (bond->GetBO() == 2)
673 gezelter 3057 {
674 tim 2440 a1->SetType("O2");
675     a1->SetHyb(2);
676 gezelter 3057 }
677     else if (bond->GetBO() == 1)
678     {
679 tim 2440 a1->SetType("O-");
680     a1->SetHyb(3);
681     a1->SetFormalCharge(-1);
682 gezelter 3057 }
683     continue;
684     }
685    
686     r1 = a1->GetResidue();
687     if (skipres && r1->GetNum() == skipres)
688     continue;
689 tim 2440
690 gezelter 3057 if (r1->GetName() != rname)
691     {
692     // if SetResName fails, skip this residue
693     skipres = SetResName(r1->GetName()) ? 0 : r1->GetNum();
694     rname = r1->GetName();
695     }
696    
697     if (LookupType(r1->GetAtomID(a1),type,hyb))
698     {
699     a1->SetType(type);
700     a1->SetHyb(hyb);
701     }
702     else // try to figure it out by bond order ???
703     {}
704     }
705    
706 tim 2440 return(true);
707 gezelter 3057 }
708 tim 2440
709 gezelter 3057 void OBResidueData::ParseLine(const char *buffer)
710     {
711 tim 2440 int bo;
712     string s;
713     vector<string> vs;
714    
715     if (buffer[0] == '#')
716 gezelter 3057 return;
717 tim 2440
718     tokenize(vs,buffer);
719     if (!vs.empty())
720 gezelter 3057 {
721 tim 2440 if (vs[0] == "BOND")
722 gezelter 3057 {
723 tim 2440 s = (vs[1] < vs[2]) ? vs[1] + " " + vs[2] :
724 gezelter 3057 vs[2] + " " + vs[1];
725 tim 2440 bo = atoi(vs[3].c_str());
726     _vtmp.push_back(pair<string,int> (s,bo));
727 gezelter 3057 }
728 tim 2440
729     if (vs[0] == "ATOM" && vs.size() == 4)
730 gezelter 3057 {
731 tim 2440 _vatmtmp.push_back(vs[1]);
732     _vatmtmp.push_back(vs[2]);
733     _vatmtmp.push_back(vs[3]);
734 gezelter 3057 }
735 tim 2440
736     if (vs[0] == "RES")
737 gezelter 3057 _resname.push_back(vs[1]);
738 tim 2440
739     if (vs[0]== "END")
740 gezelter 3057 {
741 tim 2440 _resatoms.push_back(_vatmtmp);
742     _resbonds.push_back(_vtmp);
743     _vtmp.clear();
744     _vatmtmp.clear();
745 gezelter 3057 }
746     }
747     }
748 tim 2440
749 gezelter 3057 bool OBResidueData::SetResName(const string &s)
750     {
751     if (!_init)
752     Init();
753    
754 tim 2440 unsigned int i;
755 gezelter 3057
756 tim 2440 for (i = 0;i < _resname.size();i++)
757 gezelter 3057 if (_resname[i] == s)
758 tim 2440 {
759 gezelter 3057 _resnum = i;
760     return(true);
761 tim 2440 }
762    
763     _resnum = -1;
764     return(false);
765 gezelter 3057 }
766 tim 2440
767 gezelter 3057 int OBResidueData::LookupBO(const string &s)
768     {
769 tim 2440 if (_resnum == -1)
770 gezelter 3057 return(0);
771 tim 2440
772     unsigned int i;
773     for (i = 0;i < _resbonds[_resnum].size();i++)
774 gezelter 3057 if (_resbonds[_resnum][i].first == s)
775     return(_resbonds[_resnum][i].second);
776 tim 2440
777     return(0);
778 gezelter 3057 }
779 tim 2440
780 gezelter 3057 int OBResidueData::LookupBO(const string &s1, const string &s2)
781     {
782 tim 2440 if (_resnum == -1)
783 gezelter 3057 return(0);
784 tim 2440 string s;
785    
786     s = (s1 < s2) ? s1 + " " + s2 : s2 + " " + s1;
787    
788     unsigned int i;
789     for (i = 0;i < _resbonds[_resnum].size();i++)
790 gezelter 3057 if (_resbonds[_resnum][i].first == s)
791     return(_resbonds[_resnum][i].second);
792 tim 2440
793     return(0);
794 gezelter 3057 }
795 tim 2440
796 gezelter 3057 bool OBResidueData::LookupType(const string &atmid,string &type,int &hyb)
797     {
798 tim 2440 if (_resnum == -1)
799 gezelter 3057 return(false);
800 tim 2440
801     string s;
802     vector<string>::iterator i;
803    
804     for (i = _resatoms[_resnum].begin();i != _resatoms[_resnum].end();i+=3)
805 gezelter 3057 if (atmid == *i)
806 tim 2440 {
807 gezelter 3057 i++;
808     type = *i;
809     i++;
810     hyb = atoi((*i).c_str());
811     return(true);
812 tim 2440 }
813    
814     return(false);
815 gezelter 3057 }
816 tim 2440
817 gezelter 3057 void OBGlobalDataBase::Init()
818     {
819 tim 2440 if (_init)
820 gezelter 3057 return;
821 tim 2440 _init = true;
822    
823 gezelter 3057 string buffer, subbuffer;
824 tim 2440 ifstream ifs1, ifs2, ifs3, ifs4, *ifsP;
825     // First, look for an environment variable
826     if (getenv(_envvar.c_str()) != NULL)
827 gezelter 3057 {
828     buffer = getenv(_envvar.c_str());
829     buffer += FILE_SEP_CHAR;
830 tim 2440
831     if (!_subdir.empty())
832 gezelter 3057 {
833     subbuffer = buffer;
834     subbuffer += _subdir;
835     subbuffer += FILE_SEP_CHAR;
836     }
837 tim 2440
838 gezelter 3057 buffer += _filename;
839     subbuffer += _filename;
840 tim 2440
841 gezelter 3057 ifs1.open(subbuffer.c_str());
842 tim 2440 ifsP= &ifs1;
843     if (!(*ifsP))
844 gezelter 3057 {
845     ifs2.open(buffer.c_str());
846 tim 2440 ifsP = &ifs2;
847 gezelter 3057 }
848     }
849 tim 2440 // Then, check the configured data directory
850     else // if (!(*ifsP))
851 gezelter 3057 {
852     buffer = _dir;
853     buffer += FILE_SEP_CHAR;
854 tim 2440
855 gezelter 3057 subbuffer = buffer;
856     subbuffer += BABEL_VERSION;
857     subbuffer += FILE_SEP_CHAR;
858 tim 2440
859 gezelter 3057 subbuffer += _filename;
860     buffer += _filename;
861 tim 2440
862 gezelter 3057 ifs3.open(subbuffer.c_str());
863 tim 2440 ifsP= &ifs3;
864     if (!(*ifsP))
865 gezelter 3057 {
866     ifs4.open(buffer.c_str());
867 tim 2440 ifsP = &ifs4;
868 gezelter 3057 }
869     }
870 tim 2440
871 gezelter 3057 char charBuffer[BUFF_SIZE];
872 tim 2440 if ((*ifsP))
873 gezelter 3057 {
874     while(ifsP->getline(charBuffer,BUFF_SIZE))
875     ParseLine(charBuffer);
876     }
877 tim 2440
878     else
879 gezelter 3057 // If all else fails, use the compiled in values
880     if (_dataptr)
881 tim 2440 {
882 gezelter 3057 const char *p1,*p2;
883     for (p1 = p2 = _dataptr;*p2 != '\0';p2++)
884     if (*p2 == '\n')
885     {
886     strncpy(charBuffer, p1, (p2 - p1));
887     charBuffer[(p2 - p1)] = '\0';
888     ParseLine(charBuffer);
889     p1 = ++p2;
890     }
891 tim 2440 }
892 gezelter 3057 else
893 tim 2440 {
894 gezelter 3057 string s = "Unable to open data file '";
895     s += _filename;
896     s += "'";
897     obErrorLog.ThrowError(__func__, s, obWarning);
898 tim 2440 }
899    
900     if (ifs1)
901 gezelter 3057 ifs1.close();
902 tim 2440 if (ifs2)
903 gezelter 3057 ifs2.close();
904 tim 2440 if (ifs3)
905 gezelter 3057 ifs3.close();
906 tim 2440 if (ifs4)
907 gezelter 3057 ifs4.close();
908 tim 2440
909     if (GetSize() == 0)
910     {
911 gezelter 3057 string s = "Cannot initialize database '";
912     s += _filename;
913     s += "' which may cause further errors.";
914     obErrorLog.ThrowError(__func__, "Cannot initialize database", obWarning);
915 tim 2440 }
916    
917 gezelter 3057 }
918 tim 2440
919     } // end namespace OpenBabel
920    
921     //! \file data.cpp
922     //! \brief Global data and resource file parsers.