41
42
// *******************************
57
vector<OBGenericData*>::iterator m;
58
for (m = _vdata.begin();m != _vdata.end();m++) delete *m;
58
vector<OBGenericData*>::iterator m;
59
for (m = _vdata.begin();m != _vdata.end();m++)
63
65
void OBBond::Set(int idx,OBAtom *begin,OBAtom *end,int order,int flags)
72
74
void OBBond::SetBO(int order)
78
if (_bgn) _bgn->SetAromatic();
79
if (_end) _end->SetAromatic();
84
98
void OBBond::SetLength(OBAtom *fixed, double length)
87
OBMol *mol = (OBMol*)fixed->GetParent();
88
vector3 v1,v2,v3,v4,v5;
91
int a = fixed->GetIdx();
92
int b = GetNbrAtom(fixed)->GetIdx();
94
mol->FindChildren(children,a,b);
95
children.push_back(b);
97
v1 = GetNbrAtom(fixed)->GetVector();
98
v2 = fixed->GetVector();
105
for ( i = 0 ; i < children.size() ; i++ )
101
OBMol *mol = (OBMol*)fixed->GetParent();
102
vector3 v1,v2,v3,v4,v5;
103
vector<int> children;
105
obErrorLog.ThrowError(__FUNCTION__,
106
"Ran OpenBabel::SetBondLength", obAuditMsg);
108
int a = fixed->GetIdx();
109
int b = GetNbrAtom(fixed)->GetIdx();
111
mol->FindChildren(children,a,b);
112
children.push_back(b);
114
v1 = GetNbrAtom(fixed)->GetVector();
115
v2 = fixed->GetVector();
122
for ( i = 0 ; i < children.size() ; i++ )
107
v1 = mol->GetAtom(children[i])->GetVector();
109
mol->GetAtom(children[i])->SetVector(v1);
111
idx = (children[i]-1) * 3;
124
v1 = mol->GetAtom(children[i])->GetVector();
126
mol->GetAtom(children[i])->SetVector(v1);
128
idx = (children[i]-1) * 3;
119
136
bool OBBond::IsRotor()
121
return(_bgn->GetHvyValence() > 1 && _end->GetHvyValence() > 1 &&
122
_order == 1 && !IsInRing() && _bgn->GetHyb() != 1 &&
123
_end->GetHyb() != 1);
138
return(_bgn->GetHvyValence() > 1 && _end->GetHvyValence() > 1 &&
139
_order == 1 && !IsInRing() && _bgn->GetHyb() != 1 &&
140
_end->GetHyb() != 1);
126
143
bool OBBond::IsAmide()
131
if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 7)
132
{a1 = (OBAtom*)_bgn; a2 = (OBAtom*)_end;}
134
if (_bgn->GetAtomicNum() == 7 && _end->GetAtomicNum() == 6)
135
{a1 = (OBAtom*)_end; a2 = (OBAtom*)_bgn;}
137
if (!a1 || !a2) return(false);
138
if (GetBO() != 1) return(false);
141
vector<OBEdgeBase*>::iterator i;
142
for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
143
if (bond->IsCarbonyl())
148
if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 7)
154
if (_bgn->GetAtomicNum() == 7 && _end->GetAtomicNum() == 6)
166
vector<OBEdgeBase*>::iterator i;
167
for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
168
if (bond->IsCarbonyl())
149
174
bool OBBond::IsPrimaryAmide()
154
if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 7)
155
{a1 = (OBAtom*)_bgn; a2 = (OBAtom*)_end;}
157
if (_bgn->GetAtomicNum() == 7 && _end->GetAtomicNum() == 6)
158
{a1 = (OBAtom*)_end; a2 = (OBAtom*)_bgn;}
160
if (!a1 || !a2) return(false);
161
if (GetBO() != 1) return(false);
164
vector<OBEdgeBase*>::iterator i;
165
for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
166
if (bond->IsCarbonyl())
167
if (a2->GetHvyValence() == 2)
179
if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 7)
185
if (_bgn->GetAtomicNum() == 7 && _end->GetAtomicNum() == 6)
197
vector<OBEdgeBase*>::iterator i;
198
for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
199
if (bond->IsCarbonyl())
200
if (a2->GetHvyValence() == 2)
206
//! \todo Implement this properly -- currently always returns false
174
207
bool OBBond::IsSecondaryAmide()
181
212
bool OBBond::IsEster()
186
if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 8)
187
{a1 = (OBAtom*)_bgn; a2 = (OBAtom*)_end;}
189
if (_bgn->GetAtomicNum() == 8 && _end->GetAtomicNum() == 6)
190
{a1 = (OBAtom*)_end; a2 = (OBAtom*)_bgn;}
192
if (!a1 || !a2) return(false);
193
if (GetBO() != 1) return(false);
196
vector<OBEdgeBase*>::iterator i;
197
for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
198
if (bond->IsCarbonyl())
217
if (_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 8)
223
if (_bgn->GetAtomicNum() == 8 && _end->GetAtomicNum() == 6)
235
vector<OBEdgeBase*>::iterator i;
236
for (bond = a1->BeginBond(i);bond;bond = a1->NextBond(i))
237
if (bond->IsCarbonyl())
205
243
bool OBBond::IsCarbonyl()
207
if (GetBO() != 2) return(false);
209
if ((_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 8) ||
210
(_bgn->GetAtomicNum() == 8 && _end->GetAtomicNum() == 6))
248
if ((_bgn->GetAtomicNum() == 6 && _end->GetAtomicNum() == 8) ||
249
(_bgn->GetAtomicNum() == 8 && _end->GetAtomicNum() == 6))
216
255
bool OBBond::IsSingle()
218
if (HasFlag(OB_AROMATIC_BOND)) return(false);
220
if (!((OBMol*)GetParent())->HasAromaticPerceived())
222
aromtyper.AssignAromaticFlags(*((OBMol*)GetParent()));
225
if ((this->GetBondOrder()==1) && !(HasFlag(OB_AROMATIC_BOND)))
257
if (HasFlag(OB_AROMATIC_BOND))
260
if (!((OBMol*)GetParent())->HasAromaticPerceived())
262
aromtyper.AssignAromaticFlags(*((OBMol*)GetParent()));
265
if ((this->GetBondOrder()==1) && !(HasFlag(OB_AROMATIC_BOND)))
231
271
bool OBBond::IsDouble()
233
if (HasFlag(OB_AROMATIC_BOND)) return(false);
235
if (!((OBMol*)GetParent())->HasAromaticPerceived())
237
aromtyper.AssignAromaticFlags(*((OBMol*)GetParent()));
240
if ((this->GetBondOrder()==2) && !(HasFlag(OB_AROMATIC_BOND)))
273
if (HasFlag(OB_AROMATIC_BOND))
276
if (!((OBMol*)GetParent())->HasAromaticPerceived())
278
aromtyper.AssignAromaticFlags(*((OBMol*)GetParent()));
281
if ((this->GetBondOrder()==2) && !(HasFlag(OB_AROMATIC_BOND)))
246
287
bool OBBond::IsTriple()
248
if (HasFlag(OB_AROMATIC_BOND)) return(false);
250
if (!((OBMol*)GetParent())->HasAromaticPerceived())
252
aromtyper.AssignAromaticFlags(*((OBMol*)GetParent()));
255
if ((this->GetBondOrder()==3) && !(HasFlag(OB_AROMATIC_BOND)))
289
if (HasFlag(OB_AROMATIC_BOND))
292
if (!((OBMol*)GetParent())->HasAromaticPerceived())
294
aromtyper.AssignAromaticFlags(*((OBMol*)GetParent()));
297
if ((this->GetBondOrder()==3) && !(HasFlag(OB_AROMATIC_BOND)))
261
303
bool OBBond::IsAromatic() const
263
if (((OBBond*)this)->HasFlag(OB_AROMATIC_BOND)) return(true);
305
if (((OBBond*)this)->HasFlag(OB_AROMATIC_BOND))
265
OBMol *mol = (OBMol*)((OBBond*)this)->GetParent();
266
if (!mol->HasAromaticPerceived())
308
OBMol *mol = (OBMol*)((OBBond*)this)->GetParent();
309
if (!mol->HasAromaticPerceived())
268
aromtyper.AssignAromaticFlags(*mol);
269
if (((OBBond*)this)->HasFlag(OB_AROMATIC_BOND)) return(true);
311
aromtyper.AssignAromaticFlags(*mol);
312
if (((OBBond*)this)->HasFlag(OB_AROMATIC_BOND))
319
/*! This method checks if the geometry around this bond looks unsaturated
320
by measuring the torsion angles formed by all connected atoms X-start=end-Y
321
and checking that they are close to 0 or 180 degrees */
322
bool OBBond::IsDoubleBondGeometry()
325
OBAtom *nbrStart,*nbrEnd;
326
vector<OBEdgeBase*>::iterator i,j;
327
// We concentrate on sp2 atoms with valence up to 3 and ignore the rest (like sp1 or S,P)
328
// As this is called from PerceiveBondOrders, GetHyb() may still be undefined.
329
if (_bgn->GetHyb()==1 || _bgn->GetValence()>3||
330
_end->GetHyb()==1 || _end->GetValence()>3)
333
for (nbrStart = static_cast<OBAtom*>(_bgn)->BeginNbrAtom(i); nbrStart;
334
nbrStart = static_cast<OBAtom*>(_bgn)->NextNbrAtom(i))
336
if (nbrStart != _end)
338
for (nbrEnd = static_cast<OBAtom*>(_end)->BeginNbrAtom(j);
339
nbrEnd; nbrEnd = static_cast<OBAtom*>(_end)->NextNbrAtom(j))
343
torsion=fabs(CalcTorsionAngle(nbrStart->GetVector(),
344
static_cast<OBAtom*>(_bgn)->GetVector(),
345
static_cast<OBAtom*>(_end)->GetVector(),
346
nbrEnd->GetVector()));
348
// >12&&<168 not enough
349
if (torsion > 15.0f && torsion < 165.0f)
351
// Geometry does not match a double bond
356
} // end loop for neighbors of end
358
} // end loop for neighbors of start
275
362
void OBBond::SetKSingle()
277
_flags &= (~(OB_KSINGLE_BOND|OB_KDOUBLE_BOND|OB_KTRIPLE_BOND));
278
_flags |= OB_KSINGLE_BOND;
364
_flags &= (~(OB_KSINGLE_BOND|OB_KDOUBLE_BOND|OB_KTRIPLE_BOND));
365
_flags |= OB_KSINGLE_BOND;
281
368
void OBBond::SetKDouble()
283
_flags &= (~(OB_KSINGLE_BOND|OB_KDOUBLE_BOND|OB_KTRIPLE_BOND));
284
_flags |= OB_KDOUBLE_BOND;
370
_flags &= (~(OB_KSINGLE_BOND|OB_KDOUBLE_BOND|OB_KTRIPLE_BOND));
371
_flags |= OB_KDOUBLE_BOND;
287
374
void OBBond::SetKTriple()
289
_flags &= (~(OB_KSINGLE_BOND|OB_KDOUBLE_BOND|OB_KTRIPLE_BOND));
290
_flags |= OB_KTRIPLE_BOND;
376
_flags &= (~(OB_KSINGLE_BOND|OB_KDOUBLE_BOND|OB_KTRIPLE_BOND));
377
_flags |= OB_KTRIPLE_BOND;
293
380
bool OBBond::IsKSingle()
295
if (_flags & OB_KSINGLE_BOND) return(true);
296
if (!((OBMol*)GetParent())->HasKekulePerceived())
297
((OBMol*)GetParent())->PerceiveKekuleBonds();
382
if (_flags & OB_KSINGLE_BOND)
384
if (!((OBMol*)GetParent())->HasKekulePerceived())
385
((OBMol*)GetParent())->NewPerceiveKekuleBonds();
299
return((_flags & OB_KSINGLE_BOND) != 0) ? true : false;
387
return((_flags & OB_KSINGLE_BOND) != 0) ? true : false;
302
390
bool OBBond::IsKDouble()
304
if (_flags & OB_KDOUBLE_BOND) return(true);
305
if (!((OBMol*)GetParent())->HasKekulePerceived())
306
((OBMol*)GetParent())->PerceiveKekuleBonds();
392
if (_flags & OB_KDOUBLE_BOND)
394
if (!((OBMol*)GetParent())->HasKekulePerceived())
395
((OBMol*)GetParent())->NewPerceiveKekuleBonds();
308
return((_flags & OB_KDOUBLE_BOND) != 0) ? true : false;
397
return((_flags & OB_KDOUBLE_BOND) != 0) ? true : false;
311
400
bool OBBond::IsKTriple()
313
if (_flags & OB_KTRIPLE_BOND) return(true);
314
if (!((OBMol*)GetParent())->HasKekulePerceived())
315
((OBMol*)GetParent())->PerceiveKekuleBonds();
402
if (_flags & OB_KTRIPLE_BOND)
404
if (!((OBMol*)GetParent())->HasKekulePerceived())
405
((OBMol*)GetParent())->NewPerceiveKekuleBonds();
317
return((_flags & OB_KTRIPLE_BOND) != 0) ? true : false;
407
return((_flags & OB_KTRIPLE_BOND) != 0) ? true : false;
320
410
bool OBBond::IsInRing() const
322
if (((OBBond*)this)->HasFlag(OB_RING_BOND)) return(true);
324
OBMol *mol = (OBMol*)((OBBond*)this)->GetParent();
325
if (!mol->HasRingAtomsAndBondsPerceived())
412
if (((OBBond*)this)->HasFlag(OB_RING_BOND))
415
OBMol *mol = (OBMol*)((OBBond*)this)->GetParent();
416
if (!mol->HasRingAtomsAndBondsPerceived())
327
mol->FindRingAtomsAndBonds();
328
if (((OBBond*)this)->HasFlag(OB_RING_BOND)) return(true);
418
mol->FindRingAtomsAndBonds();
419
if (((OBBond*)this)->HasFlag(OB_RING_BOND))
334
426
bool OBBond::IsClosure()
336
OBMol *mol = (OBMol*)GetParent();
337
if (!mol) return(false);
338
if (mol->HasClosureBondsPerceived()) return(HasFlag(OB_CLOSURE_BOND));
340
mol->SetClosureBondsPerceived();
344
OBBitVec uatoms,ubonds;
345
vector<OBNodeBase*> curr,next;
346
vector<OBNodeBase*>::iterator i;
347
vector<OBEdgeBase*>::iterator j;
349
uatoms.Resize(mol->NumAtoms()+1);
350
ubonds.Resize(mol->NumAtoms()+1);
352
for (;uatoms.CountBits() < (signed)mol->NumAtoms();)
428
OBMol *mol = (OBMol*)GetParent();
431
if (mol->HasClosureBondsPerceived())
432
return(HasFlag(OB_CLOSURE_BOND));
434
mol->SetClosureBondsPerceived();
436
obErrorLog.ThrowError(__FUNCTION__,
437
"Ran OpenBabel::PerceiveClosureBonds", obAuditMsg);
441
OBBitVec uatoms,ubonds;
442
vector<OBNodeBase*> curr,next;
443
vector<OBNodeBase*>::iterator i;
444
vector<OBEdgeBase*>::iterator j;
446
uatoms.Resize(mol->NumAtoms()+1);
447
ubonds.Resize(mol->NumAtoms()+1);
449
for (;uatoms.CountBits() < (signed)mol->NumAtoms();)
355
for (atom = mol->BeginAtom(i);atom;atom = mol->NextAtom(i))
356
if (!uatoms[atom->GetIdx()])
358
uatoms |= atom->GetIdx();
359
curr.push_back(atom);
363
for (;!curr.empty();)
365
for (i = curr.begin();i != curr.end();i++)
366
for (nbr = ((OBAtom*)*i)->BeginNbrAtom(j);nbr;nbr = ((OBAtom*)*i)->NextNbrAtom(j))
367
if (!uatoms[nbr->GetIdx()])
369
uatoms |= nbr->GetIdx();
370
ubonds |= (*j)->GetIdx();
452
for (atom = mol->BeginAtom(i);atom;atom = mol->NextAtom(i))
453
if (!uatoms[atom->GetIdx()])
455
uatoms |= atom->GetIdx();
456
curr.push_back(atom);
460
for (;!curr.empty();)
462
for (i = curr.begin();i != curr.end();i++)
463
for (nbr = ((OBAtom*)*i)->BeginNbrAtom(j);nbr;nbr = ((OBAtom*)*i)->NextNbrAtom(j))
464
if (!uatoms[nbr->GetIdx()])
466
uatoms |= nbr->GetIdx();
467
ubonds |= (*j)->GetIdx();
379
for (bond = mol->BeginBond(j);bond;bond = mol->NextBond(j))
380
if (!ubonds[bond->GetIdx()])
383
return(HasFlag(OB_CLOSURE_BOND));
476
for (bond = mol->BeginBond(j);bond;bond = mol->NextBond(j))
477
if (!ubonds[bond->GetIdx()])
480
return(HasFlag(OB_CLOSURE_BOND));
386
483
double OBBond::GetEquibLength()
390
// CorrectedBondRad will always return a # now
391
// if (!CorrectedBondRad(GetBeginAtom(),rad1)) return(0.0);
392
// if (!CorrectedBondRad(GetEndAtom(),rad2)) return(0.0);
394
begin = GetBeginAtom();
396
length = etab.CorrectedBondRad(begin->GetAtomicNum(), begin->GetHyb())
397
+ etab.CorrectedBondRad(end->GetAtomicNum(), end->GetHyb());
399
if (IsAromatic()) length *= 0.93;
400
else if (GetBO() == 2) length *= 0.91;
401
else if (GetBO() == 3) length *= 0.87;
487
// CorrectedBondRad will always return a # now
488
// if (!CorrectedBondRad(GetBeginAtom(),rad1)) return(0.0);
489
// if (!CorrectedBondRad(GetEndAtom(),rad2)) return(0.0);
491
begin = GetBeginAtom();
493
length = etab.CorrectedBondRad(begin->GetAtomicNum(), begin->GetHyb())
494
+ etab.CorrectedBondRad(end->GetAtomicNum(), end->GetHyb());
498
else if (GetBO() == 2)
500
else if (GetBO() == 3)
405
505
double OBBond::GetLength()
409
begin = GetBeginAtom();
412
d2 = SQUARE(begin->GetX() - end->GetX());
413
d2 += SQUARE(begin->GetY() - end->GetY());
414
d2 += SQUARE(begin->GetZ() - end->GetZ());
509
begin = GetBeginAtom();
512
d2 = SQUARE(begin->GetX() - end->GetX());
513
d2 += SQUARE(begin->GetY() - end->GetY());
514
d2 += SQUARE(begin->GetZ() - end->GetZ());
419
519
// OBGenericData methods
420
520
bool OBBond::HasData(string &s)
421
//returns true if the generic attribute/value pair exists
521
//returns true if the generic attribute/value pair exists
423
if (_vdata.empty()) return(false);
425
526
vector<OBGenericData*>::iterator i;
427
528
for (i = _vdata.begin();i != _vdata.end();i++)
428
529
if ((*i)->GetAttribute() == s)
434
535
bool OBBond::HasData(const char *s)
435
//returns true if the generic attribute/value pair exists
536
//returns true if the generic attribute/value pair exists
437
if (_vdata.empty()) return(false);
439
541
vector<OBGenericData*>::iterator i;
441
543
for (i = _vdata.begin();i != _vdata.end();i++)
442
544
if ((*i)->GetAttribute() == s)
448
bool OBBond::HasData(obDataType dt)
449
//returns true if the generic attribute/value pair exists
550
bool OBBond::HasData(unsigned int dt)
551
//returns true if the generic attribute/value pair exists
451
if (_vdata.empty()) return(false);
453
556
vector<OBGenericData*>::iterator i;
455
558
for (i = _vdata.begin();i != _vdata.end();i++)
456
559
if ((*i)->GetDataType() == dt)
462
565
OBGenericData *OBBond::GetData(string &s)
463
//returns the value given an attribute
566
//returns the value given an attribute
465
568
vector<OBGenericData*>::iterator i;
467
570
for (i = _vdata.begin();i != _vdata.end();i++)
468
if ((*i)->GetAttribute() == s)
571
if ((*i)->GetAttribute() == s)
474
577
OBGenericData *OBBond::GetData(const char *s)
475
//returns the value given an attribute
477
vector<OBGenericData*>::iterator i;
479
for (i = _vdata.begin();i != _vdata.end();i++)
480
if ((*i)->GetAttribute() == s)
486
OBGenericData *OBBond::GetData(obDataType dt)
488
vector<OBGenericData*>::iterator i;
489
for (i = _vdata.begin();i != _vdata.end();i++)
490
if ((*i)->GetDataType() == dt)
495
void OBBond::DeleteData(obDataType dt)
497
vector<OBGenericData*> vdata;
498
vector<OBGenericData*>::iterator i;
499
for (i = _vdata.begin();i != _vdata.end();i++)
500
if ((*i)->GetDataType() == dt) delete *i;
501
else vdata.push_back(*i);
578
//returns the value given an attribute
580
vector<OBGenericData*>::iterator i;
582
for (i = _vdata.begin();i != _vdata.end();i++)
583
if ((*i)->GetAttribute() == s)
589
OBGenericData *OBBond::GetData(unsigned int dt)
591
vector<OBGenericData*>::iterator i;
592
for (i = _vdata.begin();i != _vdata.end();i++)
593
if ((*i)->GetDataType() == dt)
598
void OBBond::DeleteData(unsigned int dt)
600
vector<OBGenericData*> vdata;
601
vector<OBGenericData*>::iterator i;
602
for (i = _vdata.begin();i != _vdata.end();i++)
603
if ((*i)->GetDataType() == dt)
505
610
void OBBond::DeleteData(vector<OBGenericData*> &vg)
507
vector<OBGenericData*> vdata;
508
vector<OBGenericData*>::iterator i,j;
612
vector<OBGenericData*> vdata;
613
vector<OBGenericData*>::iterator i,j;
511
for (i = _vdata.begin();i != _vdata.end();i++)
514
for (j = vg.begin();j != vg.end();j++)
521
else vdata.push_back(*i);
616
for (i = _vdata.begin();i != _vdata.end();i++)
619
for (j = vg.begin();j != vg.end();j++)
526
633
void OBBond::DeleteData(OBGenericData *gd)
528
vector<OBGenericData*>::iterator i;
529
for (i = _vdata.begin();i != _vdata.end();i++)
635
vector<OBGenericData*>::iterator i;
636
for (i = _vdata.begin();i != _vdata.end();i++)
645
} // end namespace OpenBabel
648
//! \brief Handle OBBond class