Skip to content

Commit

Permalink
#6068 - Same chain configuration imported by different HELM layouted …
Browse files Browse the repository at this point in the history
…differently (anyway - both are wrong)

#6074 - System doesn't flip chain if connected to monomer but not to base (2)

#6080 - System doesn't flip chain if connected to monomer but not to base (3)

#6081 - Smaller chain should be at the bottom

#6087 - Antisense layout is wrong for any ambiguouse base from the library

#6077 - H-bond is not alligned to Snake mode view in some cases

#6076 - Two-to-one base H-bond connection layouted wrong

#6075 - In case of multipal H-bonds system should arrange antisence chain to first base of bottom chain

#6070 - System doesn't flip chain if connected to monomer but not to base

#6067 - Two chains connected by H-bond arranged wrong if third bond present on the canvas

#6061 - RNA chain remain flipped after hydrogen bond removal
  • Loading branch information
rrodionov91 committed Dec 6, 2024
1 parent 44a8e7e commit 27e86d2
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 47 deletions.
6 changes: 6 additions & 0 deletions packages/ketcher-core/src/application/editor/tools/Erase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class EraserTool implements BaseTool {
) {
const modelChanges =
this.editor.drawingEntitiesManager.deleteSelectedEntities();
modelChanges.merge(
this.editor.drawingEntitiesManager.recalculateAntisenseChains(),
);
this.history.update(modelChanges);
this.editor.renderersContainer.update(modelChanges);
}
Expand All @@ -47,6 +50,9 @@ class EraserTool implements BaseTool {
this.editor.drawingEntitiesManager.deleteDrawingEntity(
selectedItemRenderer.drawingEntity,
);
modelChanges.merge(
this.editor.drawingEntitiesManager.recalculateAntisenseChains(),
);
this.history.update(modelChanges);
this.editor.renderersContainer.update(modelChanges);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,17 @@ export class SnakeModePolymerBondRenderer extends BaseRenderer {
) as Connection;
const isVerticalConnection = firstCellConnection.isVertical;
const isStraightVerticalConnection =
cells.length === 2 && isVerticalConnection;
(cells.length === 2 ||
cells.reduce(
(isStraight: boolean, cell: Cell, index: number): boolean => {
if (!isStraight || index === 0 || index === cells.length - 1) {
return isStraight;
}
return cell.x === firstCell.x && !cell.monomer;
},
true,
)) &&
isVerticalConnection;
const isFirstMonomerOfBondInFirstCell = firstCell.node?.monomers.includes(
this.polymerBond.firstMonomer,
);
Expand Down
63 changes: 47 additions & 16 deletions packages/ketcher-core/src/domain/entities/DrawingEntitiesManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
import { Coordinates, CoreEditor } from 'application/editor/internal';
import {
getNextMonomerInChain,
getSugarFromRnaBase,
isAmbiguousMonomerLibraryItem,
isRnaBaseOrAmbiguousRnaBase,
isValidNucleoside,
Expand Down Expand Up @@ -864,6 +865,8 @@ export class DrawingEntitiesManager {
command.merge(this.recalculateCanvasMatrix());
}

command.merge(this.recalculateAntisenseChains());

return command;
}

Expand Down Expand Up @@ -1546,6 +1549,7 @@ export class DrawingEntitiesManager {
private calculateSnakeLayoutMatrix(chainsCollection: ChainsCollection) {
const snakeLayoutMatrix = new Matrix<Cell>();
const monomersGroupedByY = new Map<number, Map<number, BaseMonomer>>();
const monomerToNode = chainsCollection.monomerToNode;

this.monomers.forEach((monomer) => {
const x = Number(monomer.position.x.toFixed());
Expand Down Expand Up @@ -1596,7 +1600,7 @@ export class DrawingEntitiesManager {
Number(indexY),
Number(monomerXToIndexInMatrix[x]),
new Cell(
chainsCollection.monomerToNode.get(monomer),
monomerToNode.get(monomer),
[],
Number(indexY),
Number(monomerXToIndexInMatrix[x]),
Expand Down Expand Up @@ -1683,8 +1687,14 @@ export class DrawingEntitiesManager {
let restOfRowsWithAntisense = 0;
let isPreviousChainWithAntisense = false;

chain.forEachNode(({ node, nodeIndex }) => {
if (rearrangedMonomersSet.has(node.monomer.id)) {
for (
let nodeIndex = Math.min(0, ...antisenseChainsStartIndexes);
nodeIndex < chain.length;
nodeIndex++
) {
const node = chain.nodes[nodeIndex];

if (node && rearrangedMonomersSet.has(node.monomer.id)) {
return;
}

Expand All @@ -1707,6 +1717,10 @@ export class DrawingEntitiesManager {
isPreviousChainWithAntisense = true;
}

if (!node) {
continue;
}

const r2PolymerBond =
node.lastMonomerInNode.attachmentPointsToBonds[
AttachmentPointName.R2
Expand Down Expand Up @@ -1759,7 +1773,8 @@ export class DrawingEntitiesManager {
command.merge(rearrangeResult.command);
});
}
});
}

lastPosition = getFirstPosition(maxVerticalDistance, lastPosition);
maxVerticalDistance = 0;

Expand Down Expand Up @@ -2643,6 +2658,16 @@ export class DrawingEntitiesManager {
const senseToAntisenseChains = new Map<Chain, Chain[]>();
const handledChains = new Set<Chain>();

this.monomers.forEach((monomer) => {
command.merge(
this.modifyMonomerItem(monomer, {
...monomer.monomerItem,
isAntisense: false,
isSense: false,
}),
);
});

chainsCollection.chains.forEach((chain) => {
if (handledChains.has(chain)) {
return;
Expand All @@ -2654,21 +2679,27 @@ export class DrawingEntitiesManager {
const chainsToCheck = new Set<Chain>();

complimentaryChainsWithData.forEach((complimentaryChainWithData) => {
const hasNucleotideWithHydrogenBond =
complimentaryChainWithData.complimentaryChain.nodes.some(
(node) =>
(node instanceof Nucleotide || node instanceof Nucleoside) &&
node.rnaBase.hydrogenBonds.length > 0,
);

if (/*hasNucleotideWithHydrogenBond*/ true) {
chainsToCheck.add(complimentaryChainWithData.complimentaryChain);
} else {
complimentaryChainWithData.complimentaryChain.monomers.forEach(
const hasHadrogenBondWithRnaBase =
complimentaryChainWithData.complimentaryChain.monomers.some(
(monomer) => {
command.merge(this.markMonomerAsAntisense(monomer));
return (
(monomer instanceof RNABase &&
monomer.hydrogenBonds.length > 0) ||
monomer.hydrogenBonds.some((hydrogenBond) => {
const anotherMonomer =
hydrogenBond.getAnotherMonomer(monomer);

return (
anotherMonomer instanceof RNABase &&
Boolean(getSugarFromRnaBase(anotherMonomer))
);
})
);
},
);

if (hasHadrogenBondWithRnaBase) {
chainsToCheck.add(complimentaryChainWithData.complimentaryChain);
}
});

Expand Down
18 changes: 0 additions & 18 deletions packages/ketcher-core/src/domain/entities/Nucleoside.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import assert from 'assert';
import {
getNextMonomerInChain,
getRnaBaseFromSugar,
getSugarFromRnaBase,
isValidNucleoside,
isValidNucleotide,
} from 'domain/helpers/monomers';
Expand Down Expand Up @@ -126,21 +125,4 @@ export class Nucleoside {
this.rnaBase.isModification || this.sugar.isModification || isNotLastNode
);
}

public getFirstAntisenseMonomer() {
for (let i = 0; i < this.monomers.length; i++) {
const monomer = this.monomers[i];
const hydrogenBondToRnaBase = monomer.hydrogenBonds.find(
(hydrogenBond) =>
hydrogenBond.firstMonomer instanceof RNABase ||
hydrogenBond.secondMonomer instanceof RNABase,
);

if (hydrogenBondToRnaBase) {
return hydrogenBondToRnaBase.getAnotherMonomer(monomer);
}
}

return undefined;
}
}
5 changes: 0 additions & 5 deletions packages/ketcher-core/src/domain/entities/Nucleotide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { AmbiguousMonomer } from 'domain/entities/AmbiguousMonomer';
import { RNA_MONOMER_DISTANCE } from 'application/editor/tools/RnaPreset';
import { SugarRenderer } from 'application/render';
import { SNAKE_LAYOUT_CELL_WIDTH } from 'domain/entities/DrawingEntitiesManager';
import { Nucleoside } from 'domain/entities/Nucleoside';

export class Nucleotide {
constructor(
Expand Down Expand Up @@ -124,8 +123,4 @@ export class Nucleotide {
this.phosphate.isModification
);
}

public getFirstAntisenseMonomer() {
return Nucleoside.prototype.getFirstAntisenseMonomer.call(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import {
BaseMonomer,
Chem,
IsChainCycled,
Nucleoside,
Nucleotide,
Peptide,
Phosphate,
RNABase,
Expand Down Expand Up @@ -312,17 +310,26 @@ export class ChainsCollection {
});
}

private getFirstAntisenseMonomerInNode(node: SubChainNode) {
for (let i = 0; i < node.monomers.length; i++) {
const monomer = node.monomers[i];
const hydrogenBond = monomer.hydrogenBonds[0];

if (hydrogenBond) {
return hydrogenBond.getAnotherMonomer(monomer);
}
}

return undefined;
}

public getComplimentaryChainsWithData(chain: Chain) {
const complimentaryChainsWithData: ComplimentaryChainsWithData[] = [];
const handledChains = new Set<Chain>();
const monomerToChain = this.monomerToChain;

chain.forEachNode(({ node }) => {
if (!(node instanceof Nucleotide || node instanceof Nucleoside)) {
return;
}

const complimentaryMonomer = node.getFirstAntisenseMonomer();
const complimentaryMonomer = this.getFirstAntisenseMonomerInNode(node);
const complimentaryNode =
complimentaryMonomer && this.monomerToNode.get(complimentaryMonomer);
const complimentaryChain =
Expand Down

0 comments on commit 27e86d2

Please sign in to comment.