ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/openbabel/base.cpp
Revision: 2450
Committed: Thu Nov 17 20:38:45 2005 UTC (18 years, 9 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

# User Rev Content
1 tim 2440 /**********************************************************************
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 gezelter 2450 #include "config.h"
21 tim 2440 #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.