@datagrok/sequence-translator 1.4.3 → 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/detectors.js +24 -0
- package/dist/455.js +2 -0
- package/dist/455.js.map +1 -0
- package/dist/package-test.js +2 -1
- package/dist/package-test.js.LICENSE.txt +8 -0
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/files/polytool-rules/rules_example.json +4 -4
- package/files/samples/cyclized.csv +3 -2
- package/package.json +14 -14
- package/src/apps/common/model/oligo-toolkit-package.ts +12 -0
- package/src/apps/common/view/components/molecule-img.ts +2 -2
- package/src/apps/pattern/model/data-manager.ts +9 -9
- package/src/apps/translator/view/ui.ts +8 -8
- package/src/package-test.ts +2 -0
- package/src/package.ts +30 -4
- package/src/polytool/pt-conversion.ts +361 -32
- package/src/polytool/pt-dialog.ts +18 -25
- package/src/polytool/pt-enumeration-helm-dialog.ts +18 -11
- package/src/polytool/pt-enumeration-helm.ts +3 -2
- package/src/polytool/pt-unrule-dialog.ts +2 -2
- package/src/polytool/pt-unrule.ts +1 -1
- package/src/polytool/types.ts +18 -0
- package/src/tests/polytool-chain-from-notation-tests.ts +45 -0
- package/src/tests/polytool-chain-parse-notation-tests.ts +59 -0
- package/src/tests/polytool-detectors-custom-notation-test.ts +43 -0
- package/src/tests/toAtomicLevel-tests.ts +26 -1
- package/src/tests/utils/detect-macromolecule-utils.ts +64 -0
- package/src/tests/{utils.ts → utils/index.ts} +2 -2
- package/src/utils/context-menu.ts +0 -3
- package/src/utils/cyclized.ts +90 -0
- package/src/utils/dimerized.ts +10 -0
|
@@ -30,7 +30,7 @@ export function doPolyToolUnrule(helms: string[], rules: Rules): string[] {
|
|
|
30
30
|
resHrzSeqList[i] = '';
|
|
31
31
|
else {
|
|
32
32
|
const chain = Chain.fromHelm(helms[i]);
|
|
33
|
-
resHrzSeqList[i] = chain.getNotation(
|
|
33
|
+
resHrzSeqList[i] = chain.getNotation();
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
return resHrzSeqList;
|
package/src/polytool/types.ts
CHANGED
|
@@ -2,6 +2,8 @@ import * as ui from 'datagrok-api/ui';
|
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
|
+
import {PolymerType} from '@datagrok-libraries/bio/src/helm/types';
|
|
6
|
+
|
|
5
7
|
export enum PolyToolEnumeratorTypes {
|
|
6
8
|
Single = 'single',
|
|
7
9
|
Matrix = 'matrix',
|
|
@@ -21,3 +23,19 @@ export type PolyToolEnumeratorParams = {
|
|
|
21
23
|
keepOriginal?: boolean;
|
|
22
24
|
trivialName?: boolean;
|
|
23
25
|
}
|
|
26
|
+
|
|
27
|
+
export class MonomerNotFoundError extends Error {
|
|
28
|
+
public type = 'MonomerNotFoundError';
|
|
29
|
+
|
|
30
|
+
constructor(polymerType: PolymerType, symbol: string, options?: ErrorOptions) {
|
|
31
|
+
super(`Monomer '${symbol}' of polymer type '${polymerType}' not found`, options);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class InvalidReactionError extends Error {
|
|
36
|
+
public type = 'InvalidReactionError';
|
|
37
|
+
|
|
38
|
+
constructor(reaction: string, options?: ErrorOptions) {
|
|
39
|
+
super(`Invalid reaction '${reaction}'.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import {before, after, category, expect, test, expectArray, testEvent, delay} from '@datagrok-libraries/utils/src/test';
|
|
6
|
+
import {Chain} from '../polytool/pt-conversion';
|
|
7
|
+
import {getRules} from '../polytool/pt-rules';
|
|
8
|
+
|
|
9
|
+
category('PolyTool: Chain: fromNotation', () => {
|
|
10
|
+
const tests = {
|
|
11
|
+
'cyclized': {
|
|
12
|
+
src: {seq: 'R-F-C(1)-T-G-H-F-Y-P-C(1)-meI'},
|
|
13
|
+
tgt: {
|
|
14
|
+
monomerCount: [11], linkageCount: 1,
|
|
15
|
+
helm: 'PEPTIDE1{R.F.C.T.G.H.F.Y.P.C.[meI]}$PEPTIDE1,PEPTIDE1,3:R3-10:R3$$$',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
'reaction1': {
|
|
19
|
+
src: {seq: 'R-F-azG(3)-T-G-H-F-Y-P-aG(3)-meI'},
|
|
20
|
+
tgt: {
|
|
21
|
+
monomerCount: [9, 1], linkageCount: 2,
|
|
22
|
+
helm: 'PEPTIDE1{R.F.[GGaz].T.G.H.F.Y.P}|PEPTIDE2{[meI]}$PEPTIDE1,PEPTIDE1,3:R3-9:R2|PEPTIDE1,PEPTIDE2,3:R4-1:R1$$$',
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
'reaction2': {
|
|
26
|
+
src: {seq: 'R-F-aG(3)-T-G-H-F-Y-P-azG(3)-meI'},
|
|
27
|
+
tgt: {
|
|
28
|
+
// TODO: Target test data requires clarification
|
|
29
|
+
monomerCount: [2, 8], linkageCount: 0,
|
|
30
|
+
helm: 'PEPTIDE1{R.F}|PEPTIDE2{T.G.H.F.Y.P.[GGaz].[meI]}$PEPTIDE1,PEPTIDE2,2:R2-7:R3|PEPTIDE2,PEPTIDE2,1:R1-7:R4,$$$',
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
for (const [testName, testData] of Object.entries(tests)) {
|
|
37
|
+
test(`${testName}`, async () => {
|
|
38
|
+
const rules = await getRules(['rules_example.json']);
|
|
39
|
+
const resChain = Chain.fromNotation(testData.src.seq, rules);
|
|
40
|
+
expectArray(resChain.monomers.map((mL) => mL.length), testData.tgt.monomerCount);
|
|
41
|
+
expect(resChain.linkages.length, testData.tgt.linkageCount);
|
|
42
|
+
expect(resChain.getHelm(), testData.tgt.helm);
|
|
43
|
+
}, testName == 'reaction2' ? {skipReason: 'reverse reaction'} : undefined);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import {before, after, category, expect, test, expectArray, testEvent, delay} from '@datagrok-libraries/utils/src/test';
|
|
6
|
+
import {Chain} from '../polytool/pt-conversion';
|
|
7
|
+
import {getRules} from '../polytool/pt-rules';
|
|
8
|
+
import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
9
|
+
|
|
10
|
+
category('PolyTool: Chain: parseNotation', () => {
|
|
11
|
+
let helmHelper: IHelmHelper;
|
|
12
|
+
|
|
13
|
+
before(async () => {
|
|
14
|
+
helmHelper = await getHelmHelper(); // initialize JSDraw2 and org
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const tests = {
|
|
18
|
+
'cyclized': {
|
|
19
|
+
src: {seq: 'R-F-C(1)-T-G-H-F-Y-P-C(1)-meI'},
|
|
20
|
+
tgt: {
|
|
21
|
+
//monomerCount: [11], linkageCount: 1,
|
|
22
|
+
helm: 'PEPTIDE1{R.F.[C(1)].T.G.H.F.Y.P.[C(1)].[meI]}$$$$V2.0',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
'dimerized1': {
|
|
26
|
+
src: {seq: '(#2)Succ-{A(CHOL)-F-C(2)-T-G-H-Y-P-C(2)-NH2}'},
|
|
27
|
+
tgt: {
|
|
28
|
+
// TODO: Target test data requires clarification
|
|
29
|
+
//monomerCount: [2, 8], linkageCount: 0,
|
|
30
|
+
helm: 'PEPTIDE1{[(#2)Succ]}|PEPTIDE2{[A(CHOL)].F.[C(2)].T.G.H.Y.P.[C(2)].[NH2]}$PEPTIDE1,PEPTIDE2,1:R1-1:R1$$$V2.0',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
'dimerized2': {
|
|
34
|
+
src: {seq: '($2)Succ-{R-F-C(1)-T-G-H-F-P-C(1)-NH2}($2){A(CHOL)-F-C(1)-T-G-H-F-P-C(1)-NH2}'},
|
|
35
|
+
tgt: {
|
|
36
|
+
// TODO: Target test data requires clarification
|
|
37
|
+
//monomerCount: [2, 8], linkageCount: 0,
|
|
38
|
+
helm: 'PEPTIDE1{[($2)Succ]}|PEPTIDE2{R.F.[C(1)].T.G.H.F.P.[C(1)].[NH2]}|PEPTIDE3{[($2)A(CHOL)].F.[C(1)].T.G.H.F.P.[C(1)].[NH2]}$PEPTIDE1,PEPTIDE2,1:R1-1:R1$$$V2.0',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
for (const [testName, testData] of Object.entries(tests)) {
|
|
44
|
+
test(`${testName}`, async () => {
|
|
45
|
+
const rules = await getRules(['rules_example.json']);
|
|
46
|
+
const resChain = await Chain.parseNotation(testData.src.seq);
|
|
47
|
+
//expectArray(resChain.monomers.map((mL) => mL.length), testData.tgt.monomerCount);
|
|
48
|
+
//expect(resChain.linkages.length, testData.tgt.linkageCount);
|
|
49
|
+
// expect(resChain.getNotationHelm(), testData.tgt.helm);
|
|
50
|
+
// expect(resChain.getNotation(), testData.src.seq);
|
|
51
|
+
|
|
52
|
+
const resMol = resChain.mol!;
|
|
53
|
+
const hwe = helmHelper.createHelmWebEditor();
|
|
54
|
+
hwe.editor.setMol(resMol!);
|
|
55
|
+
const resHelm = hwe.editor.getHelm();
|
|
56
|
+
expect(resHelm, testData.tgt.helm);
|
|
57
|
+
}, testName == 'reaction2' ? {skipReason: 'reverse reaction'} : undefined);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import {category, test, expect, before} from '@datagrok-libraries/utils/src/test';
|
|
6
|
+
import {ISeqHelper, getSeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
7
|
+
import {ALIGNMENT, ALPHABET, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
8
|
+
import {_testNeg, _testPos, DetectorTestData, DfReaderFunc, PosCol} from './utils/detect-macromolecule-utils';
|
|
9
|
+
|
|
10
|
+
category('PolyTool: detectors', () => {
|
|
11
|
+
let seqHelper: ISeqHelper;
|
|
12
|
+
|
|
13
|
+
before(async () => {
|
|
14
|
+
seqHelper = await getSeqHelper();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const tests: DetectorTestData = {
|
|
18
|
+
'cyclized1': {
|
|
19
|
+
csv: `n,seq
|
|
20
|
+
1,R-F-C(1)-T-G-H-F-Y-G-H-F-Y-G-H-F-Y-P-C(1)-meI
|
|
21
|
+
2,C(1)-T-G-H-F-Y-P-C(1)-meI
|
|
22
|
+
3,R-F-C(1)-T-G-H-F-Y-P-C(1)
|
|
23
|
+
4,C(1)-T-G-H-F-H-P-C(1)
|
|
24
|
+
5,R-F-D(2)-T-G-H-F-Y-P-NH2(2)
|
|
25
|
+
6,R-F-aG(3)-T-G-H-F-Y-P-azG(3)-meI`,
|
|
26
|
+
pos: {'seq': new PosCol(NOTATION.CUSTOM, ALIGNMENT.SEQ, ALPHABET.UN, 13, true, '-')}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
for (const [testName, testData] of Object.entries(tests)) {
|
|
31
|
+
test(`${testName}`, async () => {
|
|
32
|
+
const reader: DfReaderFunc = async (): Promise<DG.DataFrame> => {
|
|
33
|
+
return DG.DataFrame.fromCsv(testData.csv);
|
|
34
|
+
};
|
|
35
|
+
for (const negColName of testData.neg ?? [])
|
|
36
|
+
await _testNeg(reader, negColName);
|
|
37
|
+
for (const [posColName, posCol] of Object.entries(testData.pos ?? {})) {
|
|
38
|
+
await _testPos(reader, posColName, seqHelper, posCol.units, posCol.aligned,
|
|
39
|
+
posCol.alphabet, posCol.alphabetSize, posCol.alphabetIsMultichar, posCol.separator);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
});
|
|
@@ -15,6 +15,8 @@ import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
|
15
15
|
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
16
16
|
|
|
17
17
|
import {_package} from '../package-test';
|
|
18
|
+
import {getNewMonomer} from '../polytool/pt-conversion';
|
|
19
|
+
import {getRules, RuleReaction} from '../polytool/pt-rules';
|
|
18
20
|
|
|
19
21
|
category('toAtomicLevel', () => {
|
|
20
22
|
let userLibSettings: UserLibSettings;
|
|
@@ -43,7 +45,7 @@ category('toAtomicLevel', () => {
|
|
|
43
45
|
expect(ggazM != null, true, `Monomer 'GGaz' not found.`);
|
|
44
46
|
|
|
45
47
|
const overrideMonomerLibData: MonomerLibData = {[PolymerTypes.PEPTIDE]: {'GGaz': ggazM}};
|
|
46
|
-
const overriddenMonomerLib = systemMonomerLib.override(overrideMonomerLibData);
|
|
48
|
+
const overriddenMonomerLib = systemMonomerLib.override(overrideMonomerLibData, 'test');
|
|
47
49
|
|
|
48
50
|
const seqHelper = await getSeqHelper();
|
|
49
51
|
|
|
@@ -69,4 +71,27 @@ category('toAtomicLevel', () => {
|
|
|
69
71
|
mol.delete();
|
|
70
72
|
}
|
|
71
73
|
});
|
|
74
|
+
|
|
75
|
+
test('getNewMonomer', async () => {
|
|
76
|
+
const rdKitModule = await getRdKitModule();
|
|
77
|
+
const systemMonomerLib = monomerLibHelper.getMonomerLib();
|
|
78
|
+
|
|
79
|
+
const rules = await getRules(['rules_example.json']);
|
|
80
|
+
const reactionRule = rules.reactionRules.find((r) => r.name == 'GGaz')!;
|
|
81
|
+
|
|
82
|
+
const [newSymbol, newMonomer] = getNewMonomer(rdKitModule, systemMonomerLib, reactionRule);
|
|
83
|
+
expect(newSymbol, reactionRule.name);
|
|
84
|
+
|
|
85
|
+
const mol = rdKitModule.get_mol(newMonomer.molfile);
|
|
86
|
+
try {
|
|
87
|
+
const molInchi = mol.get_inchi();
|
|
88
|
+
const molInchiKey = rdKitModule.get_inchikey_for_inchi(molInchi);
|
|
89
|
+
expect(mol.get_num_bonds(), 18);
|
|
90
|
+
expect(mol.get_num_atoms(), 18);
|
|
91
|
+
// TODO: Check inchi key for the new monomer molfile
|
|
92
|
+
// expect(molInchiKey, 'V2H10N2O3S-UHFFFAOYSA-N');
|
|
93
|
+
} finally {
|
|
94
|
+
mol.delete();
|
|
95
|
+
}
|
|
96
|
+
});
|
|
72
97
|
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
|
|
4
|
+
import {ALIGNMENT, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
5
|
+
import {delay, expect} from '@datagrok-libraries/utils/src/test';
|
|
6
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
7
|
+
|
|
8
|
+
export type DetectorTestData = { [testName: string]: { csv: string, neg?: string[], pos?: { [colName: string]: PosCol } } };
|
|
9
|
+
|
|
10
|
+
export type DfReaderFunc = () => Promise<DG.DataFrame>;
|
|
11
|
+
|
|
12
|
+
export class PosCol {
|
|
13
|
+
constructor(
|
|
14
|
+
public readonly units: NOTATION,
|
|
15
|
+
public readonly aligned: ALIGNMENT | null,
|
|
16
|
+
public readonly alphabet: string | null,
|
|
17
|
+
public readonly alphabetSize: number,
|
|
18
|
+
public readonly alphabetIsMultichar?: boolean,
|
|
19
|
+
public readonly separator?: string,
|
|
20
|
+
) { };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function _testNeg(readDf: DfReaderFunc, colName: string) {
|
|
24
|
+
const df: DG.DataFrame = await readDf();
|
|
25
|
+
const col: DG.Column = df.getCol(colName)!;
|
|
26
|
+
const semType: string = await grok.functions
|
|
27
|
+
.call('Bio:detectMacromolecule', {col: col}) as unknown as string;
|
|
28
|
+
if (semType)
|
|
29
|
+
col.semType = semType;
|
|
30
|
+
|
|
31
|
+
if (col.semType === DG.SEMTYPE.MACROMOLECULE) {
|
|
32
|
+
const msg = `Negative test detected semType='${col.semType}', units='${col.meta.units}'.`;
|
|
33
|
+
throw new Error(msg);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function _testPos(
|
|
38
|
+
readDf: DfReaderFunc, colName: string, seqHelper: ISeqHelper,
|
|
39
|
+
units: string, aligned: string | null, alphabet: string | null, alphabetSize: number, alphabetIsMultichar?: boolean,
|
|
40
|
+
separator: string | null = null,
|
|
41
|
+
) {
|
|
42
|
+
const df: DG.DataFrame = await readDf();
|
|
43
|
+
const col: DG.Column = df.col(colName)!;
|
|
44
|
+
const semType: string = await grok.functions
|
|
45
|
+
.call('Bio:detectMacromolecule', {col: col}) as unknown as string;
|
|
46
|
+
if (semType)
|
|
47
|
+
col.semType = semType;
|
|
48
|
+
|
|
49
|
+
expect(col.semType, DG.SEMTYPE.MACROMOLECULE);
|
|
50
|
+
expect(col.meta.units, units);
|
|
51
|
+
expect(col.getTag(bioTAGS.aligned), aligned);
|
|
52
|
+
expect(col.getTag(bioTAGS.alphabet), alphabet);
|
|
53
|
+
if (separator)
|
|
54
|
+
expect(col.getTag(bioTAGS.separator), separator);
|
|
55
|
+
|
|
56
|
+
const sh = seqHelper.getSeqHandler(col);
|
|
57
|
+
expect(sh.getAlphabetSize(), alphabetSize);
|
|
58
|
+
expect(sh.getAlphabetIsMultichar(), alphabetIsMultichar);
|
|
59
|
+
if (!sh.isHelm()) {
|
|
60
|
+
expect(sh.aligned, aligned);
|
|
61
|
+
expect(sh.alphabet, alphabet);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
@@ -2,8 +2,8 @@ import * as grok from 'datagrok-api/grok';
|
|
|
2
2
|
import * as ui from 'datagrok-api/ui';
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
|
-
import {DEFAULT_FORMATS} from '
|
|
6
|
-
import {ITranslationHelper} from '
|
|
5
|
+
import {DEFAULT_FORMATS} from '../../apps/common/model/const';
|
|
6
|
+
import {ITranslationHelper} from '../../types';
|
|
7
7
|
|
|
8
8
|
export class OligoToolkitTestPackage extends DG.Package {
|
|
9
9
|
async getTranslationHelper(): Promise<ITranslationHelper> {
|
|
@@ -2,9 +2,6 @@ import * as grok from 'datagrok-api/grok';
|
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
import * as ui from 'datagrok-api/ui';
|
|
4
4
|
|
|
5
|
-
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
6
|
-
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
7
|
-
|
|
8
5
|
import {defaultErrorHandler} from './err-info';
|
|
9
6
|
import {polyToolEnumerateHelmUI} from '../polytool/pt-enumeration-helm-dialog';
|
|
10
7
|
import {polyToolEnumerateChemUI} from '../polytool/pt-dialog';
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import wu from 'wu';
|
|
6
|
+
|
|
7
|
+
/* eslint-disable max-len */
|
|
8
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
9
|
+
import {INotationProvider, ISeqSplitted, SeqSplittedBase, SplitterFunc} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
|
|
10
|
+
import {getSplitterWithSeparator} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
11
|
+
import {GAP_SYMBOL, GapOriginals, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
|
|
12
|
+
import {CellRendererBackBase} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
13
|
+
import {MonomerPlacer} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
|
|
14
|
+
import {monomerToShort, StringListSeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
|
|
15
|
+
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
16
|
+
|
|
17
|
+
import {Chain} from '../polytool/pt-conversion';
|
|
18
|
+
|
|
19
|
+
import {_package} from '../package';
|
|
20
|
+
|
|
21
|
+
/* eslint-enable max-len */
|
|
22
|
+
|
|
23
|
+
export class CyclizedNotationProvider implements INotationProvider {
|
|
24
|
+
private readonly separatorSplitter: SplitterFunc;
|
|
25
|
+
public readonly splitter: SplitterFunc;
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
public readonly separator: string,
|
|
29
|
+
protected readonly seqHelper: ISeqHelper
|
|
30
|
+
) {
|
|
31
|
+
this.separatorSplitter = getSplitterWithSeparator(this.separator);
|
|
32
|
+
this.splitter = this._splitter.bind(this);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private _splitter(seq: string): ISeqSplitted {
|
|
36
|
+
const baseSS: ISeqSplitted = this.separatorSplitter(seq);
|
|
37
|
+
return new CyclizedSeqSplitted(
|
|
38
|
+
wu.count(0).take(baseSS.length).map((p) => baseSS.getOriginal(p)).toArray(),
|
|
39
|
+
GapOriginals[NOTATION.SEPARATOR]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public async getHelm(seq: string, options?: any): Promise<DG.SemanticValue<string>> {
|
|
43
|
+
const seqChain = await Chain.parseNotation(seq);
|
|
44
|
+
const seqPseudoHelm = seqChain.getNotationHelm();
|
|
45
|
+
|
|
46
|
+
const resPseudoHelmSV = DG.SemanticValue.fromValueType(seqPseudoHelm,
|
|
47
|
+
DG.SEMTYPE.MACROMOLECULE, NOTATION.HELM);
|
|
48
|
+
resPseudoHelmSV.tags['pt-role'] = 'template';
|
|
49
|
+
return resPseudoHelmSV;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public createCellRendererBack(gridCol: DG.GridColumn | null, tableCol: DG.Column<string>): CellRendererBackBase<string> {
|
|
53
|
+
let maxLengthOfMonomer: number = 4; // (_package.bioProperties ? _package.bioProperties.maxMonomerLength : 4) ?? 50;
|
|
54
|
+
const back = new MonomerPlacer(gridCol, tableCol, _package.logger, maxLengthOfMonomer,
|
|
55
|
+
() => {
|
|
56
|
+
const sh = this.seqHelper.getSeqHandler(tableCol);
|
|
57
|
+
return {
|
|
58
|
+
seqHandler: sh,
|
|
59
|
+
monomerCharWidth: 7,
|
|
60
|
+
separatorWidth: 11,
|
|
61
|
+
monomerToShort: monomerToShort,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
back.init().then(() => {});
|
|
65
|
+
return back;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Gets canonical monomers for original ones with cyclization marks */
|
|
70
|
+
export class CyclizedSeqSplitted extends StringListSeqSplitted {
|
|
71
|
+
private readonly seqCList: (string | null)[];
|
|
72
|
+
|
|
73
|
+
override getCanonical(posIdx: number): string {
|
|
74
|
+
if (this.isGap(posIdx)) return GAP_SYMBOL;
|
|
75
|
+
|
|
76
|
+
let cmRes: string | null = this.seqCList[posIdx];
|
|
77
|
+
if (cmRes === null) {
|
|
78
|
+
const om = this.getOriginal(posIdx);
|
|
79
|
+
cmRes = om;
|
|
80
|
+
if (om[om.length - 1] === ')')
|
|
81
|
+
cmRes = this.seqCList[posIdx] = om.replace(/\(\d+\)$/, '');
|
|
82
|
+
}
|
|
83
|
+
return cmRes;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
constructor(seqOList: SeqSplittedBase, gapOriginalMonomer: string) {
|
|
87
|
+
super(seqOList, gapOriginalMonomer);
|
|
88
|
+
this.seqCList = new Array<string | null>(this.length).fill(null);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import {CyclizedNotationProvider} from './cyclized';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export class DimerizedNotationProvider extends CyclizedNotationProvider {
|
|
9
|
+
|
|
10
|
+
}
|