Skip to content

Commit

Permalink
feat(core): promote nonbonding_electrons to public API
Browse files Browse the repository at this point in the history
  • Loading branch information
jnooree committed Dec 12, 2023
1 parent 523824a commit 2d781e8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
13 changes: 13 additions & 0 deletions include/nuri/core/molecule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,8 @@ namespace internal {
extern constants::Hybridization from_degree(int total_degree,
int nb_electrons);

extern int nonbonding_electrons(const AtomData &data, int total_valence);

extern int count_pi_e(Molecule::Atom atom, int total_valence);
} // namespace internal

Expand Down Expand Up @@ -1836,6 +1838,17 @@ inline int sum_bond_order(Molecule::Atom atom) {
return internal::sum_bond_order(atom, true);
}

/**
* @brief Get the predicted non-bonding electron count of the atom.
* @param atom An atom.
* @return Predicted non-bonding electron count of the atom.
* @note This function might return a negative value if the atom is not
* chemically valid.
*/
inline int nonbonding_electrons(Molecule::Atom atom) {
return internal::nonbonding_electrons(atom.data(), sum_bond_order(atom));
}

/**
* @brief Get "effective" element of the atom.
* @param atom An atom.
Expand Down
28 changes: 16 additions & 12 deletions src/core/molecule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "nuri/utils.h"

namespace nuri {
using internal::nonbonding_electrons;

AtomData::AtomData(const Element &element, int implicit_hydrogens,
int formal_charge, constants::Hybridization hyb,
double partial_charge, int mass_number, bool is_aromatic,
Expand Down Expand Up @@ -516,13 +518,6 @@ MoleculeSanitizer::MoleculeSanitizer(Molecule &molecule)
}

namespace {
int nonbonding_electrons(Molecule::Atom atom, const int total_valence) {
// Don't use effective_element* here, this function must return negative
// values for any chemically invalid combinations of the three values
return atom.data().element().valence_electrons() - total_valence
- atom.data().formal_charge();
}

bool is_conjugated_candidate(Molecule::Atom atom) {
const AtomData &data = atom.data();
// Consider main-group atoms only
Expand Down Expand Up @@ -587,8 +582,10 @@ bool MoleculeSanitizer::sanitize_conjugated() {
&& dst.data().atomic_number() != 0) {
// Single - single bond -> conjugated if curr has lone pair and
// next doesn't, or vice versa, or any of them is dummy
const int src_nbe = nonbonding_electrons(src, valences_[curr]),
dst_nbe = nonbonding_electrons(dst, valences_[dst.id()]);
const int src_nbe =
nonbonding_electrons(src.data(), valences_[curr]),
dst_nbe =
nonbonding_electrons(dst.data(), valences_[dst.id()]);
if ((src_nbe > 0 && dst_nbe > 0)
|| (src_nbe <= 0 && dst_nbe <= 0)) {
continue;
Expand Down Expand Up @@ -642,8 +639,15 @@ namespace internal {
return *elem;
}

int nonbonding_electrons(const AtomData &data, const int total_valence) {
// Don't use effective_element* here, this function must return negative
// values for any chemically invalid combinations of the three values
return data.element().valence_electrons() - total_valence
- data.formal_charge();
}

int count_pi_e(Molecule::Atom atom, int total_valence) {
const int nb_electrons = nonbonding_electrons(atom, total_valence);
const int nb_electrons = nonbonding_electrons(atom.data(), total_valence);
ABSL_DLOG_IF(WARNING, nb_electrons < 0)
<< "Negative nonbonding electrons for atom " << atom.id() << " ("
<< atom.data().element().symbol() << "): " << nb_electrons;
Expand Down Expand Up @@ -864,7 +868,7 @@ namespace {
return true;
}

int nbe = std::max(0, nonbonding_electrons(atom, total_valence));
int nbe = std::max(0, nonbonding_electrons(atom.data(), total_valence));
if (nbe < 0) {
nbe = 0;
ABSL_LOG(INFO) << "Valence electrons exceeded for "
Expand Down Expand Up @@ -943,7 +947,7 @@ namespace {
return true;
}

int nbe = nonbonding_electrons(atom, total_valence);
int nbe = nonbonding_electrons(atom.data(), total_valence);
if (nbe < 0) {
ABSL_LOG(WARNING) << "Valence electrons exceeded for "
<< format_atom_common(atom, false) << ": total valence "
Expand Down

0 comments on commit 2d781e8

Please sign in to comment.