@datagrok/bio 2.12.17 → 2.12.18
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 +9 -2
- package/dist/79.js.map +1 -1
- package/dist/package-test.js +5 -5
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +3 -3
- package/dist/package.js.map +1 -1
- package/package.json +3 -3
- package/src/package-test.ts +1 -1
- package/src/package.ts +23 -7
- package/src/tests/monomer-libraries-tests.ts +1 -4
- package/src/tests/renderers-monomer-placer-tests.ts +8 -7
- package/src/tests/renderers-test.ts +1 -1
- package/src/tests/scoring.ts +2 -2
- package/src/tests/substructure-filters-tests.ts +4 -2
- package/src/tests/to-atomic-level-tests.ts +1 -1
- package/src/tests/utils.ts +15 -0
- package/src/utils/cell-renderer.ts +39 -46
- package/src/utils/helm-to-molfile/converter/converter.ts +10 -5
- package/src/utils/helm-to-molfile/converter/monomer-wrapper.ts +9 -9
- package/src/utils/helm-to-molfile/converter/polymer.ts +10 -3
- package/src/utils/monomer-cell-renderer.ts +18 -8
- package/src/utils/monomer-lib/lib-manager.ts +56 -18
- package/src/utils/monomer-lib/library-file-manager/event-manager.ts +15 -9
- package/src/utils/monomer-lib/library-file-manager/file-manager.ts +78 -59
- package/src/utils/monomer-lib/library-file-manager/file-validator.ts +3 -1
- package/src/utils/monomer-lib/library-file-manager/ui.ts +52 -47
- package/src/utils/monomer-lib/monomer-lib.ts +78 -9
- package/src/utils/sequence-to-mol.ts +7 -7
- package/src/widgets/bio-substructure-filter.ts +2 -2
- package/webpack.config.js +1 -0
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/* Do not change these import lines to match external modules in webpack configuration */
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
import * as ui from 'datagrok-api/ui';
|
|
4
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
5
|
|
|
6
|
+
import wu from 'wu';
|
|
5
7
|
import {Observable, Subject} from 'rxjs';
|
|
6
8
|
|
|
7
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
IMonomerLib, Monomer, MonomerLibSummaryType, MonomerType, PolymerType, RGroup
|
|
11
|
+
} from '@datagrok-libraries/bio/src/types';
|
|
12
|
+
import {
|
|
13
|
+
HELM_REQUIRED_FIELD as REQ, HELM_RGROUP_FIELDS as RGP
|
|
14
|
+
} from '@datagrok-libraries/bio/src/utils/const';
|
|
8
15
|
import {MolfileHandler} from '@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler';
|
|
9
16
|
|
|
10
17
|
import '../../../css/cell-renderer.css';
|
|
@@ -27,18 +34,57 @@ export class MonomerLib implements IMonomerLib {
|
|
|
27
34
|
}
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
|
|
37
|
+
/** Creates missing {@link Monomer} */
|
|
38
|
+
addMissingMonomer(polymerType: PolymerType, monomerSymbol: string): Monomer {
|
|
39
|
+
let mSet = this._monomers[polymerType];
|
|
40
|
+
if (!mSet)
|
|
41
|
+
mSet = this._monomers[polymerType] = {};
|
|
42
|
+
const m = mSet[monomerSymbol] = {
|
|
43
|
+
[REQ.SYMBOL]: monomerSymbol,
|
|
44
|
+
[REQ.NAME]: monomerSymbol,
|
|
45
|
+
[REQ.MOLFILE]: '',
|
|
46
|
+
[REQ.AUTHOR]: 'MISSING',
|
|
47
|
+
[REQ.ID]: -1,
|
|
48
|
+
[REQ.RGROUPS]:
|
|
49
|
+
wu.count(1).take(9).map((i) => {
|
|
50
|
+
return {
|
|
51
|
+
/* eslint-disable no-multi-spaces */
|
|
52
|
+
// Samples // PEPTIDE RNA
|
|
53
|
+
[RGP.CAP_GROUP_SMILES]: '', // '[*:1][H]' '[*:1][H]'
|
|
54
|
+
[RGP.ALTERNATE_ID]: '', // 'R1-H' 'R1-H'
|
|
55
|
+
[RGP.CAP_GROUP_NAME]: '', // 'H' 'H'
|
|
56
|
+
[RGP.LABEL]: `R${i.toString()}`, // 'R1' 'R1'
|
|
57
|
+
/* eslint-enable no-multi-spaces */
|
|
58
|
+
} as RGroup;
|
|
59
|
+
}).toArray(),
|
|
60
|
+
[REQ.SMILES]: '',
|
|
61
|
+
[REQ.POLYMER_TYPE]: polymerType,
|
|
62
|
+
[REQ.MONOMER_TYPE]: undefined as unknown as MonomerType, // TODO: Can we get monomerType from atom of POM
|
|
63
|
+
[REQ.CREATE_DATE]: null,
|
|
64
|
+
} as Monomer;
|
|
65
|
+
return m;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
getMonomer(polymerType: PolymerType, argMonomerSymbol: string): Monomer | null {
|
|
69
|
+
// Adjust RNA's 'R' for ribose to 'r' and 'P' for phosphate to 'p' for case-sensitive monomer names.
|
|
70
|
+
// There are uppercase 'R' and 'P' at RNA samples in test data 'helm2.csv' but lowercase in HELMCoreLibrary.json
|
|
71
|
+
let monomerSymbol = argMonomerSymbol;
|
|
72
|
+
if (polymerType == 'RNA' && monomerSymbol == 'R')
|
|
73
|
+
monomerSymbol = 'r';
|
|
74
|
+
if (polymerType == 'RNA' && monomerSymbol == 'P')
|
|
75
|
+
monomerSymbol = 'p';
|
|
76
|
+
|
|
31
77
|
if (polymerType in this._monomers! && monomerSymbol in this._monomers![polymerType])
|
|
32
78
|
return this._monomers![polymerType][monomerSymbol];
|
|
33
79
|
else
|
|
34
80
|
return null;
|
|
35
81
|
}
|
|
36
82
|
|
|
37
|
-
getPolymerTypes():
|
|
38
|
-
return Object.keys(this._monomers);
|
|
83
|
+
getPolymerTypes(): PolymerType[] {
|
|
84
|
+
return Object.keys(this._monomers) as PolymerType[];
|
|
39
85
|
}
|
|
40
86
|
|
|
41
|
-
getMonomerMolsByPolymerType(polymerType:
|
|
87
|
+
getMonomerMolsByPolymerType(polymerType: PolymerType): { [monomerSymbol: string]: string } {
|
|
42
88
|
const res: { [monomerSymbol: string]: string } = {};
|
|
43
89
|
|
|
44
90
|
Object.keys(this._monomers[polymerType] ?? {}).forEach((monomerSymbol) => {
|
|
@@ -48,14 +94,14 @@ export class MonomerLib implements IMonomerLib {
|
|
|
48
94
|
return res;
|
|
49
95
|
}
|
|
50
96
|
|
|
51
|
-
getMonomerSymbolsByType(polymerType:
|
|
97
|
+
getMonomerSymbolsByType(polymerType: PolymerType): string[] {
|
|
52
98
|
return Object.keys(this._monomers[polymerType]);
|
|
53
99
|
}
|
|
54
100
|
|
|
55
101
|
/** Get a list of monomers with specified element attached to specified
|
|
56
102
|
* R-group
|
|
57
103
|
* WARNING: RGroup numbering starts from 1, not 0*/
|
|
58
|
-
getMonomerSymbolsByRGroup(rGroupNumber: number, polymerType:
|
|
104
|
+
getMonomerSymbolsByRGroup(rGroupNumber: number, polymerType: PolymerType, element?: string): string[] {
|
|
59
105
|
const monomerSymbols = this.getMonomerSymbolsByType(polymerType);
|
|
60
106
|
let monomers = monomerSymbols.map((sym) => this.getMonomer(polymerType, sym));
|
|
61
107
|
monomers = monomers.filter((el) => el !== null);
|
|
@@ -116,15 +162,38 @@ export class MonomerLib implements IMonomerLib {
|
|
|
116
162
|
this._onChanged.next();
|
|
117
163
|
}
|
|
118
164
|
|
|
165
|
+
getSummaryObj(): MonomerLibSummaryType {
|
|
166
|
+
const res: MonomerLibSummaryType = {};
|
|
167
|
+
const ptList: PolymerType[] = this.getPolymerTypes();
|
|
168
|
+
for (const pt of ptList)
|
|
169
|
+
res[pt] = this.getMonomerSymbolsByType(pt).length;
|
|
170
|
+
return res;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
getSummaryDf(): DG.DataFrame {
|
|
174
|
+
const ptList = this.getPolymerTypes();
|
|
175
|
+
|
|
176
|
+
const countList: number[] = new Array<number>(ptList.length);
|
|
177
|
+
for (const [pt, i] of wu.enumerate(ptList))
|
|
178
|
+
countList[i] = this.getMonomerSymbolsByType(pt).length;
|
|
179
|
+
|
|
180
|
+
const resDf: DG.DataFrame = DG.DataFrame.fromColumns([
|
|
181
|
+
DG.Column.fromStrings('polymerType', ptList),
|
|
182
|
+
DG.Column.fromList(DG.COLUMN_TYPE.INT, 'count', countList),
|
|
183
|
+
]);
|
|
184
|
+
return resDf;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** @deprecated Keep for backward compatibility */
|
|
119
188
|
getSummary(): string {
|
|
120
|
-
const monTypeList:
|
|
189
|
+
const monTypeList: PolymerType[] = this.getPolymerTypes();
|
|
121
190
|
const resStr: string = monTypeList.length == 0 ? 'empty' : monTypeList.map((monType) => {
|
|
122
191
|
return `${monType} ${this.getMonomerSymbolsByType(monType).length}`;
|
|
123
192
|
}).join('\n');
|
|
124
193
|
return resStr;
|
|
125
194
|
}
|
|
126
195
|
|
|
127
|
-
getTooltip(polymerType:
|
|
196
|
+
getTooltip(polymerType: PolymerType, monomerSymbol: string): HTMLElement {
|
|
128
197
|
// getTooltip(monomer: Monomer): HTMLElement;
|
|
129
198
|
// getTooltip(monomerOrPolymerType: string | Monomer, symbol?: string): HTMLElement {
|
|
130
199
|
// let polymerType: string;
|
|
@@ -4,14 +4,16 @@ import * as ui from 'datagrok-api/ui';
|
|
|
4
4
|
import * as DG from 'datagrok-api/dg';
|
|
5
5
|
|
|
6
6
|
import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
|
|
7
|
-
import {helm2mol} from './helm-to-molfile/utils';
|
|
8
7
|
import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
|
|
9
|
-
import {checkInputColumnUI} from './check-input-column';
|
|
10
|
-
import {getMonomerLibHelper} from '../package';
|
|
11
8
|
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
12
9
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
import {helm2mol} from './helm-to-molfile/utils';
|
|
12
|
+
import {checkInputColumnUI} from './check-input-column';
|
|
13
|
+
|
|
14
|
+
export async function sequenceToMolfile(
|
|
15
|
+
df: DG.DataFrame, macroMolecule: DG.Column, nonlinear: boolean, monomerLib: IMonomerLib
|
|
16
|
+
): Promise<void> {
|
|
15
17
|
if (DG.Func.find({package: 'Chem', name: 'getRdKitModule'}).length === 0) {
|
|
16
18
|
grok.shell.warning('Transformation to atomic level requires package "Chem" installed.');
|
|
17
19
|
return;
|
|
@@ -20,12 +22,10 @@ export async function sequenceToMolfile(df: DG.DataFrame, macroMolecule: DG.Colu
|
|
|
20
22
|
const seqSh = SeqHandler.forColumn(macroMolecule);
|
|
21
23
|
if (!seqSh.isHelm())
|
|
22
24
|
macroMolecule = seqSh.convert(NOTATION.HELM);
|
|
23
|
-
helm2mol(df, macroMolecule);
|
|
24
|
-
return;
|
|
25
|
+
return helm2mol(df, macroMolecule);
|
|
25
26
|
}
|
|
26
27
|
if (!checkInputColumnUI(macroMolecule, 'To Atomic Level'))
|
|
27
28
|
return;
|
|
28
|
-
const monomerLib: IMonomerLib = getMonomerLibHelper().getBioLib();
|
|
29
29
|
const atomicLevelRes = await _toAtomicLevel(df, macroMolecule, monomerLib);
|
|
30
30
|
if (atomicLevelRes.col !== null) {
|
|
31
31
|
df.columns.add(atomicLevelRes.col, true);
|
|
@@ -273,12 +273,12 @@ export class BioSubstructureFilter extends DG.Filter implements IRenderer {
|
|
|
273
273
|
async awaitRendered(timeout: number = 10000): Promise<void> {
|
|
274
274
|
const callLog = `awaitRendered( ${timeout} )`;
|
|
275
275
|
const logPrefix = `${this.filterToLog()}.${callLog}`;
|
|
276
|
-
await delay(
|
|
276
|
+
await delay(10);
|
|
277
277
|
await testEvent(this.onRendered, () => {
|
|
278
278
|
this.logger.debug(`${logPrefix}, ` + '_onRendered event caught');
|
|
279
279
|
}, () => {
|
|
280
280
|
this.invalidate(callLog);
|
|
281
|
-
}, timeout, `${logPrefix}
|
|
281
|
+
}, timeout, `${logPrefix} timeout`);
|
|
282
282
|
|
|
283
283
|
// Rethrow stored syncer error (for test purposes)
|
|
284
284
|
const viewErrors = this.filterSyncer.resetErrors();
|