@datagrok/bio 2.15.3 → 2.15.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 (69) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/detectors.js +9 -2
  3. package/dist/284.js +1 -1
  4. package/dist/284.js.map +1 -1
  5. package/dist/455.js +2 -0
  6. package/dist/455.js.map +1 -0
  7. package/dist/980.js +1 -1
  8. package/dist/980.js.map +1 -1
  9. package/dist/package-test.js +3 -3
  10. package/dist/package-test.js.map +1 -1
  11. package/dist/package.js +2 -2
  12. package/dist/package.js.map +1 -1
  13. package/files/monomer-libraries/polytool-lib.json +52 -0
  14. package/files/tests/to-atomic-level-msa-fasta-output.csv +683 -683
  15. package/files/tests/to-atomic-level-msa-separator-output.csv +104 -104
  16. package/package.json +9 -9
  17. package/src/analysis/sequence-activity-cliffs.ts +3 -1
  18. package/src/calculations/monomerLevelMols.ts +2 -1
  19. package/src/demo/bio03-atomic-level.ts +1 -1
  20. package/src/package-test.ts +2 -1
  21. package/src/package.ts +151 -38
  22. package/src/tests/WebLogo-positions-test.ts +1 -1
  23. package/src/tests/activity-cliffs-tests.ts +2 -3
  24. package/src/tests/bio-tests.ts +1 -1
  25. package/src/tests/detectors-custom-notation-tests.ts +37 -0
  26. package/src/tests/detectors-tests.ts +20 -69
  27. package/src/tests/detectors-weak-and-likely-tests.ts +2 -2
  28. package/src/tests/monomer-libraries-tests.ts +31 -6
  29. package/src/tests/pepsea-tests.ts +1 -1
  30. package/src/tests/renderers-monomer-placer-tests.ts +2 -4
  31. package/src/tests/scoring.ts +2 -3
  32. package/src/tests/seq-handler-get-helm-tests.ts +2 -4
  33. package/src/tests/seq-handler-splitted-tests.ts +6 -2
  34. package/src/tests/splitters-test.ts +6 -6
  35. package/src/tests/substructure-filters-tests.ts +2 -3
  36. package/src/tests/to-atomic-level-tests.ts +22 -17
  37. package/src/tests/to-atomic-level-ui-tests.ts +76 -38
  38. package/src/tests/types.ts +0 -2
  39. package/src/tests/utils/detectors-utils.ts +63 -0
  40. package/src/tests/utils.ts +2 -2
  41. package/src/utils/cell-renderer-custom.ts +62 -0
  42. package/src/utils/cell-renderer.ts +58 -126
  43. package/src/utils/cyclized.ts +28 -14
  44. package/src/utils/dimerized.ts +0 -2
  45. package/src/utils/helm-to-molfile/converter/converter.ts +75 -54
  46. package/src/utils/helm-to-molfile/converter/monomer-wrapper.ts +2 -2
  47. package/src/utils/helm-to-molfile/converter/polymer.ts +23 -16
  48. package/src/utils/helm-to-molfile/converter/types.ts +0 -10
  49. package/src/utils/helm-to-molfile/utils.ts +10 -7
  50. package/src/utils/monomer-lib/consts.ts +18 -0
  51. package/src/utils/monomer-lib/lib-manager.ts +13 -3
  52. package/src/utils/monomer-lib/library-file-manager/file-manager.ts +1 -2
  53. package/src/utils/monomer-lib/monomer-colors.ts +68 -0
  54. package/src/utils/monomer-lib/monomer-lib-base.ts +165 -0
  55. package/src/utils/monomer-lib/monomer-lib.ts +44 -72
  56. package/src/utils/monomer-lib/monomer-manager/monomer-manager.ts +1 -1
  57. package/src/utils/monomer-lib/web-editor-monomer-dummy.ts +121 -0
  58. package/src/utils/monomer-lib/web-editor-monomer-of-library.ts +102 -0
  59. package/src/utils/pepsea.ts +1 -1
  60. package/src/utils/save-as-fasta.ts +1 -1
  61. package/src/utils/seq-helper/seq-helper.ts +20 -49
  62. package/src/utils/sequence-to-mol.ts +24 -28
  63. package/src/viewers/web-logo-viewer.ts +2 -1
  64. package/src/widgets/composition-analysis-widget.ts +4 -3
  65. package/src/widgets/representations.ts +8 -10
  66. package/dist/248.js +0 -2
  67. package/dist/248.js.map +0 -1
  68. package/src/utils/cell-renderer-consts.ts +0 -31
  69. package/src/utils/monomer-lib/library-file-manager/consts.ts +0 -1
@@ -10,7 +10,7 @@ import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monom
10
10
 
11
11
  import {getMonomerLibHelper, sequenceIdentityScoring, sequenceSimilarityScoring} from '../package';
12
12
  import {
13
- getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests
13
+ getUserLibSettings, setUserLibSettings
14
14
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
15
15
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
16
16
 
@@ -41,8 +41,7 @@ PEPTIDE1{[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[
41
41
  monomerLibHelper = await getMonomerLibHelper();
42
42
  userLibSettings = await getUserLibSettings();
43
43
 
44
- await setUserLibSettingsForTests();
45
- await monomerLibHelper.loadMonomerLib(true); // load default libraries
44
+ await monomerLibHelper.loadMonomerLibForTests(); // load default libraries
46
45
  });
47
46
 
48
47
  after(async () => {
@@ -5,9 +5,8 @@ import * as DG from 'datagrok-api/dg';
5
5
  import {after, before, category, expect, test} from '@datagrok-libraries/utils/src/test';
6
6
  import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
7
7
  import {NOTATION, TAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
- import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
9
8
  import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
10
- import {getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
9
+ import {getUserLibSettings, setUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
11
10
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
12
11
 
13
12
  category('SeqHandler: getHelm', () => {
@@ -19,8 +18,7 @@ category('SeqHandler: getHelm', () => {
19
18
  userLibSettings = await getUserLibSettings();
20
19
 
21
20
  // Test 'helm' requires default monomer library loaded
22
- await setUserLibSettingsForTests();
23
- await monomerLibHelper.loadMonomerLib(true); // load default libraries
21
+ await monomerLibHelper.loadMonomerLibForTests(); // load default libraries
24
22
  });
25
23
 
26
24
  after(async () => {
@@ -4,8 +4,9 @@ import * as DG from 'datagrok-api/dg';
4
4
  import wu from 'wu';
5
5
 
6
6
  import {category, expect, expectArray, test} from '@datagrok-libraries/utils/src/test';
7
- import {GapOriginals, SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
7
+ import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
8
8
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
9
+ import {GapOriginals} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
9
10
 
10
11
  enum Tests {
11
12
  fasta = 'fasta',
@@ -135,7 +136,10 @@ PEPTIDE1{meI.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.T.dK.Thr_PO3H2}$$$$`
135
136
  expect(sh.separator === testData.tgt.separator, true);
136
137
 
137
138
  const resSplitted: string[][] = wu.count(0).take(sh.length)
138
- .map((rowIdx) => wu(sh.getSplitted(rowIdx).originals).toArray()).toArray();
139
+ .map((rowIdx) => {
140
+ const seqSS = sh.getSplitted(rowIdx);
141
+ return wu.count(0).take(seqSS.length).map((posIdx) => seqSS.getOriginal(posIdx)).toArray();
142
+ }).toArray();
139
143
  expectArray(resSplitted, testData.tgt.splitted);
140
144
  });
141
145
  }
@@ -144,13 +144,13 @@ PEPTIDE1{hHis.Aca.Cys_SEt}$$$,5.72388
144
144
  });
145
145
 
146
146
  export async function _testFastaSplitter(src: string, tgt: string[]) {
147
- const res: ISeqSplitted = splitterAsFasta(src);
148
- console.debug(`Bio: tests: splitters: src=${JSON.stringify(src)}, res=${JSON.stringify(res)} .`);
149
- expectArray(wu(res.originals).toArray(), tgt);
147
+ const resSS: ISeqSplitted = splitterAsFasta(src);
148
+ console.debug(`Bio: tests: splitters: src=${JSON.stringify(src)}, res=${JSON.stringify(resSS)} .`);
149
+ expectArray(wu.count(0).take(resSS.length).map((p) => resSS.getOriginal(p)).toArray(), tgt);
150
150
  }
151
151
 
152
152
  export async function _testHelmSplitter(src: string, tgt: string[]) {
153
- const res: ISeqSplitted = splitterAsHelm(src);
154
- console.debug(`Bio: tests: splitters: src=${JSON.stringify(src)}, res=${JSON.stringify(res)} .`);
155
- expectArray(wu(res.originals).toArray(), tgt);
153
+ const resSS: ISeqSplitted = splitterAsHelm(src);
154
+ console.debug(`Bio: tests: splitters: src=${JSON.stringify(src)}, res=${JSON.stringify(resSS)} .`);
155
+ expectArray(wu.count(0).take(resSS.length).map((p) => resSS.getOriginal(p)).toArray(), tgt);
156
156
  }
@@ -8,7 +8,7 @@ import wu from 'wu';
8
8
  import {after, before, category, test, expect, delay, testEvent, awaitCheck} from '@datagrok-libraries/utils/src/test';
9
9
  import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
10
10
  import {
11
- getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests
11
+ getUserLibSettings, setUserLibSettings
12
12
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
13
13
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
14
14
  import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
@@ -36,8 +36,7 @@ category('bio-substructure-filters', async () => {
36
36
  userLibSettings = await getUserLibSettings();
37
37
 
38
38
  // Test 'helm' requires default monomer library loaded
39
- await setUserLibSettingsForTests();
40
- await monomerLibHelper.loadMonomerLib(true); // load default libraries
39
+ await monomerLibHelper.loadMonomerLibForTests(); // load default libraries
41
40
  });
42
41
 
43
42
  after(async () => {
@@ -6,19 +6,19 @@ import * as DG from 'datagrok-api/dg';
6
6
  import wu from 'wu';
7
7
 
8
8
  import {before, after, category, test, expectArray, expect} from '@datagrok-libraries/utils/src/test';
9
+ import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
9
10
  import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
10
11
  import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
11
12
  import {ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
13
  import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
13
14
  import {
14
- getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests
15
+ getUserLibSettings, setUserLibSettings
15
16
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
16
17
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
17
18
  import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
19
+ import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
18
20
 
19
- import {toAtomicLevel} from '../package';
20
21
  import {_package} from '../package-test';
21
- import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
22
22
 
23
23
  const appPath = 'System:AppData/Bio';
24
24
  const fileSource = new DG.FileSource(appPath);
@@ -60,12 +60,17 @@ category('toAtomicLevel', async () => {
60
60
  /** Backup actual user's monomer libraries settings */
61
61
  let userLibSettings: UserLibSettings;
62
62
 
63
+ let monomerLib: IMonomerLib;
64
+ let rdKitModule: RDModule;
65
+
63
66
  before(async () => {
67
+ rdKitModule = await getRdKitModule();
64
68
  monomerLibHelper = await getMonomerLibHelper();
65
69
  userLibSettings = await getUserLibSettings();
66
70
  // Clear settings to test default
67
- await setUserLibSettingsForTests();
68
- await monomerLibHelper.loadMonomerLib(true);
71
+ await monomerLibHelper.loadMonomerLibForTests();
72
+
73
+ monomerLib = monomerLibHelper.getMonomerLib();
69
74
 
70
75
  for (const [testName, testData] of Object.entries(TestsData)) {
71
76
  const inputPath = testData.inPath;
@@ -83,7 +88,8 @@ category('toAtomicLevel', async () => {
83
88
 
84
89
  async function getTestResult(source: DG.DataFrame, target: DG.DataFrame): Promise<void> {
85
90
  const inputCol = source.getCol(inputColName);
86
- await toAtomicLevel(source, inputCol, false);
91
+ // await toAtomicLevel(source, inputCol, false);
92
+ await grok.functions.call('Bio:toAtomicLevel', {table: source, seqCol: inputCol, nonlinear: false});
87
93
  const obtainedCol = source.getCol(outputColName);
88
94
  const expectedCol = target.getCol(outputColName);
89
95
  const obtainedArray: string[] = wu(obtainedCol.values()).map((mol) => polishMolfile(mol)).toArray();
@@ -212,19 +218,18 @@ PEPTIDE1{Lys_Boc.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.Aca.Tyr_PO3H2.Thr_PO3H2.Aca.Tyr
212
218
  const resCol = (await _testToAtomicLevel(srcDf, 'seq', monomerLibHelper))!;
213
219
  expect(polishMolfile(resCol.get(0)), polishMolfile(tgtMol));
214
220
  });
221
+
222
+ async function _testToAtomicLevel(
223
+ df: DG.DataFrame, seqColName: string = 'seq', monomerLibHelper: IMonomerLibHelper
224
+ ): Promise<DG.Column | null> {
225
+ const seqCol: DG.Column<string> = df.getCol(seqColName);
226
+ const res = await _toAtomicLevel(df, seqCol, monomerLib, rdKitModule);
227
+ if (res.warnings.length > 0)
228
+ _package.logger.warning(`_toAtomicLevel() warnings ${res.warnings.join('\n')}`);
229
+ return res.molCol;
230
+ }
215
231
  });
216
232
 
217
- async function _testToAtomicLevel(
218
- df: DG.DataFrame, seqColName: string = 'seq', monomerLibHelper: IMonomerLibHelper
219
- ): Promise<DG.Column | null> {
220
- const rdKitModule = await getRdKitModule();
221
- const seqCol: DG.Column<string> = df.getCol(seqColName);
222
- const monomerLib: IMonomerLib = monomerLibHelper.getMonomerLib();
223
- const res = await _toAtomicLevel(df, seqCol, monomerLib);
224
- if (res.warnings.length > 0)
225
- _package.logger.warning(`_toAtomicLevel() warnings ${res.warnings.join('\n')}`);
226
- return res.col;
227
- }
228
233
 
229
234
  function polishMolfile(mol: string): string {
230
235
  return mol.replaceAll('\r\n', '\n')
@@ -4,28 +4,36 @@ import * as grok from 'datagrok-api/grok';
4
4
  import {after, before, category, expect, expectArray, test} from '@datagrok-libraries/utils/src/test';
5
5
  import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
6
6
  import {sequenceToMolfile} from '../utils/sequence-to-mol';
7
- import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
8
7
  import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
9
- import {getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
8
+ import {getUserLibSettings, setUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
10
9
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
11
10
 
12
- import {ConverterFunc} from './types';
13
- import {_package} from '../package';
11
+ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
+ import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
13
+ import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
14
+
15
+ type TestDataTargetType = { atomCount: number, bondCount: number };
16
+ type TestDataType = {
17
+ src: { seq: string, units: NOTATION },
18
+ tgt: TestDataTargetType,
19
+ };
14
20
 
15
21
  category('toAtomicLevel-ui', () => {
16
22
 
17
23
  let monomerLibHelper: IMonomerLibHelper;
18
24
  let userLibSettings: UserLibSettings;
19
- let helmHelper: IHelmHelper;
25
+ let monomerLib: IMonomerLib;
26
+ let rdKitModule: RDModule;
20
27
 
21
28
  before(async () => {
22
- helmHelper = await getHelmHelper(); // init Helm package
29
+ rdKitModule = await getRdKitModule();
23
30
  monomerLibHelper = await getMonomerLibHelper();
24
31
  userLibSettings = await getUserLibSettings();
25
32
 
26
33
  // Test 'helm' requires default monomer library loaded
27
- await setUserLibSettingsForTests();
28
- await monomerLibHelper.loadMonomerLib(true); // load default libraries
34
+ await monomerLibHelper.loadMonomerLibForTests(); // load default libraries
35
+
36
+ monomerLib = monomerLibHelper.getMonomerLib();
29
37
  });
30
38
 
31
39
  after(async () => {
@@ -33,42 +41,72 @@ category('toAtomicLevel-ui', () => {
33
41
  await setUserLibSettings(userLibSettings);
34
42
  await monomerLibHelper.loadMonomerLib(true); // load user settings libraries
35
43
  });
36
- const fastaCsv = `seq
37
- MDYKETLLMPKTDFPMRGGLPNKEPQIQEKW
38
- MIEVFLFGIVLGLIPITLAGLFVTAYLQYRRGDQLDL
39
- MMELVLKTIIGPIVVGVVLRIVDKWLNKDK
40
- `;
41
- const helmCsv = `seq
42
- PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Aze.dV.E.N.dV.Phe_4Me}$$$$
43
- PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.meM.D-Chg.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$
44
- PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.D-Cit.N.D-Orn.D-aThr.Phe_4Me}$$$$
45
- `;
46
44
 
47
- test('toAtomicLevel-fasta-linear', async () => {
48
- const df = DG.DataFrame.fromCsv(fastaCsv);
49
- await grok.data.detectSemanticTypes(df);
50
- const seqCol = df.getCol('seq');
51
- await _testToAtomicLevelFunc(df, seqCol, false);
52
- });
45
+ const tests: { [testName: string]: TestDataType } = {
46
+ 'fasta': {
47
+ src: {seq: 'MDYKETLLMPK', units: NOTATION.FASTA,},
48
+ tgt: {atomCount: 94, bondCount: 95,},
49
+ },
50
+ 'fasta-with-gap': {
51
+ src: {seq: 'MD-YKETLLMPK', units: NOTATION.FASTA,},
52
+ tgt: {atomCount: 94, bondCount: 95,},
53
+ },
54
+ 'helm': {
55
+ src: {seq: 'PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2}$$$$', units: NOTATION.HELM,},
56
+ tgt: {atomCount: 68, bondCount: 68,},
57
+ },
58
+ 'helm-with-gap': {
59
+ src: {seq: 'PEPTIDE1{meI.hHis.*.Aca.N.T.dK.Thr_PO3H2}$$$$', units: NOTATION.HELM,},
60
+ tgt: {atomCount: 68, bondCount: 68,},
61
+ },
62
+ };
53
63
 
54
- test('toAtomicLevel-fasta-nonlinear', async () => {
55
- const df = DG.DataFrame.fromCsv(fastaCsv);
56
- await grok.data.detectSemanticTypes(df);
57
- const seqCol = df.getCol('seq');
58
- await _testToAtomicLevelFunc(df, seqCol, true);
59
- });
64
+ // const fastaCsv = `seq
65
+ // MDYKETLLMPKTDFPMRGGLPNKEPQIQEKW
66
+ // MIEVFLFGIVLGLIPITLAGLFVTAYLQYRRGDQLDL
67
+ // MMELVLKTIIGPIVVGVVLRIVDKWLNKDK
68
+ // `;
69
+ // const helmCsv = `seq
70
+ // PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Aze.dV.E.N.dV.Phe_4Me}$$$$
71
+ // PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.meM.D-Chg.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$
72
+ // PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.D-Cit.N.D-Orn.D-aThr.Phe_4Me}$$$$
73
+ // `;
60
74
 
61
- test('toAtomicLevel-helm', async () => {
62
- const df = DG.DataFrame.fromCsv(helmCsv);
75
+ const getSeqCol = async (testData: TestDataType): Promise<DG.Column<string>> => {
76
+ const seq = testData.src.seq;
77
+ const df = DG.DataFrame.fromColumns([DG.Column.fromList(DG.COLUMN_TYPE.STRING, 'seq', [seq])]);
63
78
  await grok.data.detectSemanticTypes(df);
64
- const seqCol = df.getCol('seq');
65
- await _testToAtomicLevelFunc(df, seqCol, true);
66
- });
79
+ return df.getCol('seq');
80
+ };
81
+
82
+ for (const [testName, testData] of Object.entries(tests)) {
83
+ test(`${testName}-linear`, async () => {
84
+ const seqCol = await getSeqCol(testData);
85
+ await _testToAtomicLevelFunc(seqCol, false, testData.tgt);
86
+ });
87
+ }
88
+ for (const [testName, testData] of Object.entries(tests)) {
89
+ test(`${testName}-nonlinear`, async () => {
90
+ const seqCol = await getSeqCol(testData);
91
+ await _testToAtomicLevelFunc(seqCol, true, testData.tgt);
92
+ });
93
+ }
67
94
 
68
95
  async function _testToAtomicLevelFunc(
69
- table: DG.DataFrame, seqCol: DG.Column<string>, nonlinear: boolean
96
+ seqCol: DG.Column<string>, nonlinear: boolean, tgt: TestDataTargetType,
70
97
  ): Promise<void> {
71
- const molCol = await sequenceToMolfile(table, seqCol, nonlinear, monomerLibHelper.getMonomerLib());
72
- expect(molCol!.semType, DG.SEMTYPE.MOLECULE);
98
+ const res = (await sequenceToMolfile(seqCol.dataFrame, seqCol, nonlinear, false, monomerLib, rdKitModule))!;
99
+ expect(res.molCol!.semType, DG.SEMTYPE.MOLECULE);
100
+ const resMolStr = res.molCol!.get(0)!;
101
+ const resRdMol = rdKitModule.get_mol(resMolStr);
102
+ expect(resRdMol != null, true, 'No molecule generated');
103
+ try {
104
+ const resAtomCount = resRdMol.get_num_atoms();
105
+ const resBondCount = resRdMol.get_num_bonds();
106
+ expect(resAtomCount, tgt.atomCount);
107
+ expect(resBondCount, tgt.bondCount);
108
+ } finally {
109
+ resRdMol.delete();
110
+ }
73
111
  }
74
112
  });
@@ -2,6 +2,4 @@ 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
- export type DfReaderFunc = () => Promise<DG.DataFrame>;
6
-
7
5
  export type ConverterFunc = (srcCol: DG.Column) => DG.Column;
@@ -0,0 +1,63 @@
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 {expect} from '@datagrok-libraries/utils/src/test';
6
+ import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
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, units: string, aligned: string | null,
39
+ 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 = SeqHandler.forColumn(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
+ }
@@ -7,7 +7,7 @@ import {asRenderer, IRenderer, isRenderer} from '@datagrok-libraries/bio/src/typ
7
7
  import {startDockerContainer} from '../utils/docker';
8
8
 
9
9
  import {_package} from '../package-test';
10
- import {CellRendererBackBase, getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
10
+ import {CellRendererBackBase, getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
11
11
 
12
12
  export async function loadFileAsText(name: string): Promise<string> {
13
13
  return await _package.files.readAsText(name);
@@ -47,7 +47,7 @@ export async function awaitGrid(grid: DG.Grid, timeout: number = 5000): Promise<
47
47
  if (gridCol) {
48
48
  const gridCell = grid.cell(gridCol.name, 0);
49
49
  const [_gridCol, _tableCol, temp] =
50
- getGridCellRendererBack<void, CellRendererBackBase<void>>(gridCell);
50
+ getGridCellColTemp<void, CellRendererBackBase<void>>(gridCell);
51
51
 
52
52
  const renderer = asRenderer(temp.rendererBack);
53
53
  if (renderer) await renderer.awaitRendered();
@@ -0,0 +1,62 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as DG from 'datagrok-api/dg';
3
+ import * as ui from 'datagrok-api/ui';
4
+
5
+ import {getGridCellColTemp, CellRendererBackBase} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
6
+ import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
7
+ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
+
9
+ export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
10
+ get name(): string { return 'sequence'; }
11
+
12
+ get cellType(): string { return 'sequence'; }
13
+
14
+ get defaultHeight(): number | null { return 30; }
15
+
16
+ get defaultWidth(): number | null { return 230; }
17
+
18
+ getRendererBack(gridCell: DG.GridCell): CellRendererBackBase<string> {
19
+ const [gridCol, tableCol, temp] = getGridCellColTemp<string, any>(gridCell);
20
+ const sh = SeqHandler.forColumn(tableCol);
21
+ if (sh.notation !== NOTATION.CUSTOM)
22
+ throw new Error(`Unexpected notation: '${sh.notation}'.`);
23
+ const back = sh.getRendererBack(gridCol, tableCol);
24
+ return back;
25
+ }
26
+
27
+ override onMouseLeave(gridCell: DG.GridCell, e: MouseEvent) {
28
+ const back = this.getRendererBack(gridCell);
29
+ back.onMouseLeave(gridCell, e);
30
+ }
31
+
32
+ override onMouseMove(gridCell: DG.GridCell, e: MouseEvent) {
33
+ const back = this.getRendererBack(gridCell);
34
+ back.onMouseMove(gridCell, e);
35
+ }
36
+
37
+ override onClick(gridCell: DG.GridCell, e: MouseEvent) {
38
+ const back = this.getRendererBack(gridCell);
39
+ back.onClick(gridCell, e);
40
+ }
41
+
42
+ override onDoubleClick(gridCell: DG.GridCell, e: MouseEvent) {
43
+ const back = this.getRendererBack(gridCell);
44
+ back.onDoubleClick(gridCell, e);
45
+ }
46
+
47
+ override onKeyDown(gridCell: DG.GridCell, e: KeyboardEvent) {
48
+ const back = this.getRendererBack(gridCell);
49
+ back.onKeyDown(gridCell, e);
50
+ }
51
+
52
+ override onKeyPress(gridCell: DG.GridCell, e: KeyboardEvent) {
53
+ const back = this.getRendererBack(gridCell);
54
+ back.onKeyPress(gridCell, e);
55
+ }
56
+
57
+ override render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell, cellStyle: DG.GridCellStyle) {
58
+ const back = this.getRendererBack(gridCell);
59
+ back.render(g, x, y, w, h, gridCell, cellStyle);
60
+ }
61
+ }
62
+