mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-04 21:54:27 +08:00
261 lines
7.0 KiB
C++
Executable File
261 lines
7.0 KiB
C++
Executable File
// $Id$
|
|
//
|
|
// Copyright (C) 2001-2006 Greg Landrum and Rational Discovery LLC
|
|
//
|
|
// @@ All Rights Reserved @@
|
|
//
|
|
#include "Bond.h"
|
|
#include "Atom.h"
|
|
#include "ROMol.h"
|
|
#include <RDGeneral/Invariant.h>
|
|
|
|
namespace RDKit {
|
|
|
|
Bond::Bond() {
|
|
initBond();
|
|
};
|
|
|
|
Bond::Bond(BondType bT) {
|
|
initBond();
|
|
d_bondType = bT;
|
|
};
|
|
|
|
Bond::Bond(const Bond &other){
|
|
// NOTE: we do *not* copy ownership!
|
|
dp_mol = 0;
|
|
d_bondType = other.d_bondType;
|
|
d_beginAtomIdx = other.d_beginAtomIdx;
|
|
d_endAtomIdx = other.d_endAtomIdx;
|
|
d_dirTag = other.d_dirTag;
|
|
d_stereo = other.d_stereo;
|
|
d_stereoAtoms = other.d_stereoAtoms;
|
|
df_isAromatic = other.df_isAromatic;
|
|
df_isConjugated = other.df_isConjugated;
|
|
d_index = other.d_index;
|
|
if(other.dp_props){
|
|
dp_props = new Dict(*other.dp_props);
|
|
} else {
|
|
dp_props = new Dict();
|
|
//STR_VECT computed;
|
|
//dp_props->setVal("computedProps", computed);
|
|
}
|
|
}
|
|
|
|
Bond::~Bond()
|
|
{
|
|
if(dp_props) delete dp_props;
|
|
}
|
|
|
|
Bond &Bond::operator=(const Bond &other){
|
|
// FIX: should we copy molecule ownership? I don't think so.
|
|
// FIX: how to deal with atom indices?
|
|
initBond();
|
|
dp_mol = other.dp_mol;
|
|
d_bondType = other.d_bondType;
|
|
d_beginAtomIdx = other.d_beginAtomIdx;
|
|
d_endAtomIdx = other.d_endAtomIdx;
|
|
d_dirTag = other.d_dirTag;
|
|
d_stereoAtoms = other.d_stereoAtoms;
|
|
df_isAromatic = other.df_isAromatic;
|
|
df_isConjugated = other.df_isConjugated;
|
|
d_index = other.d_index;
|
|
if(dp_props) delete dp_props;
|
|
if(other.dp_props)
|
|
dp_props = new Dict(*other.dp_props);
|
|
return *this;
|
|
}
|
|
|
|
Bond *Bond::copy() const {
|
|
Bond *res = new Bond(*this);
|
|
return res;
|
|
}
|
|
|
|
|
|
void Bond::setOwningMol(ROMol *other)
|
|
{
|
|
// FIX: doesn't update topology
|
|
dp_mol = other;
|
|
}
|
|
|
|
unsigned int Bond::getOtherAtomIdx(const unsigned int thisIdx) const
|
|
{
|
|
PRECONDITION(d_beginAtomIdx == thisIdx ||
|
|
d_endAtomIdx == thisIdx, "bad index");
|
|
if( d_beginAtomIdx == thisIdx ) return d_endAtomIdx;
|
|
else if (d_endAtomIdx == thisIdx) return d_beginAtomIdx;
|
|
// we cannot actually get down here
|
|
return 0;
|
|
}
|
|
|
|
void Bond::setBeginAtomIdx(unsigned int what) {
|
|
if(dp_mol) RANGE_CHECK(0,what,getOwningMol().getNumAtoms()-1);
|
|
d_beginAtomIdx = what;
|
|
};
|
|
|
|
void Bond::setEndAtomIdx(unsigned int what) {
|
|
if(dp_mol) RANGE_CHECK(0,what,getOwningMol().getNumAtoms()-1);
|
|
d_endAtomIdx = what;
|
|
};
|
|
|
|
|
|
void Bond::setBeginAtom(Atom *at) {
|
|
PRECONDITION( dp_mol != 0, "no owning molecule for bond");
|
|
setBeginAtomIdx(at->getIdx());
|
|
}
|
|
void Bond::setBeginAtom(Atom::ATOM_SPTR at) {
|
|
PRECONDITION( dp_mol != 0, "no owning molecule for bond");
|
|
setBeginAtomIdx(at->getIdx());
|
|
}
|
|
|
|
void Bond::setEndAtom(Atom *at) {
|
|
PRECONDITION( dp_mol != 0, "no owning molecule for bond");
|
|
setEndAtomIdx(at->getIdx());
|
|
}
|
|
void Bond::setEndAtom(Atom::ATOM_SPTR at) {
|
|
PRECONDITION( dp_mol != 0, "no owning molecule for bond");
|
|
setEndAtomIdx(at->getIdx());
|
|
}
|
|
|
|
Atom *Bond::getBeginAtom() const {
|
|
PRECONDITION( dp_mol != 0, "no owning molecule for bond");
|
|
return dp_mol->getAtomWithIdx(d_beginAtomIdx);
|
|
};
|
|
Atom *Bond::getEndAtom() const {
|
|
PRECONDITION( dp_mol != 0, "no owning molecule for bond");
|
|
return dp_mol->getAtomWithIdx(d_endAtomIdx);
|
|
};
|
|
Atom *Bond::getOtherAtom(Atom const *what) const {
|
|
PRECONDITION( dp_mol != 0, "no owning molecule for bond");
|
|
|
|
return dp_mol->getAtomWithIdx(getOtherAtomIdx(what->getIdx()));
|
|
};
|
|
|
|
|
|
double Bond::getBondTypeAsDouble() const {
|
|
switch(getBondType()){
|
|
case UNSPECIFIED: return 0; break;
|
|
case SINGLE: return 1; break;
|
|
case DOUBLE: return 2; break;
|
|
case TRIPLE: return 3; break;
|
|
case QUADRUPLE: return 4; break;
|
|
case QUINTUPLE: return 5; break;
|
|
case HEXTUPLE: return 6; break;
|
|
case ONEANDAHALF: return 1.5; break;
|
|
case TWOANDAHALF: return 2.5; break;
|
|
case THREEANDAHALF: return 3.5; break;
|
|
case FOURANDAHALF: return 4.5; break;
|
|
case FIVEANDAHALF: return 5.5; break;
|
|
case AROMATIC: return 1.5; break;
|
|
case DATIVEONE: return 1.0; break; // FIX: this should probably be different
|
|
case DATIVE: return 1.0; break; //FIX: again probably wrong
|
|
default:
|
|
UNDER_CONSTRUCTION("Bad bond type");
|
|
}
|
|
}
|
|
|
|
double Bond::getValenceContrib(Atom::ATOM_SPTR at) const {
|
|
return getValenceContrib(at.get());
|
|
}
|
|
|
|
double Bond::getValenceContrib(const Atom *atom) const {
|
|
switch(getBondType()){
|
|
case UNSPECIFIED: return 0; break;
|
|
case SINGLE: return 1; break;
|
|
case DOUBLE: return 2; break;
|
|
case TRIPLE: return 3; break;
|
|
case QUADRUPLE: return 4; break;
|
|
case QUINTUPLE: return 5; break;
|
|
case HEXTUPLE: return 6; break;
|
|
case ONEANDAHALF: return 1.5; break;
|
|
case TWOANDAHALF: return 2.5; break;
|
|
case THREEANDAHALF: return 3.5; break;
|
|
case FOURANDAHALF: return 4.5; break;
|
|
case FIVEANDAHALF: return 5.5; break;
|
|
case AROMATIC: return 1.5; break;
|
|
case DATIVEONE:
|
|
if(atom->getIdx()==getEndAtomIdx())return 1.0;
|
|
else return 0.0;
|
|
break;
|
|
case DATIVE:
|
|
if(atom->getIdx()==getEndAtomIdx())return 1.0;
|
|
else return 0.0;
|
|
break;
|
|
default:
|
|
UNDER_CONSTRUCTION("Bad bond type");
|
|
|
|
}
|
|
}
|
|
|
|
void Bond::setQuery(QUERYBOND_QUERY *what) {
|
|
// Bonds don't have queries at the moment because I have not
|
|
// yet figured out what a good base query should be.
|
|
// It would be nice to be able to do substructure searches
|
|
// using molecules alone, so it'd be nice if we got this
|
|
// issue resolved ASAP.
|
|
PRECONDITION(0,"plain bonds have no Query");
|
|
}
|
|
|
|
Bond::QUERYBOND_QUERY *Bond::getQuery() const {
|
|
PRECONDITION(0,"plain bonds have no Query");
|
|
return NULL;
|
|
};
|
|
|
|
bool Bond::Match(Bond const *what) const{
|
|
bool res;
|
|
if(getBondType()==Bond::UNSPECIFIED ||
|
|
what->getBondType()==Bond::UNSPECIFIED){
|
|
res = true;
|
|
} else {
|
|
res = getBondType() == what->getBondType();
|
|
}
|
|
return res;
|
|
};
|
|
|
|
bool Bond::Match(const Bond::BOND_SPTR what) const {
|
|
return Match(what.get());
|
|
};
|
|
|
|
void Bond::expandQuery(Bond::QUERYBOND_QUERY *what,
|
|
Queries::CompositeQueryType how,
|
|
bool maintainOrder) {
|
|
PRECONDITION(0,"plain bonds have no query");
|
|
};
|
|
|
|
void Bond::initBond(){
|
|
d_bondType = UNSPECIFIED;
|
|
d_dirTag = NONE;
|
|
d_stereo = STEREONONE;
|
|
d_stereoAtoms.clear();
|
|
dp_mol = 0;
|
|
d_beginAtomIdx = 0;
|
|
d_endAtomIdx = 0;
|
|
df_isAromatic = 0;
|
|
d_index = 0;
|
|
df_isConjugated = 0;
|
|
dp_props = new Dict();
|
|
// ok every bond contains a property entry called "computedProps" which provides
|
|
// list of property keys that correspond to value that have been computed
|
|
// this can used to blow out all computed properties while leaving the rest along
|
|
// initialize this list to an empty vector of strings
|
|
//STR_VECT computed;
|
|
//dp_props->setVal("computedProps", computed);
|
|
|
|
};
|
|
|
|
}; // end o' namespace
|
|
|
|
|
|
std::ostream & operator<<(std::ostream& target, const RDKit::Bond &bond){
|
|
target << bond.getIdx() << " ";
|
|
target << bond.getBeginAtomIdx() << "->" << bond.getEndAtomIdx();
|
|
target << " order: " << bond.getBondType();
|
|
if(bond.getBondDir())
|
|
target << " dir: " << bond.getBondDir();
|
|
if(bond.getStereo())
|
|
target << " stereo: " << bond.getStereo();
|
|
target << " conj?: " << bond.getIsConjugated();
|
|
target << " aromatic?: " << bond.getIsAromatic();
|
|
|
|
return target;
|
|
}
|