ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-3.0/src/openbabel/base.cpp
Revision: 2450
Committed: Thu Nov 17 20:38:45 2005 UTC (18 years, 8 months ago) by gezelter
File size: 8955 byte(s)
Log Message:
Unifying config.h stuff and making sure the OpenBabel codes can find
our default (and environment variable) Force Field directories.

File Contents

# Content
1 /**********************************************************************
2 base.cpp - Base classes to build a graph
3
4 Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
5 Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison
6
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 #include "config.h"
21 #include "base.hpp"
22
23 #if HAVE_IOSTREAM
24 #include <iostream>
25 #elif HAVE_IOSTREAM_H
26 #include <iostream.h>
27 #endif
28
29 #if HAVE_FSTREAM
30 #include <fstream>
31 #elif HAVE_FSTREAM_H
32 #include <fstream.h>
33 #endif
34
35 using namespace std;
36
37 //! Global namespace for all Open Babel code
38 namespace OpenBabel
39 {
40 /*
41 bool OBGraphBase::Match(OBGraphBase &g,bool singleMatch)
42 {
43 SetFinishedMatch(false);
44 SetSingleMatch(singleMatch);
45 ClearMatches();
46 g.SetVisitLock(true);
47 g.ResetVisitFlags();
48
49 OBNodeBase *node;
50 OBNodeBase *seed = GetFirstSeed();
51 vector<OBNodeBase*>::iterator i;
52
53 for (node = g.Begin(i);node;node = g.Next(i))
54 if (!node->Visit && seed->Eval(node))
55 {
56 node->Visit = true;
57 seed->SetMatch(node);
58 Match(g,BgnMatch(),BgnMatch()->second.begin());
59 seed->SetMatch((OBNodeBase*)NULL);
60 node->Visit = false;
61 if (SingleMatch() && FinishedMatch())
62 break;
63 }
64
65 g.SetVisitLock(false);
66
67 return(FinishedMatch());
68 }
69
70 bool OBGraphBase::Match(OBGraphBase &g,
71 vector<pair<OBNodeBase*,vector<OBEdgeBase*> > >::iterator i,
72 vector<OBEdgeBase*>::iterator j)
73 {
74 //bail if only one match has been requested
75 if (SingleMatch() && FinishedMatch())
76 return(true);
77
78 //full match completed
79 if (i == EndMatch() || (j == i->second.end() && (i+1) == EndMatch()))
80 {
81 SetFinishedMatch(true);
82 OBNodeBase *node;
83 vector<OBNodeBase*> vn;
84 vector<OBNodeBase*>::iterator i;
85 for (node = Begin(i);node;node = Next(i))
86 vn.push_back(node->GetMatch());
87 PushBack(vn);
88
89 return(true);
90 }
91
92 //handle next seed of disconnected pattern
93 if (j == i->second.end())
94 {
95 i++;
96 OBNodeBase *node;
97 OBNodeBase *seed = i->first;
98 vector<OBNodeBase*>::iterator k;
99 for (node = g.Begin(k);node;node = g.Next(k))
100 if (!node->Visit && seed->Eval(node))
101 {
102 node->Visit = true;
103 seed->SetMatch(node);
104 Match(g,i,i->second.begin());
105 seed->SetMatch((OBNodeBase*)NULL);
106 node->Visit = false;
107 if (SingleMatch() && FinishedMatch())
108 break;
109 }
110 return(true);
111 }
112
113 OBEdgeBase *edge = *j++;
114 if (edge->IsClosure()) //check to see if matched atoms are bonded
115 {
116 if (edge->GetBgn()->GetMatch()->IsConnected(edge->GetEnd()->GetMatch()))
117 Match(g,i,j);
118 }
119 else //bond hasn't been covered yet
120 {
121 OBNodeBase *nbr;
122 OBNodeBase *curr = edge->GetBgn();
123 OBNodeBase *next = edge->GetEnd();
124 OBNodeBase *match = curr->GetMatch();
125 vector<OBEdgeBase*>::iterator k;
126
127 for (nbr = match->BeginNbr(k);nbr;nbr = match->NextNbr(k))
128 if (!nbr->Visit && next->Eval(nbr) && edge->Eval(*k))
129 {
130 nbr->Visit = true;
131 next->SetMatch(nbr);
132 Match(g,i,j);
133 next->SetMatch(NULL);
134 nbr->Visit = false;
135 }
136 }
137
138 return(false);
139 }
140 */
141 OBNodeBase *OBGraphBase::Begin(vector<OBNodeBase*>::iterator &i)
142 {
143 i = _vatom.begin();
144 return((i != _vatom.end()) ? *i : NULL);
145 }
146
147 OBNodeBase *OBGraphBase::Next(vector<OBNodeBase*>::iterator &i)
148 {
149 i++;
150 return((i != _vatom.end()) ? *i : NULL);
151 }
152
153 OBEdgeBase *OBGraphBase::Begin(vector<OBEdgeBase*>::iterator &i)
154 {
155 i = _vbond.begin();
156 return((i != _vbond.end()) ? *i : NULL);
157 }
158
159 OBEdgeBase *OBGraphBase::Next(vector<OBEdgeBase*>::iterator &i)
160 {
161 i++;
162 return((i != _vbond.end()) ? *i : NULL);
163 }
164
165 OBNodeBase *OBNodeBase::BeginNbr(vector<OBEdgeBase*>::iterator &i)
166 {
167 i = _vbond.begin();
168
169 if (i == _vbond.end())
170 return(NULL);
171 return((this == (*i)->GetBgn()) ? (*i)->GetEnd() : (*i)->GetBgn());
172 }
173
174 OBNodeBase *OBNodeBase::NextNbr(vector<OBEdgeBase*>::iterator &i)
175 {
176 i++;
177 if (i == _vbond.end())
178 return(NULL);
179 return((this == (*i)->GetBgn()) ? (*i)->GetEnd() : (*i)->GetBgn());
180 }
181
182 void OBNodeBase::SetParent(OBGraphBase *p)
183 {
184 _parent = p;
185 }
186
187 void OBEdgeBase::SetParent(OBGraphBase *p)
188 {
189 _parent = p;
190 }
191
192 bool OBNodeBase::IsConnected(OBNodeBase *nb)
193 {
194 vector<OBEdgeBase*>::iterator i;
195 for (i = _vbond.begin();i != _vbond.end();i++)
196 if (nb == (*i)->GetBgn() || nb == (*i)->GetEnd())
197 return(true);
198
199 return(false);
200 }
201
202 void OBGraphBase::ResetVisitFlags()
203 {
204 OBNodeBase *nb;
205 vector<OBNodeBase*>::iterator i;
206 for (nb = Begin(i);nb;nb = Next(i))
207 nb->Visit = false;
208
209 OBEdgeBase *eb;
210 vector<OBEdgeBase*>::iterator j;
211 for (eb = Begin(j);eb;eb = Next(j))
212 eb->Visit = false;
213 }
214
215 bool OBGraphBase::SetVisitLock(bool v)
216 {
217 if (v && _vlock)
218 return(false);
219 _vlock = v;
220 return(true);
221 }
222
223 /*! \mainpage
224
225 \section intro Introduction and History
226
227 It is fair to say that Open Babel is a direct result of the original Babel.
228 Application development is facilitated
229 by building software on top of libraries rich in functionality. Babel
230 was the first experience for Matt Stahl in designing a molecule
231 library. In addition to developing Babel, Pat Walters and Matt
232 developed `OBabel' at Vertex Pharmaceuticals, a first
233 attempt at developing an object oriented molecule library.
234 Matt later designed a new molecule class library, OELib -- designed
235 to be flexible, extensible, portable, and efficient.
236
237 OELib was released under the GNU General Public License (GPL) by Matt Stahl
238 and Open Eye Scientific Software, Inc. to take advantage of many of
239 the "great minds writing chemical software." Open Babel took up where
240 OELib and Babel left off, starting from the existing GPL version of
241 OELib, and has continued to evolve and improve into a separate
242 high-quality chemistry class library and tool. Open Babel is now a
243 separate project and library and has changed considerably from the OELib days.
244
245 Thanks to all who have helped with Babel, OBabel, OELib and Open Babel.
246 The list is long and growing.
247
248 \section pointers Key Modules
249
250 The heart of Open Babel lies in the \link OpenBabel::OBMol OBMol\endlink,
251 \link OpenBabel::OBAtom OBAtom\endlink, and
252 \link OpenBabel::OBBond OBBond\endlink classes,
253 which handle operations on atoms, bonds and molecules. Newcomers should
254 start with looking at the \link OpenBabel::OBMol OBMol\endlink class,
255 designed to store the basic information
256 in a molecule and to perceive information about a molecule.
257
258 One of the key philosophies in the code is that transformations and
259 automatic perception of properties are performed in a <a href="http://en.wikipedia.org/wiki/Lazy_evaluation">"lazy"</a>
260 manner. That is, until you call for partial atomic charges, no
261 charges are calculated. This ensures faster transformations of
262 chemical data -- properties that are not needed for your code will
263 typically not be calculated. When such data is needed, appropriate
264 routines are called, and a "flag" is set (e.g., via OBMol::SetFlag
265 or OBAtom::SetFlag etc.) so that the code is only run once.
266
267 Arbitrary custom data and text descriptors can be stored in any atom,
268 bond, molecule, or residue using the \link OpenBabel::OBGenericData
269 OBGenericData\endlink or \link OpenBabel::OBPairData
270 OBPairData\endlink classes.
271
272 Conversion between various chemical file formats is accomplished through
273 the \link OpenBabel::OBConversion OBConversion\endlink and \link
274 OpenBabel::OBFormat OBFormat\endlink classes, often through use of the \link
275 OpenBabel::OBMoleculeFormat OBMoleculeFormat\endlink subclass which is designed
276 for easy read/write access to one or more \link OpenBabel::OBMol OBMol\endlink
277 objects. The philosophy of the file format codes is to parse as much
278 chemical information from a given file as possible (no data left
279 behind) and ideally any perception or transformations will occur when
280 writing to some other format later.
281
282 */
283
284 } // namespace OpenBabel
285
286 //! \file base.cpp
287 //! \brief Implementation of base classes.