in packages/ketcher-core/src/domain/serializers/ket/ketSerializer.ts [461:659]
deserializeToDrawingEntities(fileContent: string) {
const { error: hasValidationErrors, parsedFileContent } =
this.parseAndValidateMacromolecules(fileContent);
if (hasValidationErrors || !parsedFileContent) return;
const command = new Command();
const drawingEntitiesManager = new DrawingEntitiesManager();
const monomerIdsMap = {};
parsedFileContent.root.nodes.forEach((node) => {
const nodeDefinition = parsedFileContent[node.$ref];
switch (nodeDefinition?.type) {
case KetNodeType.MONOMER: {
const template = parsedFileContent[
setMonomerTemplatePrefix(nodeDefinition.templateId)
] as IKetMonomerTemplate;
assert(template);
const struct = KetSerializer.convertMonomerTemplateToStruct(template);
const monomerAdditionCommand = monomerToDrawingEntity(
nodeDefinition,
template,
struct,
drawingEntitiesManager,
);
const monomer = monomerAdditionCommand.operations[0]
.monomer as BaseMonomer;
monomerIdsMap[node.$ref] = monomer?.id;
KetSerializer.fillStructRgLabelsByMonomerTemplate(
template,
monomer.monomerItem,
);
command.merge(monomerAdditionCommand);
break;
}
case KetNodeType.AMBIGUOUS_MONOMER: {
const template = parsedFileContent[
setAmbiguousMonomerTemplatePrefix(nodeDefinition.templateId)
] as IKetAmbiguousMonomerTemplate;
assert(template);
const monomerAdditionCommand = variantMonomerToDrawingEntity(
drawingEntitiesManager,
nodeDefinition,
template,
parsedFileContent,
);
const monomer = monomerAdditionCommand.operations[0]
.monomer as BaseMonomer;
monomerIdsMap[node.$ref] = monomer?.id;
command.merge(monomerAdditionCommand);
break;
}
default:
break;
}
});
const fileContentForMicromolecules =
this.filterMacromoleculesContent(parsedFileContent);
const deserializedMicromolecules = this.deserializeMicromolecules(
JSON.stringify(fileContentForMicromolecules),
);
const structToDrawingEntitiesConversionResult =
MacromoleculesConverter.convertStructToDrawingEntities(
deserializedMicromolecules,
drawingEntitiesManager,
);
const localAtomIdToGlobalAtomId = new Map<number, number>();
command.merge(structToDrawingEntitiesConversionResult.modelChanges);
structToDrawingEntitiesConversionResult.fragmentIdToMonomer.forEach(
(monomer, fragmentId) => {
monomerIdsMap[`mol${fragmentId}`] = monomer.id;
},
);
structToDrawingEntitiesConversionResult.fragmentIdToAtomIdMap.forEach(
(_atomIdsMap) => {
_atomIdsMap.forEach((globalAtomId, localAtomId) => {
localAtomIdToGlobalAtomId.set(localAtomId, globalAtomId);
});
},
);
const superatomMonomerToUsedAttachmentPoint = new Map<
BaseMonomer,
Set<string>
>();
parsedFileContent.root.connections?.forEach((connection) => {
switch (connection.connectionType) {
case KetConnectionType.SINGLE: {
const firstMonomer = drawingEntitiesManager.monomers.get(
Number(
monomerIdsMap[
connection.endpoint1.monomerId ||
connection.endpoint1.moleculeId
],
),
);
const secondMonomer = drawingEntitiesManager.monomers.get(
Number(
monomerIdsMap[
connection.endpoint2.monomerId ||
connection.endpoint2.moleculeId
],
),
);
if (!firstMonomer || !secondMonomer) {
return;
}
if (
!isMonomerSgroupWithAttachmentPoints(firstMonomer) &&
!isMonomerSgroupWithAttachmentPoints(secondMonomer) &&
(firstMonomer.monomerItem.props.isMicromoleculeFragment ||
secondMonomer.monomerItem.props.isMicromoleculeFragment)
) {
const atomId = Number(
connection.endpoint1.atomId || connection.endpoint2.atomId,
);
const atom = MacromoleculesConverter.findAtomByMicromoleculeAtomId(
drawingEntitiesManager,
atomId,
firstMonomer.monomerItem.props.isMicromoleculeFragment
? firstMonomer
: secondMonomer,
);
const attachmentPointName =
connection.endpoint1.attachmentPointId ||
connection.endpoint2.attachmentPointId;
if (!atom || !attachmentPointName) {
return;
}
const bondAdditionCommand =
drawingEntitiesManager.addMonomerToAtomBond(
firstMonomer.monomerItem.props.isMicromoleculeFragment
? secondMonomer
: firstMonomer,
atom,
attachmentPointName as AttachmentPointName,
);
command.merge(bondAdditionCommand);
} else {
const bondAdditionCommand = polymerBondToDrawingEntity(
connection,
drawingEntitiesManager,
localAtomIdToGlobalAtomId,
superatomMonomerToUsedAttachmentPoint,
firstMonomer,
secondMonomer,
);
command.merge(bondAdditionCommand);
}
break;
}
case KetConnectionType.HYDROGEN: {
const firstMonomer = drawingEntitiesManager.monomers.get(
Number(monomerIdsMap[connection.endpoint1.monomerId]),
);
const secondMonomer = drawingEntitiesManager.monomers.get(
Number(monomerIdsMap[connection.endpoint2.monomerId]),
);
if (!firstMonomer || !secondMonomer) {
return;
}
command.merge(
drawingEntitiesManager.createPolymerBond(
firstMonomer,
secondMonomer,
AttachmentPointName.HYDROGEN,
AttachmentPointName.HYDROGEN,
MACROMOLECULES_BOND_TYPES.HYDROGEN,
),
);
break;
}
default:
break;
}
});
return { modelChanges: command, drawingEntitiesManager };
}