Skip to content

Commit

Permalink
#4824 - Cycled chain breaks sequence canvas and entire app
Browse files Browse the repository at this point in the history
- fixed case with infinite loop in chains analysis if phosphate is first in cycled chain
  • Loading branch information
rrodionov91 committed Jun 10, 2024
1 parent 388797b commit f509957
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 11 deletions.
18 changes: 11 additions & 7 deletions packages/ketcher-core/src/domain/entities/monomer-chains/Chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ import { LinkerSequenceNode } from 'domain/entities/LinkerSequenceNode';
export class Chain {
public subChains: BaseSubChain[] = [];

public firstMonomer: BaseMonomer | null;
public firstMonomer?: BaseMonomer;

public isCyclic = false;

constructor(firstMonomer?: BaseMonomer, isCyclic?: boolean) {
this.firstMonomer = null;

if (firstMonomer) {
this.firstMonomer = firstMonomer;

Expand All @@ -53,10 +51,16 @@ export class Chain {

const nextMonomer = getNextMonomerInChain(monomer);

if (monomer instanceof Sugar && isValidNucleoside(monomer)) {
this.lastSubChain.add(Nucleoside.fromSugar(monomer));
} else if (monomer instanceof Sugar && isValidNucleotide(monomer)) {
this.lastSubChain.add(Nucleotide.fromSugar(monomer));
if (
monomer instanceof Sugar &&
isValidNucleoside(monomer, this.firstMonomer)
) {
this.lastSubChain.add(Nucleoside.fromSugar(monomer, false));
} else if (
monomer instanceof Sugar &&
isValidNucleotide(monomer, this.firstMonomer)
) {
this.lastSubChain.add(Nucleotide.fromSugar(monomer, false));
} else if (monomer instanceof Peptide) {
this.lastSubChain.add(new MonomerSequenceNode(monomer));
} else if (
Expand Down
18 changes: 14 additions & 4 deletions packages/ketcher-core/src/domain/helpers/monomers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,32 @@ export function isMonomerBeginningOfChain(
);
}

export function isValidNucleotide(sugar: Sugar) {
export function isValidNucleotide(
sugar: Sugar,
firstMonomerInCyclicChain?: BaseMonomer,
) {
const phosphate = getPhosphateFromSugar(sugar);
const nextMonomerAfterPhosphate = getNextMonomerInChain(phosphate);

return Boolean(
getRnaBaseFromSugar(sugar) &&
getPhosphateFromSugar(sugar) &&
nextMonomerAfterPhosphate,
nextMonomerAfterPhosphate &&
phosphate !== firstMonomerInCyclicChain,
);
}

export function isValidNucleoside(sugar: Sugar) {
export function isValidNucleoside(
sugar: Sugar,
firstMonomerInCyclicChain?: BaseMonomer,
) {
const phosphate = getPhosphateFromSugar(sugar);
const nextMonomerAfterPhosphate = getNextMonomerInChain(phosphate);

return (
getRnaBaseFromSugar(sugar) && (!phosphate || !nextMonomerAfterPhosphate)
getRnaBaseFromSugar(sugar) &&
(!phosphate ||
!nextMonomerAfterPhosphate ||
phosphate === firstMonomerInCyclicChain)
);
}

0 comments on commit f509957

Please sign in to comment.