mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
325 lines
9.1 KiB
C++
325 lines
9.1 KiB
C++
//
|
|
// Copyright (C) 2001-2014 Greg Landrum and Rational Discovery LLC
|
|
//
|
|
// @@ All Rights Reserved @@
|
|
// This file is part of the RDKit.
|
|
// The contents are covered by the terms of the BSD license
|
|
// which is included in the file license.txt, found at the root
|
|
// of the RDKit source tree.
|
|
//
|
|
#ifndef _RD_BOND_H
|
|
#define _RD_BOND_H
|
|
|
|
// std stuff
|
|
#include <iostream>
|
|
|
|
// Ours
|
|
#include <RDGeneral/Invariant.h>
|
|
#include <Query/QueryObjects.h>
|
|
#include <RDGeneral/types.h>
|
|
#include <RDGeneral/RDProps.h>
|
|
#include <GraphMol/details.h>
|
|
#include <boost/foreach.hpp>
|
|
|
|
namespace RDKit {
|
|
class ROMol;
|
|
class RWMol;
|
|
class Atom;
|
|
typedef boost::shared_ptr<Atom> ATOM_SPTR;
|
|
|
|
//! class for representing a bond
|
|
/*!
|
|
|
|
<b>Notes:</b>
|
|
- many of the methods of Atom require that the Atom be associated
|
|
with a molecule (an ROMol).
|
|
- each Bond maintains a Dict of \c properties:
|
|
- Each \c property is keyed by name and can store an
|
|
arbitrary type.
|
|
- \c Properties can be marked as \c calculated, in which case
|
|
they will be cleared when the \c clearComputedProps() method
|
|
is called.
|
|
- Because they have no impact upon chemistry, all \c property
|
|
operations are \c const, this allows extra flexibility for
|
|
clients who need to store extra data on Bond objects.
|
|
|
|
*/
|
|
class Bond : public RDProps {
|
|
friend class RWMol;
|
|
friend class ROMol;
|
|
|
|
public:
|
|
typedef boost::shared_ptr<Bond> BOND_SPTR;
|
|
// FIX: grn...
|
|
typedef Queries::Query<int, Bond const *, true> QUERYBOND_QUERY;
|
|
|
|
//! the type of Bond
|
|
typedef enum {
|
|
UNSPECIFIED = 0,
|
|
SINGLE,
|
|
DOUBLE,
|
|
TRIPLE,
|
|
QUADRUPLE,
|
|
QUINTUPLE,
|
|
HEXTUPLE,
|
|
ONEANDAHALF,
|
|
TWOANDAHALF,
|
|
THREEANDAHALF,
|
|
FOURANDAHALF,
|
|
FIVEANDAHALF,
|
|
AROMATIC,
|
|
IONIC,
|
|
HYDROGEN,
|
|
THREECENTER,
|
|
DATIVEONE, //!< one-electron dative (e.g. from a C in a Cp ring to a metal)
|
|
DATIVE, //!< standard two-electron dative
|
|
DATIVEL, //!< standard two-electron dative
|
|
DATIVER, //!< standard two-electron dative
|
|
OTHER,
|
|
ZERO //!< Zero-order bond (from
|
|
// http://pubs.acs.org/doi/abs/10.1021/ci200488k)
|
|
} BondType;
|
|
|
|
//! the bond's direction (for chirality)
|
|
typedef enum {
|
|
NONE = 0, //!< no special style
|
|
BEGINWEDGE, //!< wedged: narrow at begin
|
|
BEGINDASH, //!< dashed: narrow at begin
|
|
// FIX: this may not really be adequate
|
|
ENDDOWNRIGHT, //!< for cis/trans
|
|
ENDUPRIGHT, //!< ditto
|
|
EITHERDOUBLE, //!< a "crossed" double bond
|
|
UNKNOWN, //!< intentionally unspecified stereochemistry
|
|
} BondDir;
|
|
|
|
//! the nature of the bond's stereochem (for cis/trans)
|
|
typedef enum { // stereochemistry of double bonds
|
|
STEREONONE = 0, // no special style
|
|
STEREOANY, // intentionally unspecified
|
|
// -- Put any true specifications about this point so
|
|
// that we can do comparisons like if(bond->getStereo()>Bond::STEREOANY)
|
|
STEREOZ, // Z double bond
|
|
STEREOE, // E double bond
|
|
} BondStereo;
|
|
|
|
Bond();
|
|
//! construct with a particular BondType
|
|
explicit Bond(BondType bT);
|
|
Bond(const Bond &other);
|
|
virtual ~Bond();
|
|
Bond &operator=(const Bond &other);
|
|
|
|
//! returns a copy
|
|
/*!
|
|
<b>Note:</b> the caller is responsible for <tt>delete</tt>ing
|
|
the returned pointer.
|
|
*/
|
|
virtual Bond *copy() const;
|
|
|
|
//! returns our \c bondType
|
|
BondType getBondType() const { return static_cast<BondType>(d_bondType); };
|
|
//! sets our \c bondType
|
|
void setBondType(BondType bT) { d_bondType = bT; };
|
|
//! \brief returns our \c bondType as a double
|
|
//! (e.g. SINGLE->1.0, AROMATIC->1.5, etc.)
|
|
double getBondTypeAsDouble() const;
|
|
|
|
//! returns our contribution to the explicit valence of an Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
double getValenceContrib(const Atom *at) const;
|
|
// \overload
|
|
double getValenceContrib(ATOM_SPTR at) const;
|
|
|
|
//! sets our \c isAromatic flag
|
|
void setIsAromatic(bool what) { df_isAromatic = what; };
|
|
//! returns the status of our \c isAromatic flag
|
|
bool getIsAromatic() const { return df_isAromatic; };
|
|
|
|
//! sets our \c isConjugated flag
|
|
void setIsConjugated(bool what) { df_isConjugated = what; };
|
|
//! returns the status of our \c isConjugated flag
|
|
bool getIsConjugated() const { return df_isConjugated; };
|
|
|
|
//! returns a reference to the ROMol that owns this Bond
|
|
ROMol &getOwningMol() const {
|
|
PRECONDITION(dp_mol, "no owner");
|
|
return *dp_mol;
|
|
};
|
|
//! sets our owning molecule
|
|
void setOwningMol(ROMol *other);
|
|
//! sets our owning molecule
|
|
void setOwningMol(ROMol &other) { setOwningMol(&other); };
|
|
|
|
//! returns our index within the ROMol
|
|
/*!
|
|
<b>Notes:</b>
|
|
- this makes no sense if we do not have an owning molecule
|
|
|
|
*/
|
|
unsigned int getIdx() const { return d_index; };
|
|
//! sets our index within the ROMol
|
|
/*!
|
|
<b>Notes:</b>
|
|
- this makes no sense if we do not have an owning molecule
|
|
- the index should be <tt>< this->getOwningMol()->getNumBonds()</tt>
|
|
*/
|
|
void setIdx(unsigned int index) { d_index = index; };
|
|
|
|
//! returns the index of our begin Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- this makes no sense if we do not have an owning molecule
|
|
*/
|
|
unsigned int getBeginAtomIdx() const { return d_beginAtomIdx; };
|
|
|
|
//! returns the index of our end Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- this makes no sense if we do not have an owning molecule
|
|
*/
|
|
unsigned int getEndAtomIdx() const { return d_endAtomIdx; };
|
|
|
|
//! given the index of one Atom, returns the index of the other
|
|
/*!
|
|
<b>Notes:</b>
|
|
- this makes no sense if we do not have an owning molecule
|
|
*/
|
|
unsigned int getOtherAtomIdx(unsigned int thisIdx) const;
|
|
|
|
//! sets the index of our begin Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
void setBeginAtomIdx(unsigned int what);
|
|
//! sets the index of our end Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
void setEndAtomIdx(unsigned int what);
|
|
|
|
//! sets our begin Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
void setBeginAtom(Atom *at);
|
|
//! \overload
|
|
void setBeginAtom(ATOM_SPTR at);
|
|
//! sets our end Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
void setEndAtom(Atom *at);
|
|
//! \overload
|
|
void setEndAtom(ATOM_SPTR at);
|
|
|
|
//! returns a pointer to our begin Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
Atom *getBeginAtom() const;
|
|
//! returns a pointer to our end Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
Atom *getEndAtom() const;
|
|
//! returns a pointer to the other Atom
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
Atom *getOtherAtom(Atom const *what) const;
|
|
|
|
// ------------------------------------
|
|
// Please see the note in Atom.h for some explanation
|
|
// of these methods
|
|
// ------------------------------------
|
|
|
|
// This method can be used to distinguish query bonds from standard bonds
|
|
virtual bool hasQuery() const { return false; };
|
|
|
|
// FIX: the const crap here is all mucked up.
|
|
//! NOT CALLABLE
|
|
virtual void setQuery(QUERYBOND_QUERY *what);
|
|
//! NOT CALLABLE
|
|
virtual QUERYBOND_QUERY *getQuery() const;
|
|
|
|
//! NOT CALLABLE
|
|
virtual void expandQuery(
|
|
QUERYBOND_QUERY *what,
|
|
Queries::CompositeQueryType how = Queries::COMPOSITE_AND,
|
|
bool maintainOrder = true);
|
|
|
|
//! returns whether or not we match the argument
|
|
/*!
|
|
<b>Notes:</b>
|
|
- for Bond objects, "match" means that either one of the Bonds
|
|
has \c bondType Bond::UNSPECIFIED or both Bonds have the
|
|
same \c bondType.
|
|
*/
|
|
virtual bool Match(Bond const *what) const;
|
|
//! \overload
|
|
virtual bool Match(const Bond::BOND_SPTR what) const;
|
|
|
|
//! sets our direction
|
|
void setBondDir(BondDir what) { d_dirTag = what; };
|
|
//! returns our direction
|
|
BondDir getBondDir() const { return static_cast<BondDir>(d_dirTag); };
|
|
|
|
//! sets our stereo code
|
|
void setStereo(BondStereo what) { d_stereo = what; };
|
|
//! returns our stereo code
|
|
BondStereo getStereo() const { return static_cast<BondStereo>(d_stereo); };
|
|
|
|
//! returns the indices of our stereo atoms
|
|
const INT_VECT &getStereoAtoms() const {
|
|
if (!dp_stereoAtoms) {
|
|
const_cast<Bond *>(this)->dp_stereoAtoms = new INT_VECT();
|
|
}
|
|
return *dp_stereoAtoms;
|
|
};
|
|
//! \overload
|
|
INT_VECT &getStereoAtoms() {
|
|
if (!dp_stereoAtoms) dp_stereoAtoms = new INT_VECT();
|
|
return *dp_stereoAtoms;
|
|
};
|
|
|
|
//! calculates any of our lazy \c properties
|
|
/*!
|
|
<b>Notes:</b>
|
|
- requires an owning molecule
|
|
*/
|
|
void updatePropertyCache(bool strict = true) { (void)strict; }
|
|
|
|
protected:
|
|
//! sets our owning molecule
|
|
// void setOwningMol(ROMol *other);
|
|
//! sets our owning molecule
|
|
// void setOwningMol(ROMol &other) {setOwningMol(&other);};
|
|
bool df_isAromatic;
|
|
bool df_isConjugated;
|
|
boost::uint8_t d_bondType;
|
|
boost::uint8_t d_dirTag;
|
|
boost::uint8_t d_stereo;
|
|
atomindex_t d_index;
|
|
atomindex_t d_beginAtomIdx, d_endAtomIdx;
|
|
ROMol *dp_mol;
|
|
INT_VECT *dp_stereoAtoms;
|
|
|
|
void initBond();
|
|
};
|
|
};
|
|
|
|
//! allows Bond objects to be dumped to streams
|
|
extern std::ostream &operator<<(std::ostream &target, const RDKit::Bond &b);
|
|
|
|
#endif
|