in packages/ketcher-core/src/domain/serializers/smi/stereocenters.js [30:150]
Stereocenters.prototype.buildFromBonds = function (
/* const int *atom_types, const int *atom_groups, const int *bond_orientations, */ ignoreErrors,
) {
const atoms = this.molecule.atoms;
const bonds = this.molecule.bonds;
/*
this is a set of atoms that are likely to belong to allene structures and
therefore should not be considered as potential stereocenters in the code below,
as allenes cannot be encoded in the SMILES notation
*/
const alleneMask = new Pile();
atoms.forEach((atom, aid) => {
const neiList = this.getNeighbors.call(this.context, aid);
if (neiList.length !== 2) return false;
const nei1 = neiList[0];
const nei2 = neiList[1];
// check atom labels
if (
[aid, nei1.aid, nei2.aid].findIndex(
(aid) => ['C', 'Si'].indexOf(atoms.get(aid).label) < 0,
this,
) >= 0
) {
return false;
}
// check adjacent bond types
if (
[nei1.bid, nei2.bid].findIndex(
(bid) => bonds.get(bid).type !== Bond.PATTERN.TYPE.DOUBLE,
this,
) >= 0
) {
return false;
}
// get the other neighbors of the two adjacent atoms except for the central atom
const nei1nei = this.getNeighbors
.call(this.context, nei1.aid)
.filter((nei) => nei.aid !== aid);
const nei2nei = this.getNeighbors
.call(this.context, nei2.aid)
.filter((nei) => nei.aid !== aid);
if (
nei1nei.length < 1 ||
nei1nei.length > 2 ||
nei2nei.length < 1 ||
nei2nei.length > 2
) {
return false;
}
if (
nei1nei
.concat(nei2nei)
.findIndex(
(nei) => bonds.get(nei.bid).type !== Bond.PATTERN.TYPE.SINGLE,
this,
) >= 0
) {
return false;
}
if (
nei1nei
.concat(nei2nei)
.findIndex(
(nei) => bonds.get(nei.bid).stereo === Bond.PATTERN.STEREO.EITHER,
this,
) >= 0
) {
return false;
}
alleneMask.add(nei1.aid).add(nei2.aid);
return true;
});
if (alleneMask.size > 0) {
// TODO: add error handler call
// legacy message: This structure may contain allenes, which cannot be represented in the SMILES notation. Relevant stereo-information will be discarded.
atoms.forEach((atom, aid) => {
if (alleneMask.has(aid)) return;
/*
if (atom_types[atom_idx] == 0)
continue;
*/
const neiList = this.getNeighbors.call(this.context, aid);
let stereocenter = false;
neiList.find(function (nei) {
const bond = this.molecule.bonds.get(nei.bid);
if (bond.type === Bond.PATTERN.TYPE.SINGLE && bond.begin === aid) {
if (
bond.stereo === Bond.PATTERN.STEREO.UP ||
bond.stereo === Bond.PATTERN.STEREO.DOWN
) {
stereocenter = true;
return true;
}
}
return false;
}, this);
if (!stereocenter) return;
if (ignoreErrors) {
this.buildOneCenter(
aid /* , atom_groups[atom_idx], atom_types[atom_idx], bond_orientations */,
);
} else {
this.buildOneCenter(
aid /* , atom_groups[atom_idx], atom_types[atom_idx], bond_orientations */,
);
}
});
}
};