public static convertDrawingEntitiesToStruct()

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 };
  }