@datagrok/sequence-translator 1.4.4 → 1.4.6

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/detectors.js +24 -0
  3. package/dist/455.js +2 -0
  4. package/dist/455.js.map +1 -0
  5. package/dist/package-test.js +1 -1
  6. package/dist/package-test.js.map +1 -1
  7. package/dist/package.js +1 -1
  8. package/dist/package.js.map +1 -1
  9. package/files/polytool-rules/rules_example.json +2 -2
  10. package/files/samples/HELM.csv +6 -0
  11. package/files/samples/cyclized.csv +4 -3
  12. package/files/samples/cyclized_MSA.csv +5 -0
  13. package/package.json +13 -13
  14. package/src/apps/common/model/oligo-toolkit-package.ts +23 -4
  15. package/src/apps/common/view/components/molecule-img.ts +2 -2
  16. package/src/apps/pattern/model/data-manager.ts +9 -9
  17. package/src/apps/translator/view/ui.ts +8 -8
  18. package/src/consts.ts +12 -0
  19. package/src/global.d.ts +13 -0
  20. package/src/package-test.ts +3 -0
  21. package/src/package.ts +32 -5
  22. package/src/polytool/pt-conversion.ts +395 -81
  23. package/src/polytool/pt-dialog.ts +29 -13
  24. package/src/polytool/pt-enumeration-helm-dialog.ts +79 -34
  25. package/src/polytool/pt-enumeration-helm.ts +12 -8
  26. package/src/polytool/pt-placeholders-breadth-input.ts +4 -4
  27. package/src/polytool/pt-placeholders-input.ts +6 -6
  28. package/src/polytool/pt-unrule-dialog.ts +7 -3
  29. package/src/polytool/pt-unrule.ts +4 -3
  30. package/src/polytool/types.ts +4 -4
  31. package/src/tests/polytool-chain-from-notation-tests.ts +108 -18
  32. package/src/tests/polytool-chain-parse-notation-tests.ts +100 -0
  33. package/src/tests/polytool-convert-tests.ts +102 -25
  34. package/src/tests/polytool-detectors-custom-notation-test.ts +43 -0
  35. package/src/tests/polytool-enumerate-breadth-tests.ts +4 -4
  36. package/src/tests/toAtomicLevel-tests.ts +1 -1
  37. package/src/tests/utils/detect-macromolecule-utils.ts +64 -0
  38. package/src/tests/{utils.ts → utils/index.ts} +2 -2
  39. package/src/utils/context-menu.ts +2 -5
  40. package/src/utils/cyclized.ts +88 -0
  41. package/src/utils/dimerized.ts +10 -0
@@ -5,41 +5,131 @@ import * as DG from 'datagrok-api/dg';
5
5
  import {before, after, category, expect, test, expectArray, testEvent, delay} from '@datagrok-libraries/utils/src/test';
6
6
  import {Chain} from '../polytool/pt-conversion';
7
7
  import {getRules} from '../polytool/pt-rules';
8
+ import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
9
+
10
+ category('PolyTool: Chain', () => {
11
+ let helmHelper: IHelmHelper;
12
+
13
+ before(async () => {
14
+ helmHelper = await getHelmHelper();
15
+ });
8
16
 
9
- category('PolyTool: Chain: fromNotation', () => {
10
17
  const tests = {
11
18
  'cyclized': {
12
- src: {seq: 'R-F-C(1)-T-G-H-F-Y-P-C(1)-meI'},
19
+ data: {
20
+ templateSeq: 'R-F-C(1)-T-G-H-F-Y-P-C(1)-meI',
21
+ templateHelm: 'PEPTIDE1{R.F.[C(1)].T.G.H.F.Y.P.[C(1)].[meI]}$$$$V2.0',
22
+ mmHelm: 'PEPTIDE1{R.F.C.T.G.H.F.Y.P.C.[meI]}$PEPTIDE1,PEPTIDE1,3:R3-10:R3$$$V2.0',
23
+ },
13
24
  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$$$',
25
+ templateChain: {monomerCount: [11], linkageCount: 0},
26
+ mmChain: {monomerCount: [11], linkageCount: 1,}
16
27
  },
17
28
  },
18
29
  'reaction1': {
19
- src: {seq: 'R-F-azG(3)-T-G-H-F-Y-P-aG(3)-meI'},
30
+ data: {
31
+ templateSeq: 'R-F-azG(4)-T-G-H-F-Y-P-aG(4)-meI',
32
+ templateHelm: 'PEPTIDE1{R.F.[azG(4)].T.G.H.F.Y.P.[aG(4)].[meI]}$$$$V2.0',
33
+ mmHelm: 'PEPTIDE1{R.F.[GGaz].T.G.H.F.Y.P}|PEPTIDE2{[meI]}$PEPTIDE1,PEPTIDE1,3:R3-9:R2|PEPTIDE1,PEPTIDE2,3:R4-1:R1$$$V2.0',
34
+ },
20
35
  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$$$',
36
+ templateChain: {monomerCount: [11], linkageCount: 0,},
37
+ mmChain: {monomerCount: [9, 1], linkageCount: 2,}
23
38
  }
24
39
  },
25
40
  'reaction2': {
26
- src: {seq: 'R-F-aG(3)-T-G-H-F-Y-P-azG(3)-meI'},
41
+ data: {
42
+ templateSeq: 'R-F-aG(4)-T-G-H-F-Y-P-azG(4)-meI',
43
+ templateHelm: 'PEPTIDE1{R.F.[aG(4)].T.G.H.F.Y.P.[azG(4)].[meI]}$$$$V2.0',
44
+ mmHelm: 'PEPTIDE1{R.F}|PEPTIDE2{T.G.H.F.Y.P.[GGaz].[meI]}$PEPTIDE1,PEPTIDE2,2:R2-7:R3|PEPTIDE2,PEPTIDE2,1:R1-7:R4,$$$V2.0',
45
+ },
46
+ tgt: {
47
+ templateChain: {monomerCount: [11], linkageCount: 0,},
48
+ mmChain: {monomerCount: [2, 8], linkageCount: 2,}
49
+ }
50
+ },
51
+ 'dimerized1': {
52
+ data: {
53
+ templateSeq: '(#3)Succ-{A(CHOL)-F-C(1)-T-G-H-Y-P-C(1)-NH2}',
54
+ templateHelm: 'PEPTIDE1{[(#3)Succ]}' + '|' +
55
+ 'PEPTIDE2{[A(CHOL)].F.[C(1)].T.G.H.Y.P.[C(1)].[NH2]}' + '$' +
56
+ 'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '$$$' + 'V2.0',
57
+ mmHelm: 'PEPTIDE1{[Succ].[A(CHOL)].F.C.T.G.H.Y.P.C.[NH2]}' + '|' +
58
+ 'PEPTIDE2{[A(CHOL)].F.C.T.G.H.Y.P.C.[NH2]}' + '$' +
59
+ 'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '|' +
60
+ 'PEPTIDE1,PEPTIDE1,4:R3-10:R3' + '|' +
61
+ 'PEPTIDE2,PEPTIDE2,3:R3-9:R3' + '$$$V2.0',
62
+ },
63
+ tgt: {
64
+ templateChain: {monomerCount: [1, 10], linkageCount: 1},
65
+ mmChain: {monomerCount: [11, 10], linkageCount: 3,}
66
+ }
67
+ },
68
+ 'dimerized2': {
69
+ data: {
70
+ templateSeq: '($3)Succ-{R-F-C(1)-T-G-H-F-P-C(1)-NH2}($3){A(CHOL)-F-C(1)-Y-H-G-D-N-C(1)-meI}',
71
+ templateHelm: 'PEPTIDE1{[($3)Succ]}' + '|' +
72
+ 'PEPTIDE2{R.F.[C(1)].T.G.H.F.P.[C(1)].[NH2]}' + '|' +
73
+ 'PEPTIDE3{[($3)A(CHOL)].F.[C(1)].Y.H.G.D.N.[C(1)].[meI]}' + '$' +
74
+ 'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '$$$' + 'V2.0',
75
+ mmHelm: 'PEPTIDE1{[Succ].R.F.C.T.G.H.F.P.C.[NH2]}' + '|' +
76
+ 'PEPTIDE2{[A(CHOL)].F.C.Y.H.G.D.N.C.[meI]}' + '$' +
77
+ 'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '|' +
78
+ 'PEPTIDE1,PEPTIDE1,4:R3-10:R3' + '|' +
79
+ 'PEPTIDE2,PEPTIDE2,3:R3-9:R3' + '$$$V2.0',
80
+ },
27
81
  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,$$$',
82
+ templateChain: {monomerCount: [1, 10, 10], linkageCount: 1,},
83
+ mmChain: {monomerCount: [11, 10], linkageCount: 3,}
31
84
  }
32
85
  }
33
-
34
86
  };
35
87
 
36
- for (const [testName, testData] of Object.entries(tests)) {
37
- test(`${testName}`, async () => {
88
+ for (const [testName, {data, tgt}] of Object.entries(tests)) {
89
+ test(`fromNotation-${testName}`, async () => {
38
90
  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);
91
+ const resMmChain = Chain.fromNotation(data.templateSeq, rules, helmHelper);
92
+ resMmChain.check(true);
93
+ expectArray(resMmChain.monomers.map((mL) => mL.length), tgt.mmChain.monomerCount);
94
+ expect(resMmChain.linkages.length, tgt.mmChain.linkageCount);
95
+ expect(resMmChain.getHelm(), data.mmHelm);
43
96
  }, testName == 'reaction2' ? {skipReason: 'reverse reaction'} : undefined);
44
97
  }
98
+
99
+ for (const [testName, {data, tgt}] of Object.entries(tests)) {
100
+ test(`parseNotation-${testName}`, async () => {
101
+ const rules = await getRules(['rules_example.json']);
102
+ const resTemplateChain = Chain.parseNotation(data.templateSeq, helmHelper);
103
+ resTemplateChain.check(true);
104
+ expectArray(resTemplateChain.monomers.map((mL) => mL.length), tgt.templateChain.monomerCount);
105
+ expect(resTemplateChain.linkages.length, tgt.templateChain.linkageCount);
106
+ expect(resTemplateChain.getHelm(), data.templateHelm);
107
+ expect(resTemplateChain.getNotation(), data.templateSeq);
108
+ });
109
+ }
110
+
111
+ for (const [testName, {data, tgt}] of Object.entries(tests)) {
112
+ test(`parseHelm-${testName}`, async () => {
113
+ const rules = await getRules(['rules_example.json']);
114
+ const resTemplateChain = Chain.parseHelm(data.templateHelm, helmHelper);
115
+ resTemplateChain.check(true);
116
+ expectArray(resTemplateChain.monomers.map((mL) => mL.length), tgt.templateChain.monomerCount);
117
+ expect(resTemplateChain.linkages.length, tgt.templateChain.linkageCount);
118
+ expect(resTemplateChain.getHelm(), data.templateHelm);
119
+ expect(resTemplateChain.getNotation(), data.templateSeq);
120
+ });
121
+ }
122
+
123
+ for (const [testName, {data, tgt}] of Object.entries(tests)) {
124
+ test(`applyRules-${testName}`, async () => {
125
+ const rules = await getRules(['rules_example.json']);
126
+ const resTemplateChain = Chain.parseNotation(data.templateSeq, helmHelper);
127
+ const resMmChain = resTemplateChain.applyRules(rules);
128
+ resMmChain.check(true);
129
+ expectArray(resMmChain.monomers.map((mL) => mL.length), tgt.mmChain.monomerCount);
130
+ expect(resMmChain.linkages.length, tgt.mmChain.linkageCount);
131
+ expect(resMmChain.getHelm(), data.mmHelm);
132
+ }, {skipReason: 'applyRules is not implemented'});
133
+ }
134
+
45
135
  });
@@ -0,0 +1,100 @@
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, getInnerIdx, getOuterIdx} 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: '(#3)Succ-{A(CHOL)-F-C(1)-T-G-H-Y-P-C(1)-NH2}'},
27
+ tgt: {
28
+ // TODO: Target test data requires clarification
29
+ //monomerCount: [2, 8], linkageCount: 0,
30
+ helm: 'PEPTIDE1{[(#3)Succ]}' + '|' +
31
+ 'PEPTIDE2{[A(CHOL)].F.[C(1)].T.G.H.Y.P.[C(1)].[NH2]}' + '$' +
32
+ 'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '$$$' + 'V2.0',
33
+ }
34
+ },
35
+ 'dimerized2': {
36
+ src: {seq: '($3)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}'},
37
+ tgt: {
38
+ // TODO: Target test data requires clarification
39
+ //monomerCount: [2, 8], linkageCount: 0,
40
+ helm: 'PEPTIDE1{[($3)Succ]}' + '|' +
41
+ 'PEPTIDE2{R.F.[C(1)].T.G.H.F.P.[C(1)].[NH2]}' + '|' +
42
+ 'PEPTIDE3{[($2)A(CHOL)].F.[C(1)].T.G.H.F.P.[C(1)].[NH2]}' + '$' +
43
+ 'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '$$$' + 'V2.0',
44
+ }
45
+ }
46
+ };
47
+
48
+ for (const [testName, testData] of Object.entries(tests)) {
49
+ test(`${testName}`, async () => {
50
+ const rules = await getRules(['rules_example.json']);
51
+ const resChain = await Chain.parseNotation(testData.src.seq, helmHelper);
52
+ //expectArray(resChain.monomers.map((mL) => mL.length), testData.tgt.monomerCount);
53
+ //expect(resChain.linkages.length, testData.tgt.linkageCount);
54
+ // expect(resChain.getNotationHelm(), testData.tgt.helm);
55
+ // expect(resChain.getNotation(), testData.src.seq);
56
+
57
+ const resMol = resChain.mol!;
58
+ const hwe = helmHelper.createHelmWebEditor();
59
+ hwe.editor.setMol(resMol!);
60
+ const resMolHelm = hwe.editor.getHelm();
61
+
62
+ const resHelm = resChain.getNotationHelm();
63
+
64
+ expect(resMolHelm, testData.tgt.helm);
65
+ expect(resHelm, testData.tgt.helm);
66
+ }, testName == 'reaction2' ? {skipReason: 'reverse reaction'} : undefined);
67
+ }
68
+
69
+ const innerIdxTests = {
70
+ '0-in-4-4-3': {inIdx: 0, spIdx: 0, outIdx: 0, monomers: [['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10']]},
71
+ '3-in-4-4-3': {inIdx: 3, spIdx: 0, outIdx: 3, monomers: [['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10']]},
72
+ '4-in-4-4-3': {inIdx: 0, spIdx: 1, outIdx: 4, monomers: [['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10']]},
73
+ '7-in-4-4-3': {inIdx: 3, spIdx: 1, outIdx: 7, monomers: [['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10']]},
74
+ '8-in-4-4-3': {inIdx: 0, spIdx: 2, outIdx: 8, monomers: [['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10']]},
75
+ // '11-in-4-4-3': {inIdx: 0, spIdx: 3, outIdx: 11, monomers: [['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10']]},
76
+ // '12-in-4-4-3': {inIdx: 1, spIdx: 3, outIdx: 12, monomers: [['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10']]},
77
+ '0-in-1-1-6-3': {inIdx: 0, spIdx: 0, outIdx: 0, monomers: [['0'], ['1'], ['2', '3', '4', '5', '6', '7'], ['8', '9', '10']]},
78
+ '1-in-1-1-6-3': {inIdx: 0, spIdx: 1, outIdx: 1, monomers: [['0'], ['1'], ['2', '3', '4', '5', '6', '7'], ['8', '9', '10']]},
79
+ '2-in-1-1-6-3': {inIdx: 0, spIdx: 2, outIdx: 2, monomers: [['0'], ['1'], ['2', '3', '4', '5', '6', '7'], ['8', '9', '10']]},
80
+ '3-in-1-1-6-3': {inIdx: 1, spIdx: 2, outIdx: 3, monomers: [['0'], ['1'], ['2', '3', '4', '5', '6', '7'], ['8', '9', '10']]},
81
+ '7-in-1-1-6-3': {inIdx: 5, spIdx: 2, outIdx: 7, monomers: [['0'], ['1'], ['2', '3', '4', '5', '6', '7'], ['8', '9', '10']]},
82
+ '8-in-1-1-6-3': {inIdx: 0, spIdx: 3, outIdx: 8, monomers: [['0'], ['1'], ['2', '3', '4', '5', '6', '7'], ['8', '9', '10']]},
83
+ // '11-in-1-1-6-3': {inIdx: 0, spIdx: 4}, src: {outIdx: 11, monomers: [['0'], ['1'], ['2', '3', '4', '5', '6', '7'], ['8', '9', '10']]}},
84
+ };
85
+
86
+ for (const [testName, {inIdx, spIdx, outIdx, monomers}] of Object.entries(innerIdxTests)) {
87
+ test(`innerIdx-${testName}`, async () => {
88
+ const [resInIdx, resSpIdx] = getInnerIdx(outIdx, monomers);
89
+ expect(resInIdx, inIdx);
90
+ expect(resSpIdx, spIdx);
91
+ });
92
+ }
93
+
94
+ for (const [testName, {inIdx, spIdx, outIdx, monomers}] of Object.entries(innerIdxTests)) {
95
+ test(`outerIdx-${testName}`, async () => {
96
+ const resOutIdx = getOuterIdx(inIdx, spIdx, monomers);
97
+ expect(resOutIdx, outIdx);
98
+ });
99
+ }
100
+ });
@@ -2,25 +2,35 @@ 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 {before, after, category, expect, test, expectArray, testEvent, delay} from '@datagrok-libraries/utils/src/test';
5
+ import {before, after, category, expect, test, expectArray, testEvent, delay, expectObject} from '@datagrok-libraries/utils/src/test';
6
6
  import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
7
7
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
8
8
  import {
9
9
  getUserLibSettings, setUserLibSettings
10
10
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
11
11
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
+ import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
13
+ import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
14
+ import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
15
+ import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
12
16
 
13
- import {doPolyToolConvert} from '../polytool/pt-conversion';
17
+ import {doPolyToolConvert, getOverriddenLibrary} from '../polytool/pt-conversion';
14
18
  import {getRules} from '../polytool/pt-rules';
15
19
 
16
- import {_package} from '../package-test';
17
20
 
21
+ import {_package} from '../package-test';
18
22
 
19
23
  category('PolyTool: Convert', () => {
24
+ let helmHelper: IHelmHelper;
25
+ let seqHelper: ISeqHelper;
26
+ let rdKitModule: RDModule;
20
27
  let monomerLibHelper: IMonomerLibHelper;
21
28
  let userLibSettings: UserLibSettings; //backup
22
29
 
23
30
  before(async () => {
31
+ helmHelper = await getHelmHelper();
32
+ seqHelper = await getSeqHelper();
33
+ rdKitModule = await getRdKitModule();
24
34
  monomerLibHelper = await getMonomerLibHelper();
25
35
  userLibSettings = await getUserLibSettings();
26
36
 
@@ -32,43 +42,107 @@ category('PolyTool: Convert', () => {
32
42
  await monomerLibHelper.loadMonomerLib(true);
33
43
  });
34
44
 
35
- const tests: { [testName: string]: { src: string[], tgt: string[] } } = {
36
- 'cyclized': {
37
- src: [
38
- 'R-F-C(1)-T-G-H-F-Y-P-C(1)-meI',
39
- 'C(1)-T-G-H-F-Y-P-C(1)-meI',
40
- 'R-F-C(1)-T-G-H-F-Y-P-C(1)',
41
- 'C(1)-T-G-H-F-H-P-C(1)',
42
- 'R-F-D(2)-T-G-H-F-Y-P-NH2(2)',
43
- ],
44
- tgt: [
45
- 'PEPTIDE1{R.F.C.T.G.H.F.Y.P.C.[meI]}$PEPTIDE1,PEPTIDE1,3:R3-10:R3$$$',
46
- 'PEPTIDE1{C.T.G.H.F.Y.P.C.[meI]}$PEPTIDE1,PEPTIDE1,1:R3-8:R3$$$',
47
- 'PEPTIDE1{R.F.C.T.G.H.F.Y.P.C}$PEPTIDE1,PEPTIDE1,3:R3-10:R3$$$',
48
- 'PEPTIDE1{C.T.G.H.F.H.P.C}$PEPTIDE1,PEPTIDE1,1:R3-8:R3$$$',
49
- 'PEPTIDE1{R.F.D.T.G.H.F.Y.P.[NH2]}$PEPTIDE1,PEPTIDE1,10:R2-3:R3$$$',
50
- ]
51
- }
45
+ const tests = {
46
+ 'cyclized-C(1)-2-1': {
47
+ src: {seq: 'R-F-C(1)-T-G-H-F-Y-P-C(1)-meI'},
48
+ tgt: {
49
+ helm: 'PEPTIDE1{R.F.C.T.G.H.F.Y.P.C.[meI]}$PEPTIDE1,PEPTIDE1,3:R3-10:R3$$$V2.0',
50
+ mol: {atomCount: 95, bondCount: 100, inchiKey: 'LMJUFVBPWWJJPN-AJJYTACESA-N',},
51
+ }
52
+ },
53
+ 'cyclized-C(1)-0-1': {
54
+ src: {seq: 'C(1)-T-G-H-F-Y-P-C(1)-meI'},
55
+ tgt: {
56
+ helm: 'PEPTIDE1{C.T.G.H.F.Y.P.C.[meI]}$PEPTIDE1,PEPTIDE1,1:R3-8:R3$$$V2.0',
57
+ mol: {atomCount: 73, bondCount: 77, inchiKey: 'KLFRBMUPPMMGJM-HXTBFBBASA-N',},
58
+ }
59
+ },
60
+ 'cyclized-C(1)-2-0': {
61
+ src: {seq: 'R-F-C(1)-T-G-H-F-Y-P-C(1)'},
62
+ tgt: {
63
+ helm: 'PEPTIDE1{R.F.C.T.G.H.F.Y.P.C}$PEPTIDE1,PEPTIDE1,3:R3-10:R3$$$V2.0',
64
+ mol: {atomCount: 86, bondCount: 91, inchiKey: 'WIHSRTQGMICACU-DDDKLKPZSA-N',},
65
+ }
66
+ },
67
+ 'cyclized-C(1)-0-0': {
68
+ src: {seq: 'C(1)-T-G-H-F-Y-P-C(1)'},
69
+ tgt: {
70
+ helm: 'PEPTIDE1{C.T.G.H.F.Y.P.C}$PEPTIDE1,PEPTIDE1,1:R3-8:R3$$$V2.0',
71
+ mol: {atomCount: 64, bondCount: 68, inchiKey: 'LOSMDBLEXLWPLB-OFZKBENXSA-N',},
72
+ }
73
+ },
74
+ 'cyclized-D(2)-NH2(2)-3-0': {
75
+ src: {seq: 'R-F-D(2)-T-G-H-F-Y-P-NH2(2)'},
76
+ tgt: {
77
+ helm: 'PEPTIDE1{R.F.D.T.G.H.F.Y.P.[NH2]}$PEPTIDE1,PEPTIDE1,10:R2-3:R3$$$V2.0',
78
+ mol: {atomCount: 81, bondCount: 86, inchiKey: 'CBMGNYKOZWNVNK-AHGCAHLCSA-N',},
79
+ }
80
+ },
81
+ 'cyclized-D(2)-NH2(2)-0-0': {
82
+ src: {seq: 'D(2)-T-G-H-F-Y-P-NH2(2)'},
83
+ tgt: {
84
+ helm: 'PEPTIDE1{D.T.G.H.F.Y.P.[NH2]}$PEPTIDE1,PEPTIDE1,8:R2-1:R3$$$V2.0',
85
+ mol: {atomCount: 59, bondCount: 63, inchiKey: 'HGRHAUQBJXFERJ-MUFWPYSASA-N',},
86
+ }
87
+ },
88
+ 'cyclized-azG(4)-aG(4)-2-1': {
89
+ src: {seq: 'R-F-azG(4)-T-G-H-F-Y-P-aG(4)-meI'},
90
+ tgt: {
91
+ 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$$$V2.0',
92
+ mol: {atomCount: 97, bondCount: 103, inchiKey: 'WJSYGVBGPCCSJF-PERUNASMSA-N',},
93
+ }
94
+ },
52
95
  };
53
96
 
54
97
  for (const [testName, testData] of Object.entries(tests)) {
55
- test(`${testName}`, async () => {
98
+ test(`toHelm-${testName}`, async () => {
56
99
  const rules = await getRules(['rules_example.json']);
57
- const res = doPolyToolConvert(testData.src, rules);
58
- expectArray(res, testData.tgt);
100
+ const res = doPolyToolConvert([testData.src.seq], rules, helmHelper);
101
+ expect(res[0], testData.tgt.helm);
59
102
  });
60
103
  }
61
104
 
105
+ for (const [testName, testData] of Object.entries(tests)) {
106
+ test(`toAtomicLevel-${testName}`, async () => {
107
+ const rules = await getRules(['rules_example.json']);
108
+ const helmList = doPolyToolConvert([testData.src.seq], rules, helmHelper);
109
+
110
+ const lib = await getOverriddenLibrary(rules);
111
+
112
+ const helmCol = DG.Column.fromStrings('helm', helmList);
113
+ helmCol.semType = DG.SEMTYPE.MACROMOLECULE;
114
+ helmCol.meta.units = NOTATION.HELM;
115
+ const talRes = await seqHelper.helmToAtomicLevel(helmCol, false, false, lib);
116
+ if (talRes.warnings && talRes.warnings.length > 0)
117
+ throw new Error(talRes.warnings[0]);
118
+ expect(talRes.molCol != null, true, '.molCol is not null');
119
+ const k = 11;
120
+ const molfile = talRes.molCol!.get(0)!;
121
+ const mol = rdKitModule.get_mol(molfile);
122
+ try {
123
+ const resMol = {
124
+ atomCount: mol.get_num_atoms(), bondCount: mol.get_num_bonds(),
125
+ inchiKey: rdKitModule.get_inchikey_for_inchi(mol.get_inchi())
126
+ };
127
+ expectObject(resMol, testData.tgt.mol);
128
+ } finally {
129
+ mol.delete();
130
+ }
131
+ });
132
+ }
62
133
 
63
134
  test('ui-col-wo-table', async () => {
64
135
  const packageName = _package.name;
65
- const seqCol = DG.Column.fromStrings('seq', tests['cyclized'].src);
136
+ const seqList = Object.values(tests).map((td) => td.src.seq);
137
+ const helmList = Object.values(tests).map((td) => td.tgt.helm);
138
+ const seqCol = DG.Column.fromStrings('seq', seqList);
66
139
  const helmCol: DG.Column = await grok.functions.call(`${packageName}:polyToolConvert2`, {
67
140
  seqCol: seqCol,
68
141
  generateHelm: true,
69
142
  chiralityEngine: true,
70
143
  rules: ['rules_example.json']
71
144
  });
145
+ expectArray(helmCol.toList(), helmList);
72
146
  expect(helmCol.semType, DG.SEMTYPE.MACROMOLECULE);
73
147
  expect(helmCol.meta.units, NOTATION.HELM);
74
148
  expect(helmCol.dataFrame, null);
@@ -76,7 +150,9 @@ category('PolyTool: Convert', () => {
76
150
 
77
151
  test('ui-col', async () => {
78
152
  const packageName = _package.name;
79
- const seqCol = DG.Column.fromStrings('seq', tests['cyclized'].src);
153
+ const seqList = Object.values(tests).map((td) => td.src.seq);
154
+ const helmList = Object.values(tests).map((td) => td.tgt.helm);
155
+ const seqCol = DG.Column.fromStrings('seq', seqList);
80
156
  const df = DG.DataFrame.fromColumns([seqCol]);
81
157
  const tv = grok.shell.addTableView(df);
82
158
 
@@ -86,6 +162,7 @@ category('PolyTool: Convert', () => {
86
162
  chiralityEngine: true,
87
163
  rules: ['rules_example.json']
88
164
  });
165
+ expectArray(helmCol.toList(), helmList);
89
166
  expect(helmCol.semType, DG.SEMTYPE.MACROMOLECULE);
90
167
  expect(helmCol.meta.units, NOTATION.HELM);
91
168
  expect(helmCol.dataFrame.id, df.id);
@@ -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(4)-T-G-H-F-Y-P-azG(4)-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
+ });
@@ -41,7 +41,7 @@ category('PolyTool: Enumerate', () => {
41
41
  src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
42
42
  params: {
43
43
  type: PolyToolEnumeratorTypes.Single,
44
- placeholdersBreadth: [
44
+ breadthPlaceholders: [
45
45
  {start: 2, end: 4, monomers: ['K']},
46
46
  ],
47
47
  },
@@ -55,7 +55,7 @@ category('PolyTool: Enumerate', () => {
55
55
  src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
56
56
  params: {
57
57
  type: PolyToolEnumeratorTypes.Single,
58
- placeholdersBreadth: [
58
+ breadthPlaceholders: [
59
59
  {start: 2, end: 4, monomers: ['K']},
60
60
  ],
61
61
  keepOriginal: true,
@@ -71,7 +71,7 @@ category('PolyTool: Enumerate', () => {
71
71
  src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
72
72
  params: {
73
73
  type: PolyToolEnumeratorTypes.Single,
74
- placeholdersBreadth: [
74
+ breadthPlaceholders: [
75
75
  {start: 2, end: 4, monomers: ['K', 'Y']},
76
76
  ],
77
77
  },
@@ -88,7 +88,7 @@ category('PolyTool: Enumerate', () => {
88
88
  src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
89
89
  params: {
90
90
  type: PolyToolEnumeratorTypes.Single,
91
- placeholdersBreadth: [
91
+ breadthPlaceholders: [
92
92
  {start: 2, end: 4, monomers: ['K']},
93
93
  {start: 2, end: 4, monomers: ['Y']},
94
94
  ],
@@ -45,7 +45,7 @@ category('toAtomicLevel', () => {
45
45
  expect(ggazM != null, true, `Monomer 'GGaz' not found.`);
46
46
 
47
47
  const overrideMonomerLibData: MonomerLibData = {[PolymerTypes.PEPTIDE]: {'GGaz': ggazM}};
48
- const overriddenMonomerLib = systemMonomerLib.override(overrideMonomerLibData);
48
+ const overriddenMonomerLib = systemMonomerLib.override(overrideMonomerLibData, 'test');
49
49
 
50
50
  const seqHelper = await getSeqHelper();
51
51
 
@@ -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 '../apps/common/model/const';
6
- import {ITranslationHelper} from '../types';
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';
@@ -43,11 +40,11 @@ function addContextMenuForCell(gridCell: DG.GridCell, menu: DG.Menu): boolean {
43
40
  if (gridCell && gridCell.tableColumn) {
44
41
  switch (gridCell.tableColumn.semType) {
45
42
  case DG.SEMTYPE.MACROMOLECULE: {
46
- menu.item('PolyTool-Enumerate', () => { polyToolEnumerateHelmUI(gridCell.cell); });
43
+ menu.item('PolyTool-Enumerate', () => { polyToolEnumerateHelmUI(gridCell.cell).then(() => {}); });
47
44
  return true;
48
45
  }
49
46
  case DG.SEMTYPE.MOLECULE: {
50
- menu.item('PolyTool-Enumerate', () => { polyToolEnumerateChemUI(gridCell.cell); });
47
+ menu.item('PolyTool-Enumerate', () => { polyToolEnumerateChemUI(gridCell.cell).then(() => {}); });
51
48
  return true;
52
49
  }
53
50
  }