Skip to content

Commit

Permalink
Backmerge: #5335 - The application crashes when selecting Enhanced St…
Browse files Browse the repository at this point in the history
…ereochemistry from the right-click menu (#5349)

- added set stereo labels to atoms to setMolecule
  • Loading branch information
rrodionov91 authored Aug 26, 2024
1 parent ceed0ac commit 06bf272
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 116 deletions.
95 changes: 1 addition & 94 deletions packages/ketcher-core/src/application/editor/actions/bond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@
***************************************************************************/

import {
Atom,
Bond,
Neighbor,
StereoLabel,
Struct,
Vec2,
AtomAttributes,
BondAttributes,
Expand Down Expand Up @@ -47,9 +43,9 @@ import {

import { Action } from './action';
import { ReSGroup, ReStruct } from '../../render';
import { StereoValidator } from 'domain/helpers';
import utils from '../shared/utils';
import { fromSgroupAttachmentPointRemove } from 'application/editor';
import { getStereoAtomsMap } from 'application/editor/actions/helpers';

export function fromBondAddition(
reStruct: ReStruct,
Expand Down Expand Up @@ -329,95 +325,6 @@ export function fromBondStereoUpdate(
return action;
}

export function getStereoAtomsMap(
struct: Struct,
bonds: Array<Bond>,
bond?: Bond,
) {
const stereoAtomsMap = new Map();
const correctAtomIds: Array<number> = [];

bonds.forEach((bond: Bond | undefined) => {
if (bond) {
const beginNeighs: Array<Neighbor> | undefined = struct.atomGetNeighbors(
bond.begin,
);
const endNeighs: Array<Neighbor> | undefined = struct.atomGetNeighbors(
bond.end,
);

if (
StereoValidator.isCorrectStereoCenter(
bond,
beginNeighs,
endNeighs,
struct,
)
) {
const stereoLabel = struct.atoms.get(bond.begin)?.stereoLabel;
if (
stereoLabel == null ||
stereoAtomsMap.get(bond.begin)?.stereoLabel == null
) {
stereoAtomsMap.set(bond.begin, {
stereoParity: getStereoParity(bond.stereo),
stereoLabel: stereoLabel || `${StereoLabel.Abs}`,
});
}
correctAtomIds.push(bond.begin);
} else {
if (!correctAtomIds.includes(bond.begin)) {
stereoAtomsMap.set(bond.begin, {
stereoParity: Atom.PATTERN.STEREO_PARITY.NONE,
stereoLabel: null,
});
}
if (!correctAtomIds.includes(bond.end)) {
stereoAtomsMap.set(bond.end, {
stereoParity: Atom.PATTERN.STEREO_PARITY.NONE,
stereoLabel: null,
});
}
}
}
});

// in case the stereo band is flipped, changed or removed
// TODO the duplication of the code below should be fixed, mayby by function
if (bond) {
if (!correctAtomIds.includes(bond.begin)) {
stereoAtomsMap.set(bond.begin, {
stereoParity: Atom.PATTERN.STEREO_PARITY.NONE,
stereoLabel: null,
});
}
if (!correctAtomIds.includes(bond.end)) {
stereoAtomsMap.set(bond.end, {
stereoParity: Atom.PATTERN.STEREO_PARITY.NONE,
stereoLabel: null,
});
}
}

return stereoAtomsMap;
}

function getStereoParity(stereo: number): number | null {
let newAtomParity: number | null = null;
switch (stereo) {
case Bond.PATTERN.STEREO.UP:
newAtomParity = Atom.PATTERN.STEREO_PARITY.ODD;
break;
case Bond.PATTERN.STEREO.EITHER:
newAtomParity = Atom.PATTERN.STEREO_PARITY.EITHER;
break;
case Bond.PATTERN.STEREO.DOWN:
newAtomParity = Atom.PATTERN.STEREO_PARITY.EVEN;
break;
}
return newAtomParity;
}

const plainBondTypes = [
Bond.PATTERN.TYPE.SINGLE,
Bond.PATTERN.TYPE.DOUBLE,
Expand Down
91 changes: 91 additions & 0 deletions packages/ketcher-core/src/application/editor/actions/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { Atom, Bond, Neighbor, StereoLabel, Struct } from 'domain/entities';
import { StereoValidator } from 'domain/helpers';

export function getStereoAtomsMap(
struct: Struct,
bonds: Array<Bond>,
bond?: Bond,
) {
const stereoAtomsMap = new Map();
const correctAtomIds: Array<number> = [];

bonds.forEach((bond: Bond | undefined) => {
if (bond) {
const beginNeighs: Array<Neighbor> | undefined = struct.atomGetNeighbors(
bond.begin,
);
const endNeighs: Array<Neighbor> | undefined = struct.atomGetNeighbors(
bond.end,
);

if (
StereoValidator.isCorrectStereoCenter(
bond,
beginNeighs,
endNeighs,
struct,
)
) {
const stereoLabel = struct.atoms.get(bond.begin)?.stereoLabel;
if (
stereoLabel == null ||
stereoAtomsMap.get(bond.begin)?.stereoLabel == null
) {
stereoAtomsMap.set(bond.begin, {
stereoParity: getStereoParity(bond.stereo),
stereoLabel: stereoLabel || `${StereoLabel.Abs}`,
});
}
correctAtomIds.push(bond.begin);
} else {
if (!correctAtomIds.includes(bond.begin)) {
stereoAtomsMap.set(bond.begin, {
stereoParity: Atom.PATTERN.STEREO_PARITY.NONE,
stereoLabel: null,
});
}
if (!correctAtomIds.includes(bond.end)) {
stereoAtomsMap.set(bond.end, {
stereoParity: Atom.PATTERN.STEREO_PARITY.NONE,
stereoLabel: null,
});
}
}
}
});

// in case the stereo band is flipped, changed or removed
// TODO the duplication of the code below should be fixed, mayby by function
if (bond) {
if (!correctAtomIds.includes(bond.begin)) {
stereoAtomsMap.set(bond.begin, {
stereoParity: Atom.PATTERN.STEREO_PARITY.NONE,
stereoLabel: null,
});
}
if (!correctAtomIds.includes(bond.end)) {
stereoAtomsMap.set(bond.end, {
stereoParity: Atom.PATTERN.STEREO_PARITY.NONE,
stereoLabel: null,
});
}
}

return stereoAtomsMap;
}

function getStereoParity(stereo: number): number | null {
let newAtomParity: number | null = null;
switch (stereo) {
case Bond.PATTERN.STEREO.UP:
newAtomParity = Atom.PATTERN.STEREO_PARITY.ODD;
break;
case Bond.PATTERN.STEREO.EITHER:
newAtomParity = Atom.PATTERN.STEREO_PARITY.EITHER;
break;
case Bond.PATTERN.STEREO.DOWN:
newAtomParity = Atom.PATTERN.STEREO_PARITY.EVEN;
break;
}
return newAtomParity;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
***************************************************************************/

import { Box2Abs, Vec2 } from 'domain/entities';

import { Box2Abs } from 'domain/entities/box2Abs';
import { Vec2 } from 'domain/entities/vec2';
import { LayerMap } from './generalEnumTypes';
import ReObject from './reobject';
import { Scale } from 'domain/helpers';
Expand Down
1 change: 1 addition & 0 deletions packages/ketcher-core/src/application/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export async function prepareStructToRender(
struct.initHalfBonds();
struct.initNeighbors();
struct.setImplicitHydrogen();
struct.setStereoLabelsToAtoms();
struct.markFragments();

return struct;
Expand Down
21 changes: 21 additions & 0 deletions packages/ketcher-core/src/domain/entities/struct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { RGroupAttachmentPoint } from './rgroupAttachmentPoint';
import { MonomerMicromolecule } from 'domain/entities/monomerMicromolecule';
import { isNumber } from 'lodash';
import { Image } from './image';
import { getStereoAtomsMap } from 'application/editor/actions/helpers';

export type Neighbor = {
aid: number;
Expand Down Expand Up @@ -1073,6 +1074,26 @@ export class Struct {
}
}

public setStereoLabelsToAtoms() {
const stereAtomsMap = getStereoAtomsMap(
this,
Array.from(this.bonds.values()),
);

this.atoms.forEach((atom, id) => {
if (this?.atomGetNeighbors(id)?.length === 0) {
atom.stereoLabel = null;
atom.stereoParity = 0;
} else {
const stereoProp = stereAtomsMap.get(id);
if (stereoProp) {
atom.stereoLabel = stereoProp.stereoLabel;
atom.stereoParity = stereoProp.stereoParity;
}
}
});
}

atomGetNeighbors(aid: number): Array<Neighbor> | undefined {
return this.atoms.get(aid)?.neighbors.map((nei) => {
const hb = this.halfBonds.get(nei)!;
Expand Down
21 changes: 1 addition & 20 deletions packages/ketcher-react/src/script/ui/state/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
FormatterFactory,
Pile,
SGroup,
getStereoAtomsMap,
identifyStructFormat,
Struct,
SupportedFormat,
Expand Down Expand Up @@ -186,25 +185,7 @@ export function load(struct: Struct, options?) {

parsedStruct.findConnectedComponents();
parsedStruct.setImplicitHydrogen();

const stereAtomsMap = getStereoAtomsMap(
parsedStruct,
Array.from(parsedStruct.bonds.values()),
);

parsedStruct.atoms.forEach((atom, id) => {
if (parsedStruct?.atomGetNeighbors(id)?.length === 0) {
atom.stereoLabel = null;
atom.stereoParity = 0;
} else {
const stereoProp = stereAtomsMap.get(id);
if (stereoProp) {
atom.stereoLabel = stereoProp.stereoLabel;
atom.stereoParity = stereoProp.stereoParity;
}
}
});

parsedStruct.setStereoLabelsToAtoms();
parsedStruct.markFragments();

if (fragment) {
Expand Down

0 comments on commit 06bf272

Please sign in to comment.