@datagrok/bio 2.15.13 → 2.16.2
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 +25 -0
- package/detectors.js +16 -11
- package/dist/455.js.map +1 -1
- package/dist/980.js +1 -1
- package/dist/980.js.map +1 -1
- package/dist/package-test.js +6 -6
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +3 -3
- package/dist/package.js.map +1 -1
- package/package.json +14 -14
- package/src/analysis/sequence-activity-cliffs.ts +9 -8
- package/src/analysis/sequence-diversity-viewer.ts +6 -4
- package/src/analysis/sequence-similarity-viewer.ts +9 -6
- package/src/analysis/sequence-space.ts +3 -2
- package/src/calculations/monomerLevelMols.ts +4 -5
- package/src/demo/bio01-similarity-diversity.ts +4 -1
- package/src/package-test.ts +1 -1
- package/src/package-types.ts +34 -2
- package/src/package.ts +60 -76
- package/src/substructure-search/substructure-search.ts +15 -9
- package/src/tests/WebLogo-layout-tests.ts +1 -1
- package/src/tests/WebLogo-positions-test.ts +11 -5
- package/src/tests/WebLogo-project-tests.ts +1 -1
- package/src/tests/activity-cliffs-utils.ts +11 -14
- package/src/tests/bio-tests.ts +85 -79
- package/src/tests/checkInputColumn-tests.ts +15 -10
- package/src/tests/converters-test.ts +12 -5
- package/src/tests/detectors-benchmark-tests.ts +5 -2
- package/src/tests/detectors-tests.ts +51 -44
- package/src/tests/detectors-weak-and-likely-tests.ts +12 -5
- package/src/tests/fasta-export-tests.ts +13 -5
- package/src/tests/helm-tests.ts +85 -0
- package/src/tests/mm-distance-tests.ts +14 -7
- package/src/tests/monomer-libraries-tests.ts +1 -1
- package/src/tests/msa-tests.ts +33 -24
- package/src/tests/renderers-monomer-placer-tests.ts +2 -5
- package/src/tests/renderers-test.ts +15 -9
- package/src/tests/scoring.ts +9 -6
- package/src/tests/seq-handler-get-helm-tests.ts +7 -5
- package/src/tests/seq-handler-get-region-tests.ts +9 -3
- package/src/tests/seq-handler-splitted-tests.ts +11 -5
- package/src/tests/seq-handler-tests.ts +17 -10
- package/src/tests/sequence-space-utils.ts +9 -4
- package/src/tests/splitters-test.ts +5 -4
- package/src/tests/substructure-filters-tests.ts +22 -23
- package/src/tests/to-atomic-level-tests.ts +5 -3
- package/src/tests/to-atomic-level-ui-tests.ts +4 -1
- package/src/tests/utils/detectors-utils.ts +4 -4
- package/src/utils/calculate-scores.ts +11 -9
- package/src/utils/cell-renderer-custom.ts +27 -17
- package/src/utils/cell-renderer.ts +14 -8
- package/src/utils/check-input-column.ts +13 -9
- package/src/utils/context-menu.ts +4 -4
- package/src/utils/convert.ts +21 -14
- package/src/utils/get-region-func-editor.ts +8 -5
- package/src/utils/get-region.ts +4 -5
- package/src/utils/helm-to-molfile/converter/helm.ts +4 -4
- package/src/utils/helm-to-molfile/utils.ts +5 -6
- package/src/utils/macromolecule-column-widget.ts +6 -7
- package/src/utils/monomer-cell-renderer-base.ts +8 -1
- package/src/utils/monomer-lib/lib-manager.ts +3 -2
- package/src/utils/monomer-lib/monomer-colors.ts +10 -10
- package/src/utils/monomer-lib/monomer-lib-base.ts +6 -1
- package/src/utils/monomer-lib/monomer-lib.ts +15 -9
- package/src/utils/multiple-sequence-alignment-ui.ts +30 -30
- package/src/utils/save-as-fasta.ts +19 -12
- package/src/utils/seq-helper/seq-handler.ts +836 -0
- package/src/utils/seq-helper/seq-helper.ts +43 -19
- package/src/utils/sequence-to-mol.ts +7 -8
- package/src/utils/split-to-monomers.ts +7 -2
- package/src/utils/types.ts +8 -7
- package/src/utils/ui-utils.ts +2 -2
- package/src/viewers/web-logo-viewer.ts +18 -16
- package/src/widgets/bio-substructure-filter-helm.ts +5 -2
- package/src/widgets/bio-substructure-filter.ts +14 -24
- package/src/widgets/composition-analysis-widget.ts +6 -6
- package/src/widgets/representations.ts +7 -4
- package/src/tests/detectors-custom-notation-tests.ts +0 -37
- package/src/utils/cyclized.ts +0 -89
- package/src/utils/dimerized.ts +0 -10
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
|
|
3
4
|
import {expect} from '@datagrok-libraries/utils/src/test';
|
|
4
|
-
import {sequenceSpaceTopMenu} from '../package';
|
|
5
5
|
import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
|
|
6
6
|
import {BYPASS_LARGE_DATA_WARNING} from '@datagrok-libraries/ml/src/functionEditors/consts';
|
|
7
7
|
import {DimReductionMethods} from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/types';
|
|
8
8
|
|
|
9
9
|
export async function _testSequenceSpaceReturnsResult(
|
|
10
|
-
df: DG.DataFrame, algorithm: DimReductionMethods, colName: string
|
|
10
|
+
df: DG.DataFrame, algorithm: DimReductionMethods, colName: string
|
|
11
11
|
) {
|
|
12
12
|
// await grok.data.detectSemanticTypes(df);
|
|
13
13
|
const col: DG.Column = df.getCol(colName);
|
|
@@ -18,7 +18,12 @@ export async function _testSequenceSpaceReturnsResult(
|
|
|
18
18
|
const preprocessingFunc = DG.Func.find({package: 'Bio', name: 'macromoleculePreprocessingFunction'})[0];
|
|
19
19
|
if (!preprocessingFunc)
|
|
20
20
|
throw new Error('Preprocessing function not found');
|
|
21
|
-
const sp = await
|
|
22
|
-
|
|
21
|
+
const sp = await grok.functions.call('Bio:sequenceSpaceTopMenu', {
|
|
22
|
+
table: df, molecules: df.col(colName)!,
|
|
23
|
+
methodName: algorithm, similarityMetric: MmDistanceFunctionsNames.LEVENSHTEIN,
|
|
24
|
+
plotEmbeddings: true, preprocessingFunction: preprocessingFunc, options: {[BYPASS_LARGE_DATA_WARNING]: true}
|
|
25
|
+
});
|
|
26
|
+
// const sp = await sequenceSpaceTopMenu(df, df.col(colName)!, algorithm, MmDistanceFunctionsNames.LEVENSHTEIN, true,
|
|
27
|
+
// preprocessingFunc, {[BYPASS_LARGE_DATA_WARNING]: true});
|
|
23
28
|
expect(sp != null, true);
|
|
24
29
|
}
|
|
@@ -11,13 +11,12 @@ import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/type
|
|
|
11
11
|
import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
12
12
|
import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
13
13
|
import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
14
|
+
import {ISeqHelper, getSeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
14
15
|
|
|
15
16
|
import {splitToMonomersUI} from '../utils/split-to-monomers';
|
|
16
17
|
import {awaitGrid} from './utils';
|
|
17
18
|
import * as C from '../utils/constants';
|
|
18
|
-
import {getHelmMonomers} from '../package';
|
|
19
19
|
|
|
20
|
-
import {_package} from '../package-test';
|
|
21
20
|
import {getUserLibSettings, setUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
22
21
|
|
|
23
22
|
category('splitters', async () => {
|
|
@@ -89,10 +88,12 @@ category('splitters', async () => {
|
|
|
89
88
|
});
|
|
90
89
|
|
|
91
90
|
category('splitters', () => {
|
|
91
|
+
let seqHelper: ISeqHelper;
|
|
92
92
|
let monomerLibHelper: IMonomerLibHelper;
|
|
93
93
|
let userLibSettings: UserLibSettings;
|
|
94
94
|
|
|
95
95
|
before(async () => {
|
|
96
|
+
seqHelper = await getSeqHelper();
|
|
96
97
|
monomerLibHelper = await getMonomerLibHelper();
|
|
97
98
|
userLibSettings = await getUserLibSettings();
|
|
98
99
|
|
|
@@ -113,7 +114,7 @@ category('splitters', () => {
|
|
|
113
114
|
seqCol.semType = semType;
|
|
114
115
|
seqCol.setTag(bioTAGS.aligned, C.MSA);
|
|
115
116
|
|
|
116
|
-
const newDf = await
|
|
117
|
+
const newDf: DG.DataFrame = await grok.functions.call('Bio:splitToMonomersTopMenu', {table: df, sequence: seqCol});
|
|
117
118
|
expect(newDf.columns.names().includes('17'), true);
|
|
118
119
|
// call to calculate 'cell.renderer' tag
|
|
119
120
|
await grok.data.detectSemanticTypes(newDf);
|
|
@@ -134,7 +135,7 @@ PEPTIDE1{hHis.Aca.Cys_SEt}$$$,5.72388
|
|
|
134
135
|
const expectedMonomerList = ['hHis', 'Aca', 'Cys_SEt', 'N', 'T'];
|
|
135
136
|
|
|
136
137
|
const helmCol: DG.Column = df.getCol('HELM');
|
|
137
|
-
const res = getHelmMonomers
|
|
138
|
+
const res = await grok.functions.call('Bio:getHelmMonomers', {sequence: helmCol}) as string[];
|
|
138
139
|
|
|
139
140
|
const missed = expectedMonomerList.filter((m) => !res.includes(m));
|
|
140
141
|
const unexpected = res.filter((m) => !expectedMonomerList.includes(m));
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
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
|
-
import {
|
|
14
|
+
import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
15
15
|
|
|
16
16
|
import {awaitGrid, readDataframe} from './utils';
|
|
17
17
|
|
|
@@ -23,15 +23,14 @@ import {HelmBioFilter} from '../widgets/bio-substructure-filter-helm';
|
|
|
23
23
|
|
|
24
24
|
import {_package} from '../package-test';
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
category('bio-substructure-filters', async () => {
|
|
28
|
-
let
|
|
27
|
+
let seqHelper: ISeqHelper;
|
|
29
28
|
let monomerLibHelper: IMonomerLibHelper;
|
|
30
29
|
/** Backup actual user's monomer libraries settings */
|
|
31
30
|
let userLibSettings: UserLibSettings;
|
|
32
31
|
|
|
33
32
|
before(async () => {
|
|
34
|
-
|
|
33
|
+
seqHelper = await getSeqHelper();
|
|
35
34
|
monomerLibHelper = await getMonomerLibHelper();
|
|
36
35
|
userLibSettings = await getUserLibSettings();
|
|
37
36
|
|
|
@@ -52,7 +51,7 @@ category('bio-substructure-filters', async () => {
|
|
|
52
51
|
const fSubStr: string = 'MD';
|
|
53
52
|
const fTrueCount: number = 3;
|
|
54
53
|
|
|
55
|
-
const filter = new BioSubstructureFilter();
|
|
54
|
+
const filter = new BioSubstructureFilter(seqHelper, _package.logger);
|
|
56
55
|
filter.attach(df);
|
|
57
56
|
await filter.awaitRendered();
|
|
58
57
|
try {
|
|
@@ -73,7 +72,7 @@ category('bio-substructure-filters', async () => {
|
|
|
73
72
|
|
|
74
73
|
test('separator', async () => {
|
|
75
74
|
const msa = await readDataframe('tests/filter_MSA.csv');
|
|
76
|
-
const filter = new BioSubstructureFilter();
|
|
75
|
+
const filter = new BioSubstructureFilter(seqHelper, _package.logger);
|
|
77
76
|
await grok.data.detectSemanticTypes(msa);
|
|
78
77
|
filter.attach(msa);
|
|
79
78
|
await filter.awaitRendered();
|
|
@@ -112,7 +111,7 @@ category('bio-substructure-filters', async () => {
|
|
|
112
111
|
// // // Helm filter calls waitForElementInDom
|
|
113
112
|
// // const fg = view.getFiltersGroup({createDefaultFilters: false});
|
|
114
113
|
// // _package.logger.debug('Bio tests: substructureFilters/helm, filter attaching.');
|
|
115
|
-
// // const filter =
|
|
114
|
+
// // const filter = await createBioSubstructureFilter();
|
|
116
115
|
// // filter.attach(df);
|
|
117
116
|
// // _package.logger.debug('Bio tests: substructureFilters/helm, filter attached.');
|
|
118
117
|
// // const fg = await df.plot.fromType(DG.VIEWER.FILTERS, {
|
|
@@ -157,7 +156,7 @@ category('bio-substructure-filters', async () => {
|
|
|
157
156
|
const view = grok.shell.addTableView(df);
|
|
158
157
|
|
|
159
158
|
_package.logger.debug(`${logPrefix}, filter attaching.`);
|
|
160
|
-
const filter = new BioSubstructureFilter();
|
|
159
|
+
const filter = new BioSubstructureFilter(seqHelper, _package.logger);
|
|
161
160
|
filter.attach(df);
|
|
162
161
|
const dlg = ui.dialog('Test filters').add(filter.root).show(); // to waitForElementInDom
|
|
163
162
|
await filter.awaitRendered();
|
|
@@ -337,7 +336,6 @@ category('bio-substructure-filters', async () => {
|
|
|
337
336
|
const fSeq2SubStr: string = 'GCATT';
|
|
338
337
|
const fSeq2Trues: number[] = df.getCol('trueSeq2').toList();
|
|
339
338
|
|
|
340
|
-
//const seq2Filter = new BioSubstructureFilter();
|
|
341
339
|
const filterList: any[] = [
|
|
342
340
|
{type: 'Bio:bioSubstructureFilter', columnName: fSeq1ColName},
|
|
343
341
|
{type: 'Bio:bioSubstructureFilter', columnName: fSeq2ColName},
|
|
@@ -451,19 +449,20 @@ category('bio-substructure-filters', async () => {
|
|
|
451
449
|
await delay(100);
|
|
452
450
|
await awaitGrid(view.grid);
|
|
453
451
|
});
|
|
452
|
+
|
|
453
|
+
async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
|
|
454
|
+
if (!df.columns.names().includes(colName)) {
|
|
455
|
+
throw new Error(`The column '${colName}' not found. ` +
|
|
456
|
+
`Available in data frame are ${JSON.stringify(df.columns.names())}`);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const filter = new BioSubstructureFilter(seqHelper, _package.logger);
|
|
460
|
+
filter.attach(df);
|
|
461
|
+
filter.applyState({columnName: colName});
|
|
462
|
+
filter.column = df.col(colName);
|
|
463
|
+
filter.columnName = colName;
|
|
464
|
+
//filter.tableName = df.name;
|
|
465
|
+
return filter;
|
|
466
|
+
};
|
|
454
467
|
});
|
|
455
468
|
|
|
456
|
-
async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
|
|
457
|
-
if (!df.columns.names().includes(colName)) {
|
|
458
|
-
throw new Error(`The column '${colName}' not found. ` +
|
|
459
|
-
`Available in data frame are ${JSON.stringify(df.columns.names())}`);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
const filter = new BioSubstructureFilter();
|
|
463
|
-
filter.attach(df);
|
|
464
|
-
filter.applyState({columnName: colName});
|
|
465
|
-
filter.column = df.col(colName);
|
|
466
|
-
filter.columnName = colName;
|
|
467
|
-
//filter.tableName = df.name;
|
|
468
|
-
return filter;
|
|
469
|
-
};
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
getUserLibSettings, setUserLibSettings
|
|
16
16
|
} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
17
17
|
import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
18
|
-
import {
|
|
18
|
+
import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
19
19
|
import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
20
20
|
|
|
21
21
|
import {_package} from '../package-test';
|
|
@@ -60,11 +60,13 @@ category('toAtomicLevel', async () => {
|
|
|
60
60
|
/** Backup actual user's monomer libraries settings */
|
|
61
61
|
let userLibSettings: UserLibSettings;
|
|
62
62
|
|
|
63
|
+
let seqHelper: ISeqHelper;
|
|
63
64
|
let monomerLib: IMonomerLib;
|
|
64
65
|
let rdKitModule: RDModule;
|
|
65
66
|
|
|
66
67
|
before(async () => {
|
|
67
68
|
rdKitModule = await getRdKitModule();
|
|
69
|
+
seqHelper = await getSeqHelper();
|
|
68
70
|
monomerLibHelper = await getMonomerLibHelper();
|
|
69
71
|
userLibSettings = await getUserLibSettings();
|
|
70
72
|
// Clear settings to test default
|
|
@@ -214,7 +216,7 @@ PEPTIDE1{Lys_Boc.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.Aca.Tyr_PO3H2.Thr_PO3H2.Aca.Tyr
|
|
|
214
216
|
seqCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
215
217
|
seqCol.meta.units = NOTATION.FASTA;
|
|
216
218
|
seqCol.setTag(bioTAGS.alphabet, ALPHABET.PT);
|
|
217
|
-
const sh =
|
|
219
|
+
const sh = seqHelper.getSeqHandler(seqCol);
|
|
218
220
|
const resCol = (await _testToAtomicLevel(srcDf, 'seq', monomerLibHelper))!;
|
|
219
221
|
expect(polishMolfile(resCol.get(0)), polishMolfile(tgtMol));
|
|
220
222
|
});
|
|
@@ -223,7 +225,7 @@ PEPTIDE1{Lys_Boc.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.Aca.Tyr_PO3H2.Thr_PO3H2.Aca.Tyr
|
|
|
223
225
|
df: DG.DataFrame, seqColName: string = 'seq', monomerLibHelper: IMonomerLibHelper
|
|
224
226
|
): Promise<DG.Column | null> {
|
|
225
227
|
const seqCol: DG.Column<string> = df.getCol(seqColName);
|
|
226
|
-
const res = await _toAtomicLevel(df, seqCol, monomerLib, rdKitModule);
|
|
228
|
+
const res = await _toAtomicLevel(df, seqCol, monomerLib, seqHelper, rdKitModule);
|
|
227
229
|
if (res.warnings.length > 0)
|
|
228
230
|
_package.logger.warning(`_toAtomicLevel() warnings ${res.warnings.join('\n')}`);
|
|
229
231
|
return res.molCol;
|
|
@@ -11,6 +11,7 @@ import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
|
11
11
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
12
12
|
import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
13
13
|
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
14
|
+
import {ISeqHelper, getSeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
14
15
|
|
|
15
16
|
type TestDataTargetType = { atomCount: number, bondCount: number };
|
|
16
17
|
type TestDataType = {
|
|
@@ -22,10 +23,12 @@ category('toAtomicLevel-ui', () => {
|
|
|
22
23
|
|
|
23
24
|
let monomerLibHelper: IMonomerLibHelper;
|
|
24
25
|
let userLibSettings: UserLibSettings;
|
|
26
|
+
let seqHelper: ISeqHelper;
|
|
25
27
|
let monomerLib: IMonomerLib;
|
|
26
28
|
let rdKitModule: RDModule;
|
|
27
29
|
|
|
28
30
|
before(async () => {
|
|
31
|
+
seqHelper = await getSeqHelper();
|
|
29
32
|
rdKitModule = await getRdKitModule();
|
|
30
33
|
monomerLibHelper = await getMonomerLibHelper();
|
|
31
34
|
userLibSettings = await getUserLibSettings();
|
|
@@ -95,7 +98,7 @@ category('toAtomicLevel-ui', () => {
|
|
|
95
98
|
async function _testToAtomicLevelFunc(
|
|
96
99
|
seqCol: DG.Column<string>, nonlinear: boolean, tgt: TestDataTargetType,
|
|
97
100
|
): Promise<void> {
|
|
98
|
-
const res = (await sequenceToMolfile(seqCol.dataFrame, seqCol, nonlinear, false, monomerLib, rdKitModule))!;
|
|
101
|
+
const res = (await sequenceToMolfile(seqCol.dataFrame, seqCol, nonlinear, false, monomerLib, seqHelper, rdKitModule))!;
|
|
99
102
|
expect(res.molCol!.semType, DG.SEMTYPE.MOLECULE);
|
|
100
103
|
const resMolStr = res.molCol!.get(0)!;
|
|
101
104
|
const resRdMol = rdKitModule.get_mol(resMolStr);
|
|
@@ -3,7 +3,7 @@ import * as grok from 'datagrok-api/grok';
|
|
|
3
3
|
|
|
4
4
|
import {ALIGNMENT, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
5
5
|
import {expect} from '@datagrok-libraries/utils/src/test';
|
|
6
|
-
import {
|
|
6
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
7
7
|
|
|
8
8
|
export type DetectorTestData = { [testName: string]: { csv: string, neg?: string[], pos?: { [colName: string]: PosCol } } };
|
|
9
9
|
|
|
@@ -35,8 +35,8 @@ export async function _testNeg(readDf: DfReaderFunc, colName: string) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export async function _testPos(
|
|
38
|
-
readDf: DfReaderFunc, colName: string,
|
|
39
|
-
alphabet: string | null, alphabetSize: number, alphabetIsMultichar?: boolean,
|
|
38
|
+
readDf: DfReaderFunc, colName: string, seqHelper: ISeqHelper,
|
|
39
|
+
units: string, aligned: string | null, alphabet: string | null, alphabetSize: number, alphabetIsMultichar?: boolean,
|
|
40
40
|
separator: string | null = null,
|
|
41
41
|
) {
|
|
42
42
|
const df: DG.DataFrame = await readDf();
|
|
@@ -53,7 +53,7 @@ export async function _testPos(
|
|
|
53
53
|
if (separator)
|
|
54
54
|
expect(col.getTag(bioTAGS.separator), separator);
|
|
55
55
|
|
|
56
|
-
const sh =
|
|
56
|
+
const sh = seqHelper.getSeqHandler(col);
|
|
57
57
|
expect(sh.getAlphabetSize(), alphabetSize);
|
|
58
58
|
expect(sh.getAlphabetIsMultichar(), alphabetIsMultichar);
|
|
59
59
|
if (!sh.isHelm()) {
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import {calculateScores, SCORE} from '@datagrok-libraries/bio/src/utils/macromolecule/scoring';
|
|
4
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
3
5
|
|
|
4
6
|
export async function calculateScoresWithEmptyValues(
|
|
5
|
-
|
|
7
|
+
table: DG.DataFrame, macromolecule: DG.Column, reference: string, scoring: SCORE, seqHelper: ISeqHelper,
|
|
6
8
|
): Promise<DG.Column<number>> {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
9
|
+
const scores = await calculateScores(table, macromolecule, reference, scoring, seqHelper);
|
|
10
|
+
for (let i = 0; i < scores.length; i++) {
|
|
11
|
+
if (macromolecule.isNone(i))
|
|
12
|
+
scores.set(i, null, false);
|
|
13
|
+
}
|
|
14
|
+
return scores;
|
|
15
|
+
}
|
|
@@ -3,11 +3,14 @@ import * as DG from 'datagrok-api/dg';
|
|
|
3
3
|
import * as ui from 'datagrok-api/ui';
|
|
4
4
|
|
|
5
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
6
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
8
|
-
import {
|
|
7
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
8
|
+
|
|
9
|
+
import {_package} from '../package';
|
|
9
10
|
|
|
10
11
|
export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
|
|
12
|
+
private readonly seqHelper: ISeqHelper;
|
|
13
|
+
|
|
11
14
|
get name(): string { return 'sequence'; }
|
|
12
15
|
|
|
13
16
|
get cellType(): string { return 'sequence'; }
|
|
@@ -16,18 +19,26 @@ export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
|
|
|
16
19
|
|
|
17
20
|
get defaultWidth(): number | null { return 230; }
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
this.seqHelper = _package.seqHelper;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getRendererBack(gridCell: DG.GridCell): CellRendererBackBase<string> | null {
|
|
28
|
+
const [gridCol, tableCol, _temp] = getGridCellColTemp<string, any>(gridCell);
|
|
29
|
+
let back: CellRendererBackBase<string> | null = null;
|
|
30
|
+
if (this.seqHelper) {
|
|
31
|
+
const sh = this.seqHelper.getSeqHandler(tableCol);
|
|
32
|
+
if (sh.notation !== NOTATION.CUSTOM)
|
|
33
|
+
throw new Error(`Unexpected notation: '${sh.notation}'.`);
|
|
34
|
+
back = sh.getRendererBack(gridCol, tableCol);
|
|
35
|
+
}
|
|
25
36
|
return back;
|
|
26
37
|
}
|
|
27
38
|
|
|
28
|
-
override onMouseEnter(gridCell: GridCell, e: MouseEvent) {
|
|
39
|
+
override onMouseEnter(gridCell: DG.GridCell, e: MouseEvent) {
|
|
29
40
|
const back = this.getRendererBack(gridCell);
|
|
30
|
-
back
|
|
41
|
+
back?.onMouseEnter(gridCell, e);
|
|
31
42
|
}
|
|
32
43
|
|
|
33
44
|
override onMouseLeave(gridCell: DG.GridCell, e: MouseEvent) {
|
|
@@ -39,32 +50,31 @@ export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
|
|
|
39
50
|
|
|
40
51
|
override onMouseMove(gridCell: DG.GridCell, e: MouseEvent) {
|
|
41
52
|
const back = this.getRendererBack(gridCell);
|
|
42
|
-
back
|
|
53
|
+
back?.onMouseMove(gridCell, e);
|
|
43
54
|
}
|
|
44
55
|
|
|
45
56
|
override onClick(gridCell: DG.GridCell, e: MouseEvent) {
|
|
46
57
|
const back = this.getRendererBack(gridCell);
|
|
47
|
-
back
|
|
58
|
+
back?.onClick(gridCell, e);
|
|
48
59
|
}
|
|
49
60
|
|
|
50
61
|
override onDoubleClick(gridCell: DG.GridCell, e: MouseEvent) {
|
|
51
62
|
const back = this.getRendererBack(gridCell);
|
|
52
|
-
back
|
|
63
|
+
back?.onDoubleClick(gridCell, e);
|
|
53
64
|
}
|
|
54
65
|
|
|
55
66
|
override onKeyDown(gridCell: DG.GridCell, e: KeyboardEvent) {
|
|
56
67
|
const back = this.getRendererBack(gridCell);
|
|
57
|
-
back
|
|
68
|
+
back?.onKeyDown(gridCell, e);
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
override onKeyPress(gridCell: DG.GridCell, e: KeyboardEvent) {
|
|
61
72
|
const back = this.getRendererBack(gridCell);
|
|
62
|
-
back
|
|
73
|
+
back?.onKeyPress(gridCell, e);
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
override render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell, cellStyle: DG.GridCellStyle) {
|
|
66
77
|
const back = this.getRendererBack(gridCell);
|
|
67
|
-
back
|
|
78
|
+
back?.render(g, x, y, w, h, gridCell, cellStyle);
|
|
68
79
|
}
|
|
69
80
|
}
|
|
70
|
-
|
|
@@ -17,21 +17,19 @@ import {
|
|
|
17
17
|
TAGS as bioTAGS,
|
|
18
18
|
ALPHABET,
|
|
19
19
|
} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
20
|
-
import {
|
|
20
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
21
21
|
import {getSplitter} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
|
|
22
|
-
import {
|
|
22
|
+
import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
|
|
23
23
|
import {GapOriginals} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
|
|
24
|
-
import {ISeqMonomer} from '@datagrok-libraries/bio/src/helm/types';
|
|
25
24
|
import {execMonomerHoverLinks} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
|
|
26
|
-
import {
|
|
25
|
+
import {getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
27
26
|
import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
|
|
28
27
|
import {MmcrTemps, rendererSettingsChangedState, tempTAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
|
|
29
|
-
|
|
28
|
+
|
|
29
|
+
import {CellRendererWithMonomerLibBackBase} from './monomer-cell-renderer-base';
|
|
30
30
|
import * as C from './constants';
|
|
31
31
|
|
|
32
32
|
import {_package} from '../package';
|
|
33
|
-
import {CellRendererWithMonomerLibBackBase} from './monomer-cell-renderer-base';
|
|
34
|
-
import {timeout} from 'rxjs/operators';
|
|
35
33
|
|
|
36
34
|
type TempType = { [tagName: string]: any };
|
|
37
35
|
|
|
@@ -60,6 +58,8 @@ type RendererGridCellTemp = {
|
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
61
|
+
private readonly seqHelper: ISeqHelper;
|
|
62
|
+
|
|
63
63
|
get name(): string { return 'sequence'; }
|
|
64
64
|
|
|
65
65
|
get cellType(): string { return 'sequence'; }
|
|
@@ -68,6 +68,11 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
68
68
|
|
|
69
69
|
get defaultWidth(): number | null { return 230; }
|
|
70
70
|
|
|
71
|
+
constructor() {
|
|
72
|
+
super();
|
|
73
|
+
this.seqHelper = _package.seqHelper;
|
|
74
|
+
}
|
|
75
|
+
|
|
71
76
|
onClick(gridCell: DG.GridCell, _e: MouseEvent): void {
|
|
72
77
|
const colTemp: TempType = gridCell.cell.column.temp;
|
|
73
78
|
colTemp[tempTAGS.currentWord] = gridCell.cell.value;
|
|
@@ -106,7 +111,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
106
111
|
getGridCellColTemp<string, MonomerPlacer>(gridCell);
|
|
107
112
|
if (!tableCol) return;
|
|
108
113
|
const tableColTemp: TempType = tableCol.temp;
|
|
109
|
-
const sh =
|
|
114
|
+
const sh = this.seqHelper.getSeqHandler(tableCol);
|
|
110
115
|
|
|
111
116
|
let gapLength = 0;
|
|
112
117
|
const msaGapLength = 8;
|
|
@@ -132,6 +137,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
132
137
|
};
|
|
133
138
|
});
|
|
134
139
|
tableCol.temp[MmcrTemps.rendererSettingsChanged] === rendererSettingsChangedState.true;
|
|
140
|
+
seqColTemp.init().then(() => {});
|
|
135
141
|
}
|
|
136
142
|
|
|
137
143
|
seqColTemp.render(g, x, y, w, h, gridCell, _cellStyle);
|
|
@@ -2,7 +2,9 @@ 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 {
|
|
5
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
6
|
+
|
|
7
|
+
import {_package} from '../package';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Checks if the column is suitable for the analysis.
|
|
@@ -13,9 +15,11 @@ import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
|
13
15
|
* @param {boolean} notify show warning message if the column is not suitable for the analysis
|
|
14
16
|
* @return {boolean} True if the column is suitable for the analysis.
|
|
15
17
|
*/
|
|
16
|
-
export function checkInputColumnUI(col: DG.Column, name: string,
|
|
17
|
-
allowedAlphabets: string[] = [], notify: boolean = true
|
|
18
|
-
|
|
18
|
+
export function checkInputColumnUI(col: DG.Column, name: string,
|
|
19
|
+
allowedNotations: string[] = [], allowedAlphabets: string[] = [], notify: boolean = true
|
|
20
|
+
): boolean {
|
|
21
|
+
const seqHelper = _package.seqHelper;
|
|
22
|
+
const [res, msg]: [boolean, string] = checkInputColumn(col, name, seqHelper, allowedNotations, allowedAlphabets);
|
|
19
23
|
if (notify && !res)
|
|
20
24
|
grok.shell.warning(msg);
|
|
21
25
|
return res;
|
|
@@ -23,23 +27,23 @@ export function checkInputColumnUI(col: DG.Column, name: string, allowedNotation
|
|
|
23
27
|
|
|
24
28
|
/**
|
|
25
29
|
* Checks if the column is suitable for the analysis.
|
|
26
|
-
* @param {DG.Column} col macromolecule
|
|
27
|
-
* @param {string} name
|
|
30
|
+
* @param {DG.Column} col macromolecule column.
|
|
31
|
+
* @param {string} name Analysis name
|
|
28
32
|
* @param {string[]} allowedNotations allowed notations
|
|
29
33
|
* @param {string[]} allowedAlphabets allowed alphabets
|
|
30
34
|
* @return {[boolean, string]} [True if the column is suitable for the analysis, warning message].
|
|
31
35
|
*/
|
|
32
|
-
export function checkInputColumn(
|
|
33
|
-
|
|
36
|
+
export function checkInputColumn(col: DG.Column, name: string, seqHelper: ISeqHelper,
|
|
37
|
+
allowedNotations: string[] = [], allowedAlphabets: string[] = [],
|
|
34
38
|
): [boolean, string] {
|
|
35
39
|
let res: boolean = true;
|
|
36
40
|
let msg: string = '';
|
|
37
41
|
|
|
38
|
-
const sh = SeqHandler.forColumn(col);
|
|
39
42
|
if (col.semType !== DG.SEMTYPE.MACROMOLECULE) {
|
|
40
43
|
grok.shell.warning(name + ' analysis is allowed for Macromolecules semantic type');
|
|
41
44
|
res = false;
|
|
42
45
|
} else {
|
|
46
|
+
const sh = seqHelper.getSeqHandler(col);
|
|
43
47
|
const notation: string = sh.notation;
|
|
44
48
|
if (allowedNotations.length > 0 &&
|
|
45
49
|
!allowedNotations.some((n) => notation.toUpperCase() == (n.toUpperCase()))
|
|
@@ -2,21 +2,21 @@ 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
5
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
6
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
7
7
|
|
|
8
8
|
import {_package} from '../package';
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
export function addCopyMenuUI(cell: DG.Cell, menu: DG.Menu): void {
|
|
12
|
-
const sh =
|
|
11
|
+
export function addCopyMenuUI(cell: DG.Cell, menu: DG.Menu, seqHelper: ISeqHelper): void {
|
|
12
|
+
const sh = seqHelper.getSeqHandler(cell.column);
|
|
13
13
|
const tgtNotationList: string[] = Object.values(NOTATION).filter((v) => v !== sh.units);
|
|
14
14
|
|
|
15
15
|
menu.group('Copy')
|
|
16
16
|
.items(tgtNotationList, (tgtNotation) => {
|
|
17
17
|
const srcCol = cell.column;
|
|
18
18
|
const srcRowIdx = cell.rowIndex;
|
|
19
|
-
const srcSh =
|
|
19
|
+
const srcSh = seqHelper.getSeqHandler(srcCol);
|
|
20
20
|
const separator = tgtNotation === NOTATION.SEPARATOR ? _package.properties.defaultSeparator : undefined;
|
|
21
21
|
const joiner = srcSh.getJoiner({notation: tgtNotation as NOTATION, separator});
|
|
22
22
|
const srcSS = srcSh.getSplitted(srcRowIdx);
|
package/src/utils/convert.ts
CHANGED
|
@@ -6,7 +6,7 @@ import $ from 'cash-dom';
|
|
|
6
6
|
import {Subscription} from 'rxjs';
|
|
7
7
|
|
|
8
8
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
9
|
-
import {
|
|
9
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
let convertDialog: DG.Dialog | null = null;
|
|
@@ -15,13 +15,14 @@ let convertDialogSubs: Subscription[] = [];
|
|
|
15
15
|
/**
|
|
16
16
|
* Converts notations of a Macromolecule column
|
|
17
17
|
*
|
|
18
|
-
* @param {DG.
|
|
18
|
+
* @param {DG.Column<string>} col Column with 'Macromolecule' semantic type
|
|
19
|
+
* @param {ISeqHelper} seqHelper
|
|
19
20
|
*/
|
|
20
|
-
export function convert(col
|
|
21
|
+
export function convert(col: DG.Column<string> | undefined, seqHelper: ISeqHelper): void {
|
|
21
22
|
let srcCol = col ?? grok.shell.t.columns.bySemType('Macromolecule')!;
|
|
22
23
|
if (!srcCol)
|
|
23
24
|
throw new Error('No column with Macromolecule semantic type found');
|
|
24
|
-
let converterSh =
|
|
25
|
+
let converterSh = seqHelper.getSeqHandler(srcCol);
|
|
25
26
|
let currentNotation: NOTATION = converterSh.notation;
|
|
26
27
|
const dialogHeader = ui.divText(
|
|
27
28
|
'Current notation: ' + currentNotation,
|
|
@@ -46,14 +47,16 @@ export function convert(col?: DG.Column): void {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
srcCol = newCol;
|
|
49
|
-
converterSh =
|
|
50
|
+
converterSh = seqHelper.getSeqHandler(srcCol);
|
|
50
51
|
currentNotation = converterSh.notation;
|
|
51
52
|
if (currentNotation === NOTATION.HELM)
|
|
52
53
|
separatorInput.value = '/'; // helm monomers can have - in the name like D-aThr;
|
|
53
54
|
dialogHeader.textContent = 'Current notation: ' + currentNotation;
|
|
54
55
|
filteredNotations = notations.filter((e) => e !== currentNotation);
|
|
55
|
-
targetNotationInput = ui.input.choice('Convert to', {
|
|
56
|
-
|
|
56
|
+
targetNotationInput = ui.input.choice('Convert to', {
|
|
57
|
+
value: filteredNotations[0], items: filteredNotations,
|
|
58
|
+
onValueChanged: toggleSeparator
|
|
59
|
+
});
|
|
57
60
|
toggleSeparator();
|
|
58
61
|
convertDialog?.clear();
|
|
59
62
|
convertDialog?.add(ui.div([
|
|
@@ -64,8 +67,10 @@ export function convert(col?: DG.Column): void {
|
|
|
64
67
|
]));
|
|
65
68
|
};
|
|
66
69
|
|
|
67
|
-
const targetColumnInput = ui.input.column('Column', {
|
|
68
|
-
|
|
70
|
+
const targetColumnInput = ui.input.column('Column', {
|
|
71
|
+
table: grok.shell.t, value: srcCol,
|
|
72
|
+
onValueChanged: (value) => toggleColumn(value)
|
|
73
|
+
});
|
|
69
74
|
|
|
70
75
|
const separatorArray = ['-', '.', '/'];
|
|
71
76
|
let filteredNotations = notations.filter((e) => e !== currentNotation);
|
|
@@ -79,8 +84,10 @@ export function convert(col?: DG.Column): void {
|
|
|
79
84
|
else
|
|
80
85
|
$(separatorInput.root).show();
|
|
81
86
|
};
|
|
82
|
-
let targetNotationInput = ui.input.choice('Convert to', {
|
|
83
|
-
|
|
87
|
+
let targetNotationInput = ui.input.choice('Convert to', {
|
|
88
|
+
value: filteredNotations[0], items: filteredNotations,
|
|
89
|
+
onValueChanged: toggleSeparator
|
|
90
|
+
});
|
|
84
91
|
|
|
85
92
|
// set correct visibility on init
|
|
86
93
|
toggleSeparator();
|
|
@@ -101,7 +108,7 @@ export function convert(col?: DG.Column): void {
|
|
|
101
108
|
const targetNotation = targetNotationInput.value as NOTATION;
|
|
102
109
|
const separator: string | undefined = targetNotation === NOTATION.SEPARATOR ? separatorInput.value! : undefined;
|
|
103
110
|
|
|
104
|
-
await convertDo(srcCol, targetNotation, separator);
|
|
111
|
+
await convertDo(srcCol, seqHelper, targetNotation, separator);
|
|
105
112
|
})
|
|
106
113
|
.show({x: 350, y: 100});
|
|
107
114
|
|
|
@@ -118,8 +125,8 @@ export function convert(col?: DG.Column): void {
|
|
|
118
125
|
* @param {NOTATION} targetNotation Target notation
|
|
119
126
|
* @param {string | null} separator Separator for SEPARATOR notation
|
|
120
127
|
*/
|
|
121
|
-
export async function convertDo(srcCol: DG.Column, targetNotation: NOTATION, separator?: string): Promise<DG.Column> {
|
|
122
|
-
const converterSh =
|
|
128
|
+
export async function convertDo(srcCol: DG.Column, seqHelper: ISeqHelper, targetNotation: NOTATION, separator?: string): Promise<DG.Column> {
|
|
129
|
+
const converterSh = seqHelper.getSeqHandler(srcCol);
|
|
123
130
|
const newColumn = converterSh.convert(targetNotation, separator);
|
|
124
131
|
srcCol.dataFrame.columns.add(newColumn);
|
|
125
132
|
|