Current Dev State

This commit is contained in:
Tim Lorsbach
2025-06-23 20:13:54 +02:00
parent b4f9bb277d
commit ded50edaa2
22617 changed files with 4345095 additions and 174 deletions

View File

@ -0,0 +1,212 @@
/****************************************************************************
* Copyright 2017 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
var Map = require('../../util/map');
var Vec2 = require('../../util/vec2');
var Struct = require('../struct');
function CisTrans(mol, neighborsFunc, context) {
this.molecule = mol;
this.bonds = new Map();
this.getNeighbors = neighborsFunc;
this.context = context;
}
CisTrans.PARITY = {
NONE: 0,
CIS: 1,
TRANS: 2
};
CisTrans.prototype.each = function (func, context) {
this.bonds.each(func, context);
};
CisTrans.prototype.getParity = function (idx) {
return this.bonds.get(idx).parity;
};
CisTrans.prototype.getSubstituents = function (idx) {
return this.bonds.get(idx).substituents;
};
CisTrans.prototype.sameside = function (beg, end, neiBeg, neiEnd) {
var diff = Vec2.diff(beg, end);
var norm = new Vec2(-diff.y, diff.x);
if (!norm.normalize())
return 0;
var normBeg = Vec2.diff(neiBeg, beg);
var normEnd = Vec2.diff(neiEnd, end);
if (!normBeg.normalize())
return 0;
if (!normEnd.normalize())
return 0;
var prodBeg = Vec2.dot(normBeg, norm);
var prodEnd = Vec2.dot(normEnd, norm);
if (Math.abs(prodBeg) < 0.001 || Math.abs(prodEnd) < 0.001)
return 0;
return (prodBeg * prodEnd > 0) ? 1 : -1;
};
CisTrans.prototype.samesides = function (iBeg, iEnd, iNeiBeg, iNeiEnd) {
return this.sameside(this.molecule.atoms.get(iBeg).pp, this.molecule.atoms.get(iEnd).pp,
this.molecule.atoms.get(iNeiBeg).pp, this.molecule.atoms.get(iNeiEnd).pp);
};
CisTrans.prototype.sortSubstituents = function (substituents) { // eslint-disable-line max-statements
var h0 = this.molecule.atoms.get(substituents[0]).pureHydrogen();
var h1 = substituents[1] < 0 || this.molecule.atoms.get(substituents[1]).pureHydrogen();
var h2 = this.molecule.atoms.get(substituents[2]).pureHydrogen();
var h3 = substituents[3] < 0 || this.molecule.atoms.get(substituents[3]).pureHydrogen();
if (h0 && h1)
return false;
if (h2 && h3)
return false;
if (h1) {
substituents[1] = -1;
} else if (h0) {
substituents[0] = substituents[1];
substituents[1] = -1;
} else if (substituents[0] > substituents[1]) {
swap(substituents, 0, 1);
}
if (h3) {
substituents[3] = -1;
} else if (h2) {
substituents[2] = substituents[3];
substituents[3] = -1;
} else if (substituents[2] > substituents[3]) {
swap(substituents, 2, 3);
}
return true;
};
CisTrans.prototype.isGeomStereoBond = function (bondIdx, substituents) { // eslint-disable-line max-statements
// it must be [C,N,Si]=[C,N,Si] bond
var bond = this.molecule.bonds.get(bondIdx);
if (bond.type != Struct.Bond.PATTERN.TYPE.DOUBLE)
return false;
var label1 = this.molecule.atoms.get(bond.begin).label;
var label2 = this.molecule.atoms.get(bond.end).label;
if (label1 != 'C' && label1 != 'N' && label1 != 'Si' && label1 != 'Ge')
return false;
if (label2 != 'C' && label2 != 'N' && label2 != 'Si' && label2 != 'Ge')
return false;
// the atoms should have 1 or 2 single bonds
// (apart from the double bond under consideration)
var neiBegin = this.getNeighbors.call(this.context, bond.begin);
var neiЕnd = this.getNeighbors.call(this.context, bond.end);
if (
neiBegin.length < 2 || neiBegin.length > 3 ||
neiЕnd.length < 2 || neiЕnd.length > 3
)
return false;
substituents[0] = -1;
substituents[1] = -1;
substituents[2] = -1;
substituents[3] = -1;
var i;
var nei;
for (i = 0; i < neiBegin.length; i++) {
nei = neiBegin[i];
if (nei.bid == bondIdx)
continue; // eslint-disable-line no-continue
if (this.molecule.bonds.get(nei.bid).type != Struct.Bond.PATTERN.TYPE.SINGLE)
return false;
if (substituents[0] == -1)
substituents[0] = nei.aid;
else // (substituents[1] == -1)
substituents[1] = nei.aid;
}
for (i = 0; i < neiЕnd.length; i++) {
nei = neiЕnd[i];
if (nei.bid == bondIdx)
continue; // eslint-disable-line no-continue
if (this.molecule.bonds.get(nei.bid).type != Struct.Bond.PATTERN.TYPE.SINGLE)
return false;
if (substituents[2] == -1)
substituents[2] = nei.aid;
else // (substituents[3] == -1)
substituents[3] = nei.aid;
}
if (substituents[1] != -1 && this.samesides(bond.begin, bond.end, substituents[0], substituents[1]) != -1)
return false;
if (substituents[3] != -1 && this.samesides(bond.begin, bond.end, substituents[2], substituents[3]) != -1)
return false;
return true;
};
CisTrans.prototype.build = function (excludeBonds) {
this.molecule.bonds.each(function (bid, bond) {
var ct = this.bonds.set(bid,
{
parity: 0,
substituents: []
});
if (Array.isArray(excludeBonds) && excludeBonds[bid])
return;
if (!this.isGeomStereoBond(bid, ct.substituents))
return;
if (!this.sortSubstituents(ct.substituents))
return;
var sign = this.samesides(bond.begin, bond.end, ct.substituents[0], ct.substituents[2]);
if (sign == 1)
ct.parity = CisTrans.PARITY.CIS;
else if (sign == -1)
ct.parity = CisTrans.PARITY.TRANS;
}, this);
};
function swap(arr, i1, i2) {
var tmp = arr[i1];
arr[i1] = arr[i2];
arr[i2] = tmp;
}
module.exports = CisTrans;