in packages/ketcher-core/src/application/editor/MacromoleculesConverter.ts [112:303]
public static convertDrawingEntitiesToStruct(
drawingEntitiesManager: DrawingEntitiesManager,
struct: Struct,
reStruct?: ReStruct,
) {
const monomerToAtomIdMap = new Map<BaseMonomer, Map<number, number>>();
const monomerToMonomerMicromolecule = new Map<
BaseMonomer,
MonomerMicromolecule
>();
drawingEntitiesManager.micromoleculesHiddenEntities.mergeInto(struct);
drawingEntitiesManager.clearMicromoleculesHiddenEntities();
drawingEntitiesManager.monomers.forEach((monomer) => {
if (monomer.monomerItem.props.isMicromoleculeFragment) {
const atomIdMap = new Map<number, number>();
monomer.monomerItem.struct.mergeInto(
struct,
null,
null,
false,
false,
atomIdMap,
);
monomerToAtomIdMap.set(monomer, atomIdMap);
} else {
const atomIdsMap = new Map<number, number>();
const monomerMicromolecule = this.convertMonomerToMonomerMicromolecule(
monomer,
struct,
);
reStruct?.sgroups.set(
monomerMicromolecule.id,
new ReSGroup(monomerMicromolecule),
);
const monomerAtoms =
monomer instanceof AmbiguousMonomer
? monomer.monomers[0].monomerItem.struct.atoms
: monomer.monomerItem.struct.atoms;
const monomerBonds =
monomer instanceof AmbiguousMonomer
? monomer.monomers[0].monomerItem.struct.bonds
: monomer.monomerItem.struct.bonds;
monomerToMonomerMicromolecule.set(monomer, monomerMicromolecule);
monomerAtoms.forEach((oldAtom, oldAtomId) => {
const { atom, atomId } = this.addMonomerAtomToStruct(
oldAtom,
monomer,
monomerMicromolecule,
struct,
);
atomIdsMap.set(oldAtomId, atomId);
monomerToAtomIdMap.set(monomer, atomIdsMap);
reStruct?.atoms.set(atomId, new ReAtom(atom));
});
monomerMicromolecule.addAttachmentPoints(
monomer.listOfAttachmentPoints.map(
(attachmentPointName, attachmentPointIndex) => {
const attachmentPointNumber =
getAttachmentPointNumberFromLabel(attachmentPointName);
const attachmentPoint = monomer.monomerItem.attachmentPoints?.[
attachmentPointIndex
] as IKetAttachmentPoint;
return new SGroupAttachmentPoint(
atomIdsMap.get(attachmentPoint.attachmentAtom) as number,
atomIdsMap.get(attachmentPoint.leavingGroup?.atoms[0]),
undefined,
attachmentPointNumber,
);
},
) || [],
false,
);
struct.sGroupForest.insert(monomerMicromolecule);
monomerBonds.forEach((bond) => {
const bondClone = bond.clone();
bondClone.begin = atomIdsMap.get(bondClone.begin) as number;
bondClone.end = atomIdsMap.get(bondClone.end) as number;
const bondId = struct.bonds.add(bondClone);
reStruct?.bonds.set(bondId, new ReBond(bondClone));
});
struct.functionalGroups.add(new FunctionalGroup(monomerMicromolecule));
}
});
let conversionErrorMessage = '';
drawingEntitiesManager.polymerBonds.forEach((polymerBond) => {
assert(polymerBond.secondMonomer);
if (polymerBond instanceof HydrogenBond) {
const bond = new Bond({
type: Bond.PATTERN.TYPE.HYDROGEN,
begin: monomerToAtomIdMap
.get(polymerBond.firstMonomer)
?.values()
.next().value,
end: monomerToAtomIdMap
.get(polymerBond.secondMonomer)
?.values()
.next().value,
});
const bondId = struct.bonds.add(bond);
reStruct?.bonds.set(bondId, new ReBond(bond));
return;
}
const {
globalAttachmentAtomId: beginAtom,
attachmentPointNumber: beginSuperatomAttachmentPointNumber,
} = this.findAttachmentPointAtom(
polymerBond,
polymerBond.firstMonomer,
monomerToAtomIdMap,
);
const {
globalAttachmentAtomId: endAtom,
attachmentPointNumber: endSuperatomAttachmentPointNumber,
} = this.findAttachmentPointAtom(
polymerBond,
polymerBond.secondMonomer,
monomerToAtomIdMap,
);
if (!isNumber(beginAtom) || !isNumber(endAtom)) {
conversionErrorMessage =
'There is no atom for provided attachment point. Bond between monomers was not created.';
return;
}
const bond = new Bond({
type:
polymerBond instanceof HydrogenBond
? Bond.PATTERN.TYPE.HYDROGEN
: Bond.PATTERN.TYPE.SINGLE,
begin: beginAtom,
end: endAtom,
beginSuperatomAttachmentPointNumber,
endSuperatomAttachmentPointNumber,
});
const bondId = struct.bonds.add(bond);
reStruct?.bonds.set(bondId, new ReBond(bond));
});
drawingEntitiesManager.monomerToAtomBonds.forEach((monomerToAtomBond) => {
const {
globalAttachmentAtomId: beginAtom,
attachmentPointNumber: beginSuperatomAttachmentPointNumber,
} = this.findAttachmentPointAtom(
monomerToAtomBond,
monomerToAtomBond.monomer,
monomerToAtomIdMap,
);
const endAtom = monomerToAtomIdMap
?.get(monomerToAtomBond.atom.monomer)
?.get(monomerToAtomBond.atom.atomIdInMicroMode);
if (!isNumber(beginAtom) || !isNumber(endAtom)) {
conversionErrorMessage =
'There is no atom for provided attachment point. Bond between monomers was not created.';
return;
}
const bond = new Bond({
type: Bond.PATTERN.TYPE.SINGLE,
begin: beginAtom,
end: endAtom,
beginSuperatomAttachmentPointNumber,
});
const bondId = struct.bonds.add(bond);
reStruct?.bonds.set(bondId, new ReBond(bond));
});
struct.findConnectedComponents();
struct.setImplicitHydrogen();
struct.setStereoLabelsToAtoms();
struct.markFragments();
return { struct, reStruct, conversionErrorMessage };
}