@datagrok/bio 2.16.5 → 2.16.7
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 +19 -2
- package/dist/package-test.js +2 -2
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +2 -2
- package/dist/package.js.map +1 -1
- package/package.json +2 -2
- package/src/package.ts +2 -2
- package/src/tests/monomer-libraries-tests.ts +1 -0
- package/src/tests/seq-handler-get-helm-tests.ts +2 -2
- package/src/tests/seq-handler-splitted-tests.ts +3 -1
- package/src/utils/helm-to-molfile/converter/converter.ts +12 -33
- package/src/utils/helm-to-molfile/converter/simple-polymer.ts +4 -2
- package/src/utils/monomer-lib/library-file-manager/ui.ts +1 -1
- package/src/utils/monomer-lib/monomer-lib-base.ts +4 -0
- package/src/utils/monomer-lib/monomer-lib.ts +3 -5
- package/src/utils/monomer-lib/monomer-manager/monomer-manager.ts +1 -0
- package/src/utils/seq-helper/seq-handler.ts +7 -9
- package/src/utils/seq-helper/seq-helper.ts +1 -1
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Aleksandr Tanas",
|
|
6
6
|
"email": "atanas@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.16.
|
|
8
|
+
"version": "2.16.7",
|
|
9
9
|
"description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@biowasm/aioli": "^3.1.0",
|
|
40
|
-
"@datagrok-libraries/bio": "^5.45.
|
|
40
|
+
"@datagrok-libraries/bio": "^5.45.5",
|
|
41
41
|
"@datagrok-libraries/chem-meta": "^1.2.7",
|
|
42
42
|
"@datagrok-libraries/math": "^1.2.2",
|
|
43
43
|
"@datagrok-libraries/ml": "^6.7.4",
|
package/src/package.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
|
27
27
|
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
28
28
|
import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
29
29
|
import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
30
|
+
import {MmcrTemps} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
|
|
30
31
|
|
|
31
32
|
import {getMacromoleculeColumns} from './utils/ui-utils';
|
|
32
33
|
import {MacromoleculeDifferenceCellRenderer, MacromoleculeSequenceCellRenderer,} from './utils/cell-renderer';
|
|
@@ -630,7 +631,7 @@ export async function toAtomicLevel(
|
|
|
630
631
|
const pi = DG.TaskBarProgressIndicator.create('Converting to atomic level ...');
|
|
631
632
|
try {
|
|
632
633
|
await initBioPromise;
|
|
633
|
-
const monomerLib = _package.monomerLib;
|
|
634
|
+
const monomerLib = seqCol.temp[MmcrTemps.overriddenLibrary] ?? _package.monomerLib;
|
|
634
635
|
const seqHelper = _package.seqHelper;
|
|
635
636
|
const rdKitModule = _package.rdKitModule;
|
|
636
637
|
await sequenceToMolfile(table, seqCol, nonlinear, highlight, monomerLib, seqHelper, rdKitModule);
|
|
@@ -1138,7 +1139,6 @@ export async function sdfToJsonLib(table: DG.DataFrame) {
|
|
|
1138
1139
|
//input: string seq { semType: Macromolecule }
|
|
1139
1140
|
//input: bool nonlinear
|
|
1140
1141
|
//output: string molfile { semType: Molecule }
|
|
1141
|
-
//meta.role: converter
|
|
1142
1142
|
export async function seq2atomic(seq: string, nonlinear: boolean): Promise<string | undefined> {
|
|
1143
1143
|
if (!(seq.trim())) return '';
|
|
1144
1144
|
try {
|
|
@@ -85,6 +85,7 @@ category('monomerLibraries', () => {
|
|
|
85
85
|
|
|
86
86
|
const overriddenMonomerLib = monomerLib.override({[overMon.polymerType]: {[overMon.symbol]: overMon}}, 'test');
|
|
87
87
|
const resOverMon = overriddenMonomerLib.getMonomer(overMon.polymerType, overMon.symbol);
|
|
88
|
+
if (resOverMon) resOverMon.lib = undefined; // cleanup to prevent infinite recursive comparison
|
|
88
89
|
expectObject(resOverMon as any, overMon);
|
|
89
90
|
});
|
|
90
91
|
});
|
|
@@ -81,8 +81,8 @@ category('SeqHandler: getHelm', () => {
|
|
|
81
81
|
await grok.data.detectSemanticTypes(df);
|
|
82
82
|
|
|
83
83
|
const sh = seqHelper.getSeqHandler(seqCol);
|
|
84
|
-
const
|
|
85
|
-
const resHelm =
|
|
84
|
+
const resMValue = await sh.getValue(0);
|
|
85
|
+
const resHelm = resMValue.helm;
|
|
86
86
|
expect(resHelm, tgtHelm);
|
|
87
87
|
}
|
|
88
88
|
});
|
|
@@ -114,7 +114,8 @@ rut2-rty-her2---wert-rut12-rty-her2---wert
|
|
|
114
114
|
PEPTIDE1{meI.hHis.Aca.N.T.dE.Thr_PO3H2.Aca.D-Tyr_Et.Thr_PO3H2.Aca.D-Tyr_Et}$$$$
|
|
115
115
|
PEPTIDE1{meI.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.Aca.dK.Thr_PO3H2.Aca}$$$$
|
|
116
116
|
PEPTIDE1{Lys_Boc.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.Aca.dK.Thr_PO3H2.Aca}$$$$
|
|
117
|
-
PEPTIDE1{meI.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.T.dK.Thr_PO3H2}
|
|
117
|
+
PEPTIDE1{meI.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.T.dK.Thr_PO3H2}$$$$,
|
|
118
|
+
PEPTIDE1{meI.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.T.dK}|PEPTIDE2{Thr_PO3H2}$$$$`,
|
|
118
119
|
},
|
|
119
120
|
tgt: {
|
|
120
121
|
notation: NOTATION.HELM,
|
|
@@ -123,6 +124,7 @@ PEPTIDE1{meI.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.T.dK.Thr_PO3H2}$$$$`
|
|
|
123
124
|
['meI', 'hHis', 'Aca', 'Cys_SEt', 'T', 'dK', 'Thr_PO3H2', 'Aca', 'dK', 'Thr_PO3H2', 'Aca'],
|
|
124
125
|
['Lys_Boc', 'hHis', 'Aca', 'Cys_SEt', 'T', 'dK', 'Thr_PO3H2', 'Aca', 'dK', 'Thr_PO3H2', 'Aca'],
|
|
125
126
|
['meI', 'hHis', 'Aca', 'Cys_SEt', 'T', 'dK', 'Thr_PO3H2', 'T', 'dK', 'Thr_PO3H2'],
|
|
127
|
+
['meI', 'hHis', 'Aca', 'Cys_SEt', 'T', 'dK', 'Thr_PO3H2', 'T', 'dK', 'Thr_PO3H2'],
|
|
126
128
|
]
|
|
127
129
|
}
|
|
128
130
|
}
|
|
@@ -94,53 +94,33 @@ export class HelmToMolfileConverter {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
public convertToMolfileV3KColumn(
|
|
98
|
-
helmCol: DG.Column<string>
|
|
99
|
-
): DG.Column<string> {
|
|
97
|
+
public convertToMolfileV3KColumn(helmCol: DG.Column<string>): DG.Column<string> {
|
|
100
98
|
const df = helmCol.dataFrame;
|
|
101
|
-
const
|
|
102
|
-
const molfileList = polymerGraphColumn.toList().map(
|
|
103
|
-
(pseudoMolfile: string, idx: number) => {
|
|
104
|
-
const helm = helmCol.get(idx);
|
|
105
|
-
if (!helm) return '';
|
|
106
|
-
|
|
107
|
-
let resMolfileWithMap: MolfileWithMap;
|
|
108
|
-
try {
|
|
109
|
-
resMolfileWithMap = this.getPolymerMolfile(helm, pseudoMolfile);
|
|
110
|
-
} catch (err: any) {
|
|
111
|
-
const [errMsg, errStack] = errInfo(err);
|
|
112
|
-
_package.logger.error(errMsg, undefined, errStack);
|
|
113
|
-
resMolfileWithMap = MolfileWithMap.createEmpty();
|
|
114
|
-
}
|
|
115
|
-
return resMolfileWithMap.molfile;
|
|
116
|
-
});
|
|
99
|
+
const molfileList = this.convertToMolfileV3K(helmCol.toList()).map((mwm) => mwm.molfile);
|
|
117
100
|
const molColName = getUnusedColName(df, `molfileV2K(${helmCol.name})`);
|
|
118
101
|
const molfileColumn = DG.Column.fromList('string', molColName, molfileList);
|
|
119
102
|
return molfileColumn;
|
|
120
103
|
}
|
|
121
104
|
|
|
122
105
|
/** Gets list of monomer molfiles */
|
|
123
|
-
public convertToMolfileV3K(
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
for (let rowIdx = 0; rowIdx < rowCount; ++rowIdx) {
|
|
128
|
-
const helm = helmCol.get(rowIdx);
|
|
106
|
+
public convertToMolfileV3K(helmList: string[]): MolfileWithMap[] {
|
|
107
|
+
const resList: MolfileWithMap[] = new Array<MolfileWithMap>(helmList.length);
|
|
108
|
+
for (let i = 0; i < helmList.length; ++i) {
|
|
109
|
+
const helm = helmList[i];
|
|
129
110
|
if (!helm) {
|
|
130
|
-
resList[
|
|
111
|
+
resList[i] = MolfileWithMap.createEmpty();
|
|
131
112
|
continue;
|
|
132
113
|
}
|
|
133
114
|
|
|
134
|
-
const pseudoMolfile = polymerGraphColumn.get(rowIdx)!;
|
|
135
115
|
let resMolfile: MolfileWithMap;
|
|
136
116
|
try {
|
|
137
|
-
resMolfile = this.getPolymerMolfile(helm
|
|
117
|
+
resMolfile = this.getPolymerMolfile(helm);
|
|
138
118
|
} catch (err: any) {
|
|
139
119
|
const [errMsg, errStack] = errInfo(err);
|
|
140
120
|
_package.logger.error(errMsg, undefined, errStack);
|
|
141
121
|
resMolfile = MolfileWithMap.createEmpty();
|
|
142
122
|
}
|
|
143
|
-
resList[
|
|
123
|
+
resList[i] = resMolfile;
|
|
144
124
|
}
|
|
145
125
|
return resList;
|
|
146
126
|
}
|
|
@@ -152,16 +132,15 @@ export class HelmToMolfileConverter {
|
|
|
152
132
|
return molfileCol;
|
|
153
133
|
}
|
|
154
134
|
|
|
155
|
-
private getPolymerMolfile(
|
|
156
|
-
helm: string, polymerGraph: string
|
|
157
|
-
): MolfileWithMap {
|
|
135
|
+
private getPolymerMolfile(helm: string): MolfileWithMap {
|
|
158
136
|
const woGapsRes = this.helmHelper.removeGaps(helm);
|
|
159
137
|
const woGapsHelm = woGapsRes.resHelm;
|
|
160
138
|
const woGapsReverseMap = new Map<number, number>();
|
|
161
139
|
for (const [orgPosIdx, woGapsPosIdx] of (woGapsRes.monomerMap?.entries() ?? [])) {
|
|
162
140
|
woGapsReverseMap.set(woGapsPosIdx, orgPosIdx);
|
|
163
141
|
}
|
|
164
|
-
const
|
|
142
|
+
const pseudoMolfile = this.helmHelper.getMolfiles([woGapsHelm])[0];
|
|
143
|
+
const globalPositionHandler = new GlobalMonomerPositionHandler(pseudoMolfile);
|
|
165
144
|
const woGapsPolymer = new Polymer(woGapsHelm, this.rdKitModule, this.monomerLib);
|
|
166
145
|
globalPositionHandler.monomerSymbols.forEach((monomerSymbol: string, monomerIdx: number) => {
|
|
167
146
|
const shift = globalPositionHandler.getMonomerShifts(monomerIdx);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import {HELM_MONOMER_TYPE, HELM_POLYMER_TYPE} from '@datagrok-libraries/bio/src/utils/const';
|
|
2
|
+
import {cleanupHelmSymbol} from '@datagrok-libraries/bio/src/helm/utils';
|
|
3
|
+
|
|
2
4
|
import {Bond} from './types';
|
|
3
5
|
|
|
4
6
|
/** Wrapper over simple polymer substring of HELM, like RNA1{d(A)p} */
|
|
@@ -41,7 +43,7 @@ export class SimplePolymer {
|
|
|
41
43
|
return id;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
private getMonomerSymbolsAndTypes(): {monomers: string[], monomerTypes: HELM_MONOMER_TYPE[]} {
|
|
46
|
+
private getMonomerSymbolsAndTypes(): { monomers: string[], monomerTypes: HELM_MONOMER_TYPE[] } {
|
|
45
47
|
const helmWrapperRegex = new RegExp(`${this.polymerType}${this.idx}{|}`, 'g');
|
|
46
48
|
const monomerGroups = this.simplePolymer.replace(helmWrapperRegex, '').split('.');
|
|
47
49
|
const monomerList: string[] = [];
|
|
@@ -51,7 +53,7 @@ export class SimplePolymer {
|
|
|
51
53
|
// monomerList.push(...splitted);
|
|
52
54
|
// WARNING: only the groups of the form r(A)p, as in RNA, are supported
|
|
53
55
|
|
|
54
|
-
monomerList.push(monomerGroup);
|
|
56
|
+
monomerList.push(cleanupHelmSymbol(monomerGroup));
|
|
55
57
|
// const monomerTypes = splitted.map(
|
|
56
58
|
// (_, idx) => (idx % 2 === 0) ? HELM_MONOMER_TYPE.BACKBONE : HELM_MONOMER_TYPE.BRANCH
|
|
57
59
|
// );
|
|
@@ -132,7 +132,7 @@ class LibraryControlsManager {
|
|
|
132
132
|
|
|
133
133
|
private _createControlsForm(): HTMLElement {
|
|
134
134
|
const libraryControls = this.createLibraryControls();
|
|
135
|
-
const inputsForm = ui.form(libraryControls);
|
|
135
|
+
const inputsForm = ui.form(libraryControls, undefined, false);
|
|
136
136
|
$(inputsForm).addClass('monomer-lib-controls-form');
|
|
137
137
|
|
|
138
138
|
return inputsForm;
|
|
@@ -46,6 +46,10 @@ export class MonomerLibBase implements IMonomerLibBase {
|
|
|
46
46
|
) {
|
|
47
47
|
this._isEmpty = !this._monomers || Object.keys(this._monomers).length === 0 ||
|
|
48
48
|
Object.entries(this._monomers).every(([_, ptMonomers]) => Object.keys(ptMonomers).length === 0);
|
|
49
|
+
for (const [_monomerType, monomersOfType] of Object.entries(this._monomers)) {
|
|
50
|
+
for (const [_monomerSymbol, monomer] of Object.entries(monomersOfType))
|
|
51
|
+
monomer.lib = this;
|
|
52
|
+
}
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
getMonomerSymbolsByType(polymerType: PolymerType): string[] {
|
|
@@ -43,10 +43,6 @@ export class MonomerLib extends MonomerLibBase implements IMonomerLib {
|
|
|
43
43
|
public readonly error: string | undefined = undefined,
|
|
44
44
|
) {
|
|
45
45
|
super(monomers, source);
|
|
46
|
-
for (const [_monomerType, monomersOfType] of Object.entries(this._monomers)) {
|
|
47
|
-
for (const [_monomerSymbol, monomer] of Object.entries(monomersOfType))
|
|
48
|
-
monomer.lib = this;
|
|
49
|
-
}
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
toJSON(): Monomer[] {
|
|
@@ -237,8 +233,10 @@ export class MonomerLib extends MonomerLibBase implements IMonomerLib {
|
|
|
237
233
|
return resStr;
|
|
238
234
|
}
|
|
239
235
|
|
|
236
|
+
static overrideCounter: number = 0;
|
|
237
|
+
|
|
240
238
|
override(data: MonomerLibData, source: string): IMonomerLibBase {
|
|
241
|
-
return new OverriddenMonomerLib(data,
|
|
239
|
+
return new OverriddenMonomerLib(data, `override: ${++MonomerLib.overrideCounter}, ${source}`, this);
|
|
242
240
|
}
|
|
243
241
|
}
|
|
244
242
|
|
|
@@ -868,6 +868,7 @@ class MonomerForm implements INewMonomerForm {
|
|
|
868
868
|
await grok.dapi.files.writeAsText(LIB_PATH + libName, JSON.stringify(libJSON));
|
|
869
869
|
await (await MonomerLibManager.getInstance()).loadLibraries(true);
|
|
870
870
|
await this.refreshTable(monomer.symbol);
|
|
871
|
+
this._molChanged = false; // reset the flag
|
|
871
872
|
grok.shell.info(`Monomer ${monomer.symbol} was successfully saved in library ${libName}`);
|
|
872
873
|
} catch (e) {
|
|
873
874
|
grok.shell.error('Error saving monomer');
|
|
@@ -14,7 +14,7 @@ import {GAP_SYMBOL, GapOriginals} from '@datagrok-libraries/bio/src/utils/macrom
|
|
|
14
14
|
import {CellRendererBackBase, GridCellRendererTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
15
15
|
import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
|
|
16
16
|
import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
|
|
17
|
-
import {ISeqHandler, ConvertFunc, JoinerFunc, SeqTemps} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
17
|
+
import {ISeqHandler, ConvertFunc, JoinerFunc, SeqTemps, MacromoleculeValueBase} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
18
18
|
|
|
19
19
|
import {SeqHelper} from './seq-helper';
|
|
20
20
|
|
|
@@ -241,18 +241,16 @@ export class SeqHandler implements ISeqHandler {
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
/** Any Macromolecule can be represented on Helm format. The reverse is not always possible. */
|
|
244
|
-
public async
|
|
244
|
+
public async getValue(rowIdx: number, options?: any): Promise<MacromoleculeValueBase> {
|
|
245
245
|
const seq: string = this.column.get(rowIdx);
|
|
246
|
-
let
|
|
246
|
+
let resHelm: string;
|
|
247
247
|
if (this.notationProvider)
|
|
248
|
-
|
|
248
|
+
resHelm = await this.notationProvider.getHelm(seq, options);
|
|
249
249
|
else {
|
|
250
|
-
|
|
251
|
-
resHelmSV = DG.SemanticValue.fromValueType(resHelm, DG.SEMTYPE.MACROMOLECULE, NOTATION.HELM);
|
|
252
|
-
// TODO: set tags from column
|
|
250
|
+
resHelm = this.convertToHelm(seq);
|
|
253
251
|
}
|
|
254
|
-
|
|
255
|
-
return
|
|
252
|
+
const resMValue = new MacromoleculeValueBase(resHelm, this, rowIdx);
|
|
253
|
+
return resMValue;
|
|
256
254
|
}
|
|
257
255
|
|
|
258
256
|
private _stats: SeqColStats | null = null;
|
|
@@ -56,7 +56,7 @@ export class SeqHelper implements ISeqHelper {
|
|
|
56
56
|
|
|
57
57
|
//#region From HelmToMolfileConverter.convertToRdKitBeautifiedMolfileColumn
|
|
58
58
|
|
|
59
|
-
const molfilesV3K = converter.convertToMolfileV3K(helmCol
|
|
59
|
+
const molfilesV3K = converter.convertToMolfileV3K(helmCol.toList());
|
|
60
60
|
|
|
61
61
|
const beautifiedMolList: (RDMol | null)[] = molfilesV3K.map((item) => {
|
|
62
62
|
const molfile = item.molfile;
|