Skip to content

Commit

Permalink
#5359 - Display molecules in macro mode: basic structures with atoms …
Browse files Browse the repository at this point in the history
…and bonds (#5636)

- fixed monomer to atom bonds repositioning issue after switching between modes if there are more than one molecule
  • Loading branch information
rrodionov91 authored Oct 3, 2024
1 parent 8454ce7 commit 06aa065
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import {
getAttachmentPointLabel,
getAttachmentPointNumberFromLabel,
} from 'domain/helpers/attachmentPointCalculations';
import { isNumber } from 'lodash';
import { invert, isNumber } from 'lodash';
import { IKetAttachmentPoint } from 'application/formatters';
import { MonomerToAtomBond } from 'domain/entities/MonomerToAtomBond';
import { CoreEditor } from 'application/editor/Editor';
import { isMonomerSgroupWithAttachmentPoints } from '../../utilities/monomers';
import { Atom } from 'domain/entities/CoreAtom';
import { AtomLabel } from 'domain/constants';
import { isMonomerSgroupWithAttachmentPoints } from '../../utilities/monomers';

export class MacromoleculesConverter {
private static convertMonomerToMonomerMicromolecule(
Expand Down Expand Up @@ -373,9 +373,12 @@ export class MacromoleculesConverter {
public static findAtomByMicromoleculeAtomId(
drawingEntitiesManager: DrawingEntitiesManager,
atomId: number,
monomer?: BaseMonomer,
) {
return [...drawingEntitiesManager.atoms.values()].find(
(atom) => atom.atomIdInMicroMode === atomId,
(atom) =>
atom.atomIdInMicroMode === atomId &&
(!monomer || monomer === atom.monomer),
);
}

Expand All @@ -402,6 +405,7 @@ export class MacromoleculesConverter {

let fragmentNumber = 1;
const fragmentIdToAtomIdMap = new Map<number, Map<number, number>>();
const globalAtomIdToMonomerMap = new Map<number, BaseMonomer>();

fragments.forEach((_fragment) => {
const atomIdMap = new Map<number, number>();
Expand All @@ -412,26 +416,20 @@ export class MacromoleculesConverter {
drawingEntitiesManager,
);
const monomer = monomerAddCommand.operations[0].monomer as BaseMonomer;
const atomIdMapObject = Object.fromEntries(atomIdMap.entries());
const localAtomIdToGlobalAtomId = invert(atomIdMapObject);
const atomsMap = new Map<number, Atom>();

_fragment.forEach((fragmentId) => {
fragmentIdToMonomer.set(fragmentId as number, monomer);
fragmentIdToAtomIdMap.set(fragmentId, atomIdMap);
});
command.merge(monomerAddCommand);
fragmentNumber++;
});
const superatomAttachmentPointToBond = new Map<
SGroupAttachmentPoint,
Bond
>();

drawingEntitiesManager.monomers.forEach((monomer) => {
if (
monomer.monomerItem.props.isMicromoleculeFragment &&
!isMonomerSgroupWithAttachmentPoints(monomer)
) {
const atomsMap: { [atomId: number]: Atom } = {};

monomer.monomerItem.struct.atoms.forEach((atom, atomId) => {
const atomAddCommand = drawingEntitiesManager.addAtom(
atom.pp,
Expand All @@ -440,23 +438,41 @@ export class MacromoleculesConverter {
atom.label as AtomLabel,
);

atomsMap[atomId] = atomAddCommand.operations[0].atom as Atom;
command.merge(atomAddCommand);
atomsMap.set(atomId, atomAddCommand.operations[0].atom as Atom);
globalAtomIdToMonomerMap.set(
Number(localAtomIdToGlobalAtomId[atomId]),
monomer,
);
});

monomer.monomerItem.struct.bonds.forEach((bond) => {
const firstAtom = atomsMap.get(bond.begin);
const secondAtom = atomsMap.get(bond.end);

if (!firstAtom || !secondAtom) {
return;
}

command.merge(
drawingEntitiesManager.addBond(
atomsMap[bond.begin],
atomsMap[bond.end],
firstAtom,
secondAtom,
bond.type,
bond.stereo,
),
);
});
}

fragmentNumber++;
});

const superatomAttachmentPointToBond = new Map<
SGroupAttachmentPoint,
Bond
>();

struct.bonds.forEach((bond) => {
const beginAtom = struct.atoms.get(bond.begin);
const endAtom = struct.atoms.get(bond.end);
Expand Down Expand Up @@ -500,6 +516,7 @@ export class MacromoleculesConverter {
MacromoleculesConverter.findAtomByMicromoleculeAtomId(
drawingEntitiesManager,
atomIdInMicromolecules,
globalAtomIdToMonomerMap.get(moleculeAtomId),
);

if (
Expand Down
19 changes: 12 additions & 7 deletions packages/ketcher-core/src/domain/serializers/ket/ketSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ export class KetSerializer implements Serializer<Struct> {
deserializedMicromolecules,
drawingEntitiesManager,
);
const atomIdsMap = new Map<number, number>();
const localAtomIdToGlobalAtomId = new Map<number, number>();

command.merge(structToDrawingEntitiesConversionResult.modelChanges);

Expand All @@ -528,8 +528,8 @@ export class KetSerializer implements Serializer<Struct> {

structToDrawingEntitiesConversionResult.fragmentIdToAtomIdMap.forEach(
(_atomIdsMap) => {
_atomIdsMap.forEach((atomId, oldAtomId) => {
atomIdsMap.set(oldAtomId, atomId);
_atomIdsMap.forEach((globalAtomId, localAtomId) => {
localAtomIdToGlobalAtomId.set(localAtomId, globalAtomId);
});
},
);
Expand Down Expand Up @@ -569,11 +569,16 @@ export class KetSerializer implements Serializer<Struct> {
(firstMonomer.monomerItem.props.isMicromoleculeFragment ||
secondMonomer.monomerItem.props.isMicromoleculeFragment)
) {
const atomId = Number(
connection.endpoint1.atomId || connection.endpoint2.atomId,
);

const atom = MacromoleculesConverter.findAtomByMicromoleculeAtomId(
drawingEntitiesManager,
Number(
connection.endpoint1.atomId || connection.endpoint2.atomId,
),
atomId,
firstMonomer.monomerItem.props.isMicromoleculeFragment
? firstMonomer
: secondMonomer,
);
const attachmentPointName =
connection.endpoint1.attachmentPointId ||
Expand All @@ -597,7 +602,7 @@ export class KetSerializer implements Serializer<Struct> {
const bondAdditionCommand = polymerBondToDrawingEntity(
connection,
drawingEntitiesManager,
atomIdsMap,
localAtomIdToGlobalAtomId,
superatomMonomerToUsedAttachmentPoint,
firstMonomer,
secondMonomer,
Expand Down

0 comments on commit 06aa065

Please sign in to comment.