~vcs-imports/openbabel/trunk

« back to all changes in this revision

Viewing changes to bond.cpp

  • Committer: ghutchis
  • Date: 2001-11-27 18:50:36 UTC
  • Revision ID: svn-v4:86f38270-e075-4da6-bf68-7dcd545c500b:openbabel/trunk:46
Initial revision

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
 
3
 
 
4
This program is free software; you can redistribute it and/or modify
 
5
it under the terms of the GNU General Public License as published by
 
6
the Free Software Foundation version 2 of the License.
 
7
 
 
8
This program is distributed in the hope that it will be useful,
 
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
GNU General Public License for more details.
 
12
***********************************************************************/
 
13
 
 
14
#include "mol.h"
 
15
#include "typer.h"
 
16
 
 
17
namespace OpenEye {
 
18
 
 
19
extern OEAromaticTyper  aromtyper;
 
20
 
 
21
// *******************************
 
22
// *** OEBond member functions ***
 
23
// *******************************
 
24
 
 
25
OEBond::OEBond()
 
26
 {
 
27
   _idx=0;
 
28
   _order=0;
 
29
   _flags=0;
 
30
   _bgn=NULL;
 
31
   _end=NULL;
 
32
 }
 
33
 
 
34
void OEBond::Set(int idx,OEAtom *begin,OEAtom *end,int order,int flags)
 
35
{
 
36
  SetIdx(idx);
 
37
  SetBegin(begin);
 
38
  SetEnd(end);
 
39
  SetBO(order);
 
40
  SetFlag(flags);
 
41
}
 
42
 
 
43
void OEBond::SetBO(int order)
 
44
{
 
45
  _order = (char)order;
 
46
  if (order == 5)
 
47
    {
 
48
      SetAromatic();
 
49
      if (_bgn) _bgn->SetAromatic();
 
50
      if (_end) _end->SetAromatic();
 
51
    }
 
52
  else            UnsetAromatic();
 
53
}
 
54
 
 
55
void OEBond::SetLength(OEAtom *fixed, float length)
 
56
{
 
57
  unsigned int i;
 
58
  OEMol *mol = (OEMol*)fixed->GetParent();
 
59
  Vector v1,v2,v3,v4,v5;
 
60
  vector<int> children;
 
61
 
 
62
  int a = fixed->GetIdx();
 
63
  int b = GetNbrAtom(fixed)->GetIdx();
 
64
 
 
65
  mol->FindChildren(children,a,b);
 
66
  children.push_back(b);
 
67
 
 
68
  v1 = GetNbrAtom(fixed)->GetVector();
 
69
  v2 = fixed->GetVector();
 
70
  v3 = v1 - v2;
 
71
  v3.normalize();
 
72
  v3 *= length;
 
73
  v3 += v2;
 
74
  v4 = v3 - v1;
 
75
 
 
76
  for ( i = 0 ; i < children.size() ; i++ )
 
77
    {
 
78
      v1 = mol->GetAtom(children[i])->GetVector();
 
79
      v1 += v4;
 
80
      mol->GetAtom(children[i])->SetVector(v1);
 
81
      /*
 
82
      idx = (children[i]-1) * 3;
 
83
      c[idx]   += x; 
 
84
      c[idx+1] += y;
 
85
      c[idx+2] += z;
 
86
      */
 
87
    }
 
88
}
 
89
   
 
90
bool OEBond::IsRotor()
 
91
{
 
92
  return(_bgn->GetHvyValence() > 1 && _end->GetHvyValence() > 1 && 
 
93
         _order == 1 && !IsInRing() && _bgn->GetHyb() != 1 &&
 
94
         _end->GetHyb() != 1);
 
95
}
 
96
 
 
97
bool OEBond::IsAmide()
 
98
{
 
99
  OEAtom *a1,*a2;
 
100
  a1 = a2 = NULL;
 
101
 
 
102
  if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 7)
 
103
    {a1 = (OEAtom*)_bgn; a2 = (OEAtom*)_end;}
 
104
 
 
105
  if (_bgn->GetAtomicNum() == 7 && _end->GetAtomicNum() == 6)
 
106
    {a1 = (OEAtom*)_end; a2 = (OEAtom*)_bgn;}
 
107
 
 
108
  if (!a1 || !a2) return(false);
 
109
  if (GetBO() != 1) return(false);
 
110
  
 
111
  OEBond *bond;
 
112
  vector<OEBond*>::iterator i;
 
113
  for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
 
114
    if (bond->IsCarbonyl())
 
115
      return(true);
 
116
  
 
117
  return(false);
 
118
}
 
119
 
 
120
bool OEBond::IsPrimaryAmide()
 
121
{
 
122
  OEAtom *a1,*a2;
 
123
  a1 = a2 = NULL;
 
124
 
 
125
  if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 7)
 
126
    {a1 = (OEAtom*)_bgn; a2 = (OEAtom*)_end;}
 
127
 
 
128
  if (_bgn->GetAtomicNum() == 7 && _end->GetAtomicNum() == 6)
 
129
    {a1 = (OEAtom*)_end; a2 = (OEAtom*)_bgn;}
 
130
 
 
131
  if (!a1 || !a2) return(false);
 
132
  if (GetBO() != 1) return(false);
 
133
  
 
134
  OEBond *bond;
 
135
  vector<OEBond*>::iterator i;
 
136
  for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
 
137
    if (bond->IsCarbonyl())
 
138
      if (a2->GetHvyValence() == 2)
 
139
      return(true);
 
140
 
 
141
  
 
142
  return(false);
 
143
}
 
144
 
 
145
bool OEBond::IsSecondaryAmide()
 
146
{
 
147
  
 
148
  
 
149
  return(false);
 
150
}
 
151
 
 
152
bool OEBond::IsEster()
 
153
{
 
154
  OEAtom *a1,*a2;
 
155
  a1 = a2 = NULL;
 
156
 
 
157
  if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 8)
 
158
    {a1 = (OEAtom*)_bgn; a2 = (OEAtom*)_end;}
 
159
 
 
160
  if (_bgn->GetAtomicNum() == 8 && _end->GetAtomicNum() == 6)
 
161
    {a1 = (OEAtom*)_end; a2 = (OEAtom*)_bgn;}
 
162
 
 
163
  if (!a1 || !a2) return(false);
 
164
  if (GetBO() != 1) return(false);
 
165
  
 
166
  OEBond *bond;
 
167
  vector<OEBond*>::iterator i;
 
168
  for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
 
169
    if (bond->IsCarbonyl())
 
170
      return(true);
 
171
  
 
172
  
 
173
  return(false);
 
174
}
 
175
 
 
176
bool OEBond::IsCarbonyl()
 
177
{
 
178
  if (GetBO() != 2) return(false);
 
179
  
 
180
  if ((_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 8) || 
 
181
      (_bgn->GetAtomicNum() == 8 && _end->GetAtomicNum() == 6))
 
182
    return(true);
 
183
 
 
184
  return(false);
 
185
}
 
186
 
 
187
bool OEBond::IsSingle()
 
188
{
 
189
        if (HasFlag(OE_AROMATIC_BOND)) return(false);
 
190
 
 
191
        if (!((OEMol*)GetParent())->HasAromaticPerceived())
 
192
                {
 
193
                        aromtyper.AssignAromaticFlags(*((OEMol*)GetParent()));
 
194
                }
 
195
 
 
196
        if ((this->GetBondOrder()==1) && !(HasFlag(OE_AROMATIC_BOND)))
 
197
                return(true);
 
198
 
 
199
        return(false);
 
200
}
 
201
 
 
202
bool OEBond::IsDouble()
 
203
{
 
204
        if      (HasFlag(OE_AROMATIC_BOND)) return(false);
 
205
 
 
206
        if (!((OEMol*)GetParent())->HasAromaticPerceived())
 
207
                {
 
208
                        aromtyper.AssignAromaticFlags(*((OEMol*)GetParent()));
 
209
                }
 
210
                        
 
211
        if ((this->GetBondOrder()==2) && !(HasFlag(OE_AROMATIC_BOND)))
 
212
                return(true);
 
213
 
 
214
        return(false);
 
215
}
 
216
 
 
217
bool OEBond::IsAromatic() const
 
218
{
 
219
  if (((OEBond*)this)->HasFlag(OE_AROMATIC_BOND)) return(true);
 
220
 
 
221
  OEMol *mol = (OEMol*)((OEBond*)this)->GetParent();
 
222
  if (!mol->HasAromaticPerceived())
 
223
    {
 
224
      aromtyper.AssignAromaticFlags(*mol);
 
225
      if (((OEBond*)this)->HasFlag(OE_AROMATIC_BOND)) return(true);
 
226
    }
 
227
 
 
228
  return(false);
 
229
}
 
230
 
 
231
void OEBond::SetKSingle()
 
232
{
 
233
  _flags &= (~(OE_KSINGLE_BOND|OE_KDOUBLE_BOND|OE_KTRIPLE_BOND));
 
234
  _flags |= OE_KSINGLE_BOND;
 
235
}
 
236
 
 
237
void OEBond::SetKDouble()
 
238
{
 
239
  _flags &= (~(OE_KSINGLE_BOND|OE_KDOUBLE_BOND|OE_KTRIPLE_BOND));
 
240
  _flags |= OE_KDOUBLE_BOND;
 
241
}
 
242
 
 
243
void OEBond::SetKTriple()
 
244
{
 
245
  _flags &= (~(OE_KSINGLE_BOND|OE_KDOUBLE_BOND|OE_KTRIPLE_BOND));
 
246
  _flags |= OE_KTRIPLE_BOND;
 
247
}
 
248
 
 
249
bool OEBond::IsKSingle()
 
250
{
 
251
  if (_flags & OE_KSINGLE_BOND) return(true);
 
252
  if (!((OEMol*)GetParent())->HasKekulePerceived()) 
 
253
          ((OEMol*)GetParent())->PerceiveKekuleBonds();
 
254
 
 
255
  return((_flags & OE_KSINGLE_BOND) != 0) ? true : false;
 
256
}
 
257
 
 
258
bool OEBond::IsKDouble()
 
259
{
 
260
  if (_flags & OE_KDOUBLE_BOND) return(true);
 
261
  if (!((OEMol*)GetParent())->HasKekulePerceived()) 
 
262
          ((OEMol*)GetParent())->PerceiveKekuleBonds();
 
263
 
 
264
  return((_flags & OE_KDOUBLE_BOND) != 0) ? true : false;
 
265
}
 
266
 
 
267
bool OEBond::IsKTriple()
 
268
{
 
269
  if (_flags & OE_KTRIPLE_BOND) return(true);
 
270
  if (!((OEMol*)GetParent())->HasKekulePerceived()) 
 
271
          ((OEMol*)GetParent())->PerceiveKekuleBonds();
 
272
 
 
273
  return((_flags & OE_KTRIPLE_BOND) != 0) ? true : false;
 
274
}
 
275
 
 
276
bool OEBond::IsInRing() const
 
277
{
 
278
  if (((OEBond*)this)->HasFlag(OE_RING_BOND)) return(true);
 
279
  
 
280
  OEMol *mol = (OEMol*)((OEBond*)this)->GetParent();
 
281
  if (!mol->HasRingAtomsAndBondsPerceived())
 
282
    {
 
283
      mol->FindRingAtomsAndBonds();
 
284
      if (((OEBond*)this)->HasFlag(OE_RING_BOND)) return(true);
 
285
    }
 
286
 
 
287
  return(false);
 
288
}
 
289
 
 
290
bool OEBond::IsClosure()
 
291
{
 
292
  OEMol *mol = (OEMol*)GetParent();
 
293
  if (!mol) return(false);
 
294
  if (mol->HasClosureBondsPerceived()) return(HasFlag(OE_CLOSURE_BOND));
 
295
  
 
296
  mol->SetClosureBondsPerceived();
 
297
  
 
298
  OEBond *bond;
 
299
  OEAtom *atom,*nbr;
 
300
  OEBitVec uatoms,ubonds;
 
301
  vector<OEAtom*> curr,next;
 
302
  vector<OEAtom*>::iterator i;
 
303
  vector<OEBond*>::iterator j;
 
304
 
 
305
  uatoms.Resize(mol->NumAtoms()+1);
 
306
  ubonds.Resize(mol->NumAtoms()+1);
 
307
 
 
308
  for (;uatoms.CountBits() < (signed)mol->NumAtoms();)
 
309
    {
 
310
      if (curr.empty())
 
311
        for (atom = mol->BeginAtom(i);atom;atom = mol->NextAtom(i))
 
312
          if (!uatoms[atom->GetIdx()])
 
313
            {
 
314
              uatoms |= atom->GetIdx();
 
315
              curr.push_back(atom);
 
316
              break;
 
317
            }
 
318
 
 
319
      for (;!curr.empty();)
 
320
        {
 
321
          for (i = curr.begin();i != curr.end();i++)
 
322
            for (nbr = (*i)->BeginNbrAtom(j);nbr;nbr = (*i)->NextNbrAtom(j))
 
323
              if (!uatoms[nbr->GetIdx()])
 
324
                {
 
325
                  uatoms |= nbr->GetIdx();
 
326
                  ubonds |= (*j)->GetIdx();
 
327
                  next.push_back(nbr);
 
328
                }
 
329
 
 
330
          curr = next;
 
331
          next.clear();
 
332
        }
 
333
    }
 
334
 
 
335
  for (bond = mol->BeginBond(j);bond;bond = mol->NextBond(j))
 
336
    if (!ubonds[bond->GetIdx()])
 
337
      bond->SetClosure();
 
338
  
 
339
  return(HasFlag(OE_CLOSURE_BOND));
 
340
}
 
341
 
 
342
float OEBond::GetEquibLength()
 
343
{
 
344
  float length;
 
345
  OEAtom *begin, *end;
 
346
  // CorrectedBondRad will always return a # now
 
347
  //  if (!CorrectedBondRad(GetBeginAtom(),rad1)) return(0.0);
 
348
  //  if (!CorrectedBondRad(GetEndAtom(),rad2))   return(0.0);
 
349
 
 
350
  begin = GetBeginAtom();
 
351
  end = GetEndAtom();
 
352
  length = etab.CorrectedBondRad(begin->GetAtomicNum(), begin->GetHyb())
 
353
    + etab.CorrectedBondRad(end->GetAtomicNum(), end->GetHyb());
 
354
  
 
355
  if (IsAromatic()) length *= 0.93f;
 
356
  else if (GetBO() == 2)         length *= 0.91f;
 
357
  else if (GetBO() == 3)         length *= 0.87f;
 
358
  return(length);
 
359
}
 
360
 
 
361
float OEBond::GetLength()
 
362
{
 
363
  float d2;
 
364
  OEAtom *begin, *end;
 
365
  begin = GetBeginAtom();
 
366
  end = GetEndAtom();
 
367
  
 
368
  d2 = SQUARE(begin->GetX() - end->GetX());
 
369
  d2 += SQUARE(begin->GetY() - end->GetY());
 
370
  d2 += SQUARE(begin->GetZ() - end->GetZ());
 
371
 
 
372
  return(sqrt(d2));
 
373
}
 
374
 
 
375
}