@datagrok/bio 2.12.12 → 2.12.13
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/.eslintrc.json +2 -2
- package/CHANGELOG.md +4 -0
- package/dist/package-test.js +5 -5
- package/dist/package-test.js.LICENSE.txt +0 -8
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +5 -5
- package/dist/package.js.LICENSE.txt +0 -8
- package/dist/package.js.map +1 -1
- package/package.json +6 -5
- package/src/tests/renderers-test.ts +47 -1
- package/src/utils/cell-renderer.ts +28 -3
- package/src/utils/helm-to-molfile/converter/const.ts +1 -26
- package/src/utils/helm-to-molfile/converter/mol-atoms.ts +1 -1
- package/src/utils/helm-to-molfile/converter/polymer.ts +3 -4
- package/src/utils/poly-tool/const.ts +0 -4
- package/src/utils/poly-tool/transformation.ts +119 -56
- package/webpack.config.js +4 -3
- package/src/utils/atomic-works.ts +0 -367
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Aleksandr Tanas",
|
|
6
6
|
"email": "atanas@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.12.
|
|
8
|
+
"version": "2.12.13",
|
|
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",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@biowasm/aioli": "^3.1.0",
|
|
37
|
-
"@datagrok-libraries/bio": "^5.40.
|
|
38
|
-
"@datagrok-libraries/chem-meta": "^1.2.
|
|
37
|
+
"@datagrok-libraries/bio": "^5.40.8",
|
|
38
|
+
"@datagrok-libraries/chem-meta": "^1.2.5",
|
|
39
|
+
"@datagrok-libraries/math": "^1.1.1",
|
|
39
40
|
"@datagrok-libraries/ml": "^6.6.0",
|
|
40
41
|
"@datagrok-libraries/tutorials": "^1.3.12",
|
|
41
42
|
"@datagrok-libraries/utils": "^4.2.0",
|
|
42
|
-
"@datagrok-libraries/math": "^1.1.1",
|
|
43
43
|
"@webgpu/types": "^0.1.40",
|
|
44
44
|
"ajv": "^8.12.0",
|
|
45
45
|
"ajv-errors": "^3.0.0",
|
|
@@ -103,7 +103,8 @@
|
|
|
103
103
|
"All users"
|
|
104
104
|
],
|
|
105
105
|
"sources": [
|
|
106
|
-
"css/helm.css"
|
|
106
|
+
"css/helm.css",
|
|
107
|
+
"common/openchemlib-full.js"
|
|
107
108
|
],
|
|
108
109
|
"category": "Bioinformatics",
|
|
109
110
|
"meta": {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import * as grok from 'datagrok-api/grok';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
4
|
|
|
4
|
-
import
|
|
5
|
+
import $ from 'cash-dom';
|
|
6
|
+
import {fromEvent} from 'rxjs';
|
|
7
|
+
|
|
8
|
+
import {category, expect, test, delay, testEvent} from '@datagrok-libraries/utils/src/test';
|
|
5
9
|
import {ALIGNMENT, ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
6
10
|
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
7
11
|
|
|
@@ -12,6 +16,8 @@ import {multipleSequenceAlignmentUI} from '../utils/multiple-sequence-alignment-
|
|
|
12
16
|
import {awaitGrid} from './utils';
|
|
13
17
|
import * as C from '../utils/constants';
|
|
14
18
|
|
|
19
|
+
import {_package} from '../package-test';
|
|
20
|
+
|
|
15
21
|
category('renderers', () => {
|
|
16
22
|
test('long sequence performance ', async () => {
|
|
17
23
|
await performanceTest(generateLongSequence, 'Long sequences');
|
|
@@ -48,6 +54,10 @@ category('renderers', () => {
|
|
|
48
54
|
await _selectRendererBySemType();
|
|
49
55
|
});
|
|
50
56
|
|
|
57
|
+
test('scatterPlotTooltip', async () => {
|
|
58
|
+
await _testScatterPlotTooltip();
|
|
59
|
+
});
|
|
60
|
+
|
|
51
61
|
async function _rendererMacromoleculeFasta() {
|
|
52
62
|
const csv: string = await grok.dapi.files.readAsText('System:AppData/Bio/samples/FASTA.csv');
|
|
53
63
|
const df: DG.DataFrame = DG.DataFrame.fromCsv(csv);
|
|
@@ -197,4 +207,40 @@ category('renderers', () => {
|
|
|
197
207
|
`view renderer has set to '${renderer}' instead of correct 'MacromoleculeDifference'.`);
|
|
198
208
|
}
|
|
199
209
|
}
|
|
210
|
+
|
|
211
|
+
const seqCoordsCsv = `seq,x,y
|
|
212
|
+
ACGGTGTCGT,0,0
|
|
213
|
+
CGGTATCCCT,1,0
|
|
214
|
+
CTCGGCATGC,2,0
|
|
215
|
+
`;
|
|
216
|
+
|
|
217
|
+
async function _testScatterPlotTooltip(): Promise<void> {
|
|
218
|
+
const df = DG.DataFrame.fromCsv(seqCoordsCsv);
|
|
219
|
+
df.currentRowIdx = 0;
|
|
220
|
+
const view = grok.shell.addTableView(df);
|
|
221
|
+
const sp: DG.ScatterPlotViewer = df.plot.scatter({x: 'x', y: 'y'});
|
|
222
|
+
view.dockManager.dock(sp, DG.DOCK_TYPE.RIGHT, null);
|
|
223
|
+
await Promise.all([
|
|
224
|
+
testEvent(sp.onAfterDrawScene, () => {}, () => { sp.invalidateCanvas(); }, 1000),
|
|
225
|
+
awaitGrid(view.grid, 500)
|
|
226
|
+
]);
|
|
227
|
+
|
|
228
|
+
const spBcr = sp.root.getBoundingClientRect();
|
|
229
|
+
const wp = sp.worldToScreen(1, 0);
|
|
230
|
+
const ev = new MouseEvent('mousemove', {
|
|
231
|
+
cancelable: true, bubbles: true, view: window, button: 0,
|
|
232
|
+
clientX: spBcr.left + wp.x, clientY: spBcr.top + wp.y
|
|
233
|
+
});
|
|
234
|
+
const spCanvas = $(sp.root).find('canvas').get()[0] as HTMLCanvasElement;
|
|
235
|
+
await testEvent(fromEvent(spCanvas, 'mousemove'), () => {
|
|
236
|
+
_package.logger.debug(`Test: event, currentRowIdx=${df.currentRowIdx}`);
|
|
237
|
+
expect($(ui.tooltip.root).find('div table.d4-row-tooltip-table tr td canvas').length, 1);
|
|
238
|
+
expect(sp.hitTest(wp.x, wp.y), 1);
|
|
239
|
+
}, () => {
|
|
240
|
+
spCanvas.dispatchEvent(ev);
|
|
241
|
+
}, 500);
|
|
242
|
+
// TODO: Any error occurred become 'Cannot read properties of null (reading 'get$columns')' because of scatter plot
|
|
243
|
+
//await testEvent(sp.onAfterDrawScene, () => {}, () => { sp.invalidateCanvas(); }, 200);
|
|
244
|
+
await awaitGrid(view.grid, 500);
|
|
245
|
+
}
|
|
200
246
|
});
|
|
@@ -59,6 +59,31 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
59
59
|
return [text, simplified];
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
type RendererGridCellTemp = {
|
|
63
|
+
[mmcrTemps.monomerPlacer]: MonomerPlacer
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function getRendererFridCellTempTemp(gridCell: DG.GridCell): RendererGridCellTemp {
|
|
67
|
+
/** Primarily store/get MonomerPlacer at GridColumn, fallback at (Table) Column for scatter plot tooltip */
|
|
68
|
+
let temp: RendererGridCellTemp | null = null;
|
|
69
|
+
|
|
70
|
+
let gridCol: DG.GridColumn | null = null;
|
|
71
|
+
try { gridCol = gridCell.gridColumn; } catch { gridCol = null; }
|
|
72
|
+
temp = gridCol && gridCol.dart ? gridCol.temp as RendererGridCellTemp : null;
|
|
73
|
+
|
|
74
|
+
if (!temp) {
|
|
75
|
+
let tableCol: DG.Column | null = null;
|
|
76
|
+
try { tableCol = gridCell.cell.column; } catch { tableCol = null; }
|
|
77
|
+
if (!tableCol) {
|
|
78
|
+
const k = 42;
|
|
79
|
+
}
|
|
80
|
+
temp = tableCol ? tableCol.temp as RendererGridCellTemp : null;
|
|
81
|
+
}
|
|
82
|
+
if (temp === null)
|
|
83
|
+
throw new Error(`Monomer placer store (GridColumn or Column) not found.`);
|
|
84
|
+
return temp;
|
|
85
|
+
}
|
|
86
|
+
|
|
62
87
|
export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
63
88
|
private padding: number = 5;
|
|
64
89
|
|
|
@@ -82,7 +107,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
82
107
|
|
|
83
108
|
const tableCol: DG.Column = gridCell.cell.column;
|
|
84
109
|
//const tableColTemp: TempType = tableCol.temp;
|
|
85
|
-
const seqColTemp: MonomerPlacer = gridCell
|
|
110
|
+
const seqColTemp: MonomerPlacer = getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer];
|
|
86
111
|
if (!seqColTemp) return; // Can do nothing without precalculated data
|
|
87
112
|
|
|
88
113
|
const gridCellBounds: DG.Rect = gridCell.bounds;
|
|
@@ -165,7 +190,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
165
190
|
(!isNaN(tagMaxMonomerLength) ? tagMaxMonomerLength : _package.properties?.MaxMonomerLength) ?? 4;
|
|
166
191
|
}
|
|
167
192
|
|
|
168
|
-
let seqColTemp: MonomerPlacer = gridCell
|
|
193
|
+
let seqColTemp: MonomerPlacer = getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer];
|
|
169
194
|
if (!seqColTemp) {
|
|
170
195
|
seqColTemp = new MonomerPlacer(grid, tableCol,
|
|
171
196
|
() => {
|
|
@@ -192,7 +217,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
192
217
|
const _maxIndex = maxLengthWords.length;
|
|
193
218
|
|
|
194
219
|
// Store updated seqColTemp to the col temp
|
|
195
|
-
if (seqColTemp.updated) gridCell
|
|
220
|
+
if (seqColTemp.updated) getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer] = seqColTemp;
|
|
196
221
|
|
|
197
222
|
g.save();
|
|
198
223
|
try {
|
|
@@ -1,29 +1,4 @@
|
|
|
1
1
|
export const HELM_ITEM_SEPARATOR = '|';
|
|
2
2
|
export const HELM_SECTION_SEPARATOR = '$';
|
|
3
|
-
export const HYDROGEN_SYMBOL = 'H';
|
|
4
|
-
export const R_GROUP_ELEMENT_SYMBOL = 'R#';
|
|
5
|
-
|
|
6
|
-
export const enum V2K_CONST {
|
|
7
|
-
MAX_ATOM_COUNT = 999,
|
|
8
|
-
RGP_LINE_START = 'M RGP',
|
|
9
|
-
ATOM_ALIAS_LINE_START = 'A ',
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const enum V3K_CONST {
|
|
13
|
-
HEADER = `
|
|
14
|
-
RDKit 2D
|
|
15
|
-
|
|
16
|
-
0 0 0 0 0 0 0 0 0 0999 V3000`,
|
|
17
|
-
BEGIN_CTAB = 'M V30 BEGIN CTAB',
|
|
18
|
-
COUNTS_LINE_START = 'M V30 COUNTS ',
|
|
19
|
-
COUNTS_LINE_END = ' 0 0 0',
|
|
20
|
-
BEGIN_ATOM_BLOCK = 'M V30 BEGIN ATOM',
|
|
21
|
-
END_ATOM_BLOCK = 'M V30 END ATOM',
|
|
22
|
-
BEGIN_BOND_BLOCK = 'M V30 BEGIN BOND',
|
|
23
|
-
END_BOND_BLOCK = 'M V30 END BOND',
|
|
24
|
-
BEGIN_COLLECTION_BLOCK = 'M V30 BEGIN COLLECTION',
|
|
25
|
-
END_COLLECTION_BLOCK = 'M V30 END COLLECTION',
|
|
26
|
-
END_CTAB = 'M V30 END CTAB',
|
|
27
|
-
END = 'M END\n',
|
|
28
|
-
}
|
|
29
3
|
|
|
4
|
+
export const HYDROGEN_SYMBOL = 'H';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
2
|
-
import {
|
|
2
|
+
import {V3K_CONST} from '@datagrok-libraries/chem-meta/src/formats/molfile-const';
|
|
3
3
|
import {Helm} from './helm';
|
|
4
4
|
import {MonomerWrapper} from './monomer-wrapper';
|
|
5
5
|
|
|
@@ -44,7 +44,6 @@ export class Polymer {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
compileToMolfile(): string {
|
|
47
|
-
const molfileHeader = '\nDatagrok\n';
|
|
48
47
|
const atomLines: string[] = [];
|
|
49
48
|
const bondLines: string[] = [];
|
|
50
49
|
|
|
@@ -73,8 +72,8 @@ export class Polymer {
|
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
private getV3KHeader(atomCount: number, bondCount: number): string {
|
|
76
|
-
const countsLine = `${V3K_CONST.COUNTS_LINE_START}${atomCount} ${bondCount}${V3K_CONST.
|
|
77
|
-
return `${V3K_CONST.
|
|
75
|
+
const countsLine = `${V3K_CONST.COUNTS_LINE_START}${atomCount} ${bondCount}${V3K_CONST.COUNTS_LINE_DUMMY_END}`;
|
|
76
|
+
return `${V3K_CONST.DUMMY_HEADER}\n${V3K_CONST.BEGIN_CTAB}\n${countsLine}`;
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
private getV3KAtomBlock(atomLines: string[]): string {
|
|
@@ -6,12 +6,15 @@ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
|
6
6
|
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
7
7
|
import {ALIGNMENT, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
8
8
|
|
|
9
|
-
import {HELM_WRAPPER} from './const';
|
|
10
9
|
import {getMolColumnFromHelm} from '../helm-to-molfile/utils';
|
|
11
10
|
|
|
12
11
|
export const RULES_PATH = 'System:AppData/Bio/polytool-rules/';
|
|
13
12
|
export const RULES_STORAGE_NAME = 'Polytool';
|
|
14
13
|
|
|
14
|
+
const enum HELM_WRAPPER {
|
|
15
|
+
LEFT = 'PEPTIDE1{',
|
|
16
|
+
RIGHT = '}$$$$',
|
|
17
|
+
}
|
|
15
18
|
|
|
16
19
|
type ConnectionData = {
|
|
17
20
|
allPos1: number[],
|
|
@@ -43,19 +46,8 @@ class TransformationCommon {
|
|
|
43
46
|
this.helmColumn = helmColumn;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
protected
|
|
47
|
-
|
|
48
|
-
if (helm.includes('(1)'))
|
|
49
|
-
isLinkable = true;
|
|
50
|
-
if (helm.includes('(2)'))
|
|
51
|
-
isLinkable = true;
|
|
52
|
-
|
|
53
|
-
return isLinkable;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
protected getLinkedPositions(helm: string, rules: Rule[]): [number, number][] {
|
|
57
|
-
const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
|
|
58
|
-
const monomers = seq.split('.').map((m) => { return m.replace('[', '').replace(']', ''); });
|
|
49
|
+
protected getLinkedPositions(monomers: string[], rules: Rule[]): [number, number][] {
|
|
50
|
+
const monomersNames = monomers.map((m) => { return m.replace('[', '').replace(']', ''); });
|
|
59
51
|
const result: [number, number][] = new Array<[number, number]>(rules.length);
|
|
60
52
|
|
|
61
53
|
for (let i = 0; i < rules.length; i++) {
|
|
@@ -65,14 +57,14 @@ class TransformationCommon {
|
|
|
65
57
|
let firstEntryIndex = -1;
|
|
66
58
|
let secondEntryIndex = -1;
|
|
67
59
|
const add = `(${rules[i].code})`;
|
|
68
|
-
for (let j = 0; j <
|
|
69
|
-
if (
|
|
60
|
+
for (let j = 0; j < monomersNames.length; j++) {
|
|
61
|
+
if (monomersNames[j].includes(add)) {
|
|
70
62
|
if (firstFound) {
|
|
71
|
-
if (firstIsFirst &&
|
|
63
|
+
if (firstIsFirst && monomersNames[j] == rules[i].secondMonomer + add) {
|
|
72
64
|
secondFound = true;
|
|
73
65
|
secondEntryIndex = j;
|
|
74
66
|
break;
|
|
75
|
-
} else if (!firstIsFirst &&
|
|
67
|
+
} else if (!firstIsFirst && monomersNames[j] == rules[i].firstMonomer + add) {
|
|
76
68
|
secondFound = true;
|
|
77
69
|
secondEntryIndex = j;
|
|
78
70
|
break;
|
|
@@ -83,11 +75,11 @@ class TransformationCommon {
|
|
|
83
75
|
// secondFound = true;
|
|
84
76
|
// break;
|
|
85
77
|
} else {
|
|
86
|
-
if (
|
|
78
|
+
if (monomersNames[j] == rules[i].firstMonomer + add) {
|
|
87
79
|
firstFound = true;
|
|
88
80
|
firstIsFirst = true;
|
|
89
81
|
firstEntryIndex = j;
|
|
90
|
-
} else if (
|
|
82
|
+
} else if (monomersNames[j] == rules[i].secondMonomer + add) {
|
|
91
83
|
firstFound = true;
|
|
92
84
|
firstIsFirst = false;
|
|
93
85
|
firstEntryIndex = j;
|
|
@@ -141,22 +133,42 @@ class TransformationCommon {
|
|
|
141
133
|
return rules;
|
|
142
134
|
}
|
|
143
135
|
|
|
144
|
-
protected
|
|
145
|
-
const
|
|
146
|
-
const
|
|
136
|
+
protected getDimeric(helm: string): [string[], [number, number][]] {
|
|
137
|
+
const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
|
|
138
|
+
const monomers = seq.split('.');
|
|
139
|
+
const duplicates: [number, number][] = [];
|
|
140
|
+
|
|
141
|
+
for (let i = 0; i < monomers.length; i++) {
|
|
142
|
+
if (monomers[i].includes('(#2)')) {
|
|
143
|
+
monomers[i] = monomers[i].replace('(#2)', '');
|
|
144
|
+
const duplicateStart = i + 1;
|
|
145
|
+
let duplicateFinish = 0;
|
|
146
|
+
for (let j = duplicateStart + 1; j < monomers.length; j++) {
|
|
147
|
+
if (monomers[j].includes('}')) {
|
|
148
|
+
duplicateFinish = j; break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
monomers[duplicateStart] = monomers[duplicateStart].replace('{', '');
|
|
152
|
+
monomers[duplicateFinish] = monomers[duplicateFinish].replace('}', '');
|
|
153
|
+
duplicates.push([duplicateStart, duplicateFinish]);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
147
156
|
|
|
157
|
+
return [monomers, duplicates];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
protected getAllCycles(rules: Rule[], monomers: string [], positions: [number, number][]) :
|
|
161
|
+
[string [], number [], number [], number [], number []] {
|
|
148
162
|
const allPos1: number [] = [];
|
|
149
163
|
const allPos2: number [] = [];
|
|
150
164
|
const allAttaches1: number [] = [];
|
|
151
165
|
const allAttaches2: number [] = [];
|
|
166
|
+
const ruleCount = rules.length;
|
|
152
167
|
|
|
153
168
|
for (let i = 0; i < ruleCount; i++) {
|
|
154
169
|
if (positions[i][0] == -1)
|
|
155
170
|
continue;
|
|
156
171
|
|
|
157
|
-
//helm = helm.replaceAll(`(${i + 1})`, '');
|
|
158
|
-
const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
|
|
159
|
-
const monomers = seq.split('.');
|
|
160
172
|
const firstMonomer = monomers[positions[i][0]].replace('[', '').replace(']', '');
|
|
161
173
|
const secondMonomer = monomers[positions[i][1]].replace('[', '').replace(']', '');
|
|
162
174
|
|
|
@@ -167,31 +179,97 @@ class TransformationCommon {
|
|
|
167
179
|
allPos2.push(positions[i][1] + 1);
|
|
168
180
|
allAttaches1.push(rules[i].firstR);
|
|
169
181
|
allAttaches2.push(rules[i].secondR);
|
|
182
|
+
}
|
|
170
183
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
184
|
+
return [monomers, allPos1, allPos2, allAttaches1, allAttaches2];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
protected getHelmCycle(source: ConnectionData, polFirst: number, poSecond: number): string {
|
|
188
|
+
let cycled = '';
|
|
189
|
+
|
|
190
|
+
for (let i = 0; i < source.allPos1.length; i++) {
|
|
191
|
+
if (i == 0)
|
|
192
|
+
cycled += `PEPTIDE${polFirst},PEPTIDE${poSecond},`;
|
|
193
|
+
else
|
|
194
|
+
cycled += `|PEPTIDE${polFirst},PEPTIDE${poSecond},`;
|
|
195
|
+
cycled += `${source.allPos1[i]}:R${source.allAttaches1[i]}-${source.allPos2[i]}:R${source.allAttaches2[i]}`;
|
|
179
196
|
}
|
|
197
|
+
return cycled;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
//"PEPTIDE1{[(#2)Succ].[{R].F.[Dab(2)].T.G.H.F.G.A.A.Y.P.[E(2)].[NH2}]}$$$$"
|
|
201
|
+
protected getTransformedHelm(helm: string, rules: Rule[]): string {
|
|
202
|
+
const [monomers, duplicates] = this.getDimeric(helm);
|
|
203
|
+
const positions = this.getLinkedPositions(monomers, rules);
|
|
204
|
+
const [monomersCycled, allPos1, allPos2, allAttaches1, allAttaches2] =
|
|
205
|
+
this.getAllCycles(rules, monomers, positions);
|
|
206
|
+
|
|
207
|
+
helm = 'PEPTIDE1{';
|
|
208
|
+
for (let i = 0; i < monomersCycled.length; i++)
|
|
209
|
+
helm += i != monomersCycled.length - 1 ? monomersCycled[i] + '.' : monomersCycled[i];
|
|
210
|
+
|
|
211
|
+
helm += '}';
|
|
212
|
+
|
|
213
|
+
const dimerCodes = new Array<string>(duplicates.length);
|
|
214
|
+
const cycleCodes = new Array<string>(duplicates.length);
|
|
215
|
+
for (let i = 0; i < duplicates.length; i++) {
|
|
216
|
+
let helmAdd = `|PEPTIDE${i + 2}{`;
|
|
217
|
+
const lengthAdd = duplicates[i][1] - duplicates[i][0];
|
|
218
|
+
//const monomersAdd = new Array<string>(lengthAdd);
|
|
219
|
+
const allPosAdd1: number [] = [];
|
|
220
|
+
const allPosAdd2: number [] = [];
|
|
221
|
+
const allAttachesAdd1: number [] = [];
|
|
222
|
+
const allAttachesAdd2: number [] = [];
|
|
223
|
+
|
|
224
|
+
for (let j = 0; j <= lengthAdd; j ++) {
|
|
225
|
+
const index = j + duplicates[i][0];
|
|
226
|
+
helmAdd += j != lengthAdd ? monomersCycled[index] + '.' : monomersCycled[index];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
helmAdd += '}';
|
|
230
|
+
|
|
231
|
+
for (let j = 0; j < allPos1.length; j++) {
|
|
232
|
+
if (allPos1[j] - 1 >= duplicates[i][0] && allPos1[j] - 1 <= duplicates[i][1]) {
|
|
233
|
+
allPosAdd1.push(allPos1[j] - duplicates[i][0]);
|
|
234
|
+
allPosAdd2.push(allPos2[j] - duplicates[i][0]);
|
|
235
|
+
allAttachesAdd1.push(allAttaches1[j]);
|
|
236
|
+
allAttachesAdd2.push(allAttaches1[j]);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
180
239
|
|
|
240
|
+
const addCyclysation = this.getHelmCycle({
|
|
241
|
+
allPos1: allPosAdd1,
|
|
242
|
+
allPos2: allPosAdd2,
|
|
243
|
+
allAttaches1: allAttachesAdd1,
|
|
244
|
+
allAttaches2: allAttachesAdd2}, i + 2, i + 2);
|
|
245
|
+
|
|
246
|
+
dimerCodes[i] = helmAdd;
|
|
247
|
+
cycleCodes[i] = this.getHelmCycle({
|
|
248
|
+
allPos1: [duplicates[i][0]],
|
|
249
|
+
allPos2: [1],
|
|
250
|
+
allAttaches1: [1],
|
|
251
|
+
allAttaches2: [1]}, 1, i + 2);
|
|
252
|
+
cycleCodes.push(addCyclysation);
|
|
253
|
+
}
|
|
181
254
|
|
|
182
|
-
|
|
255
|
+
for (let i = 0; i < dimerCodes.length; i++)
|
|
256
|
+
helm += dimerCodes[i];
|
|
183
257
|
|
|
184
|
-
|
|
258
|
+
helm += '$';
|
|
259
|
+
const mainCyclysation = this.getHelmCycle({allPos1, allPos2, allAttaches1, allAttaches2}, 1, 1);
|
|
260
|
+
helm += mainCyclysation;
|
|
261
|
+
for (let i = 0; i < cycleCodes.length; i++) {
|
|
262
|
+
helm += '|';
|
|
263
|
+
helm += cycleCodes[i];
|
|
264
|
+
}
|
|
265
|
+
helm += '$$$';
|
|
266
|
+
return helm;
|
|
185
267
|
}
|
|
186
268
|
|
|
187
269
|
transform(rulesTables: DG.DataFrame[]): string[] {
|
|
188
270
|
const rules = this.getRules(rulesTables);
|
|
189
271
|
const resultList = this.helmColumn.toList().map((helm: string) => {
|
|
190
|
-
|
|
191
|
-
return this.getTransformedHelm(helm, rules);
|
|
192
|
-
|
|
193
|
-
console.log(helm);
|
|
194
|
-
return helm;
|
|
272
|
+
return this.getTransformedHelm(helm, rules);
|
|
195
273
|
});
|
|
196
274
|
return resultList;
|
|
197
275
|
}
|
|
@@ -205,21 +283,6 @@ class PolymerTransformation {
|
|
|
205
283
|
}
|
|
206
284
|
}
|
|
207
285
|
|
|
208
|
-
function getHelmCycle(helm: string, source: ConnectionData): string {
|
|
209
|
-
let cycled = helm.replace(HELM_WRAPPER.RIGHT, '}$');
|
|
210
|
-
|
|
211
|
-
for (let i = 0; i < source.allPos1.length; i++) {
|
|
212
|
-
if (i == 0)
|
|
213
|
-
cycled += 'PEPTIDE1,PEPTIDE1,';
|
|
214
|
-
else
|
|
215
|
-
cycled += '|PEPTIDE1,PEPTIDE1,';
|
|
216
|
-
cycled += `${source.allPos1[i]}:R${source.allAttaches1[i]}-${source.allPos2[i]}:R${source.allAttaches2[i]}`;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
cycled += '$$$';
|
|
220
|
-
return cycled;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
286
|
export async function addTransformedColumn(
|
|
224
287
|
molColumn: DG.Column<string>, addHelm: boolean, ruleFiles: string[], chiralityEngine?: boolean
|
|
225
288
|
): Promise<void> {
|
package/webpack.config.js
CHANGED
|
@@ -2,11 +2,12 @@ const path = require('path');
|
|
|
2
2
|
const FuncGeneratorPlugin = require('datagrok-tools/plugins/func-gen-plugin');
|
|
3
3
|
const packageName = path.parse(require('./package.json').name).name.toLowerCase().replace(/-/g, '');
|
|
4
4
|
|
|
5
|
+
const mode = 'development';
|
|
5
6
|
module.exports = {
|
|
6
7
|
cache: {
|
|
7
8
|
type: 'filesystem',
|
|
8
9
|
},
|
|
9
|
-
mode:
|
|
10
|
+
mode: mode,
|
|
10
11
|
entry: {
|
|
11
12
|
package: ['./src/package.ts'],
|
|
12
13
|
test: {
|
|
@@ -29,12 +30,12 @@ module.exports = {
|
|
|
29
30
|
plugins: [
|
|
30
31
|
new FuncGeneratorPlugin({outputPath: './src/package.g.ts'}),
|
|
31
32
|
],
|
|
32
|
-
devtool: 'source-map',
|
|
33
|
+
devtool: mode === 'development' ? 'source-map' : 'inline-source-map',
|
|
33
34
|
externals: {
|
|
34
35
|
'datagrok-api/dg': 'DG',
|
|
35
36
|
'datagrok-api/grok': 'grok',
|
|
36
37
|
'datagrok-api/ui': 'ui',
|
|
37
|
-
'openchemlib/full
|
|
38
|
+
'openchemlib/full': 'OCL',
|
|
38
39
|
'rxjs': 'rxjs',
|
|
39
40
|
'rxjs/operators': 'rxjs.operators',
|
|
40
41
|
'cash-dom': '$',
|