@datagrok/sequence-translator 1.4.8 → 1.5.0
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 +1 -1
- package/CHANGELOG.md +24 -0
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/files/polytool-rules/rules_example.json +35 -38
- package/package.json +9 -9
- package/src/apps/common/model/oligo-toolkit-package.ts +13 -7
- package/src/package.ts +8 -7
- package/src/polytool/const.ts +1 -0
- package/src/polytool/{pt-conversion.ts → conversion/pt-chain.ts} +118 -285
- package/src/polytool/conversion/pt-conversion.ts +26 -0
- package/src/polytool/conversion/pt-misc.ts +193 -0
- package/src/polytool/conversion/pt-rules.ts +231 -0
- package/src/polytool/conversion/rule-manager.ts +205 -0
- package/src/polytool/pt-convert-editor.ts +1 -1
- package/src/polytool/pt-dialog.ts +133 -6
- package/src/polytool/{pt-enumeration-helm-dialog.ts → pt-enumerate-seq-dialog.ts} +243 -114
- package/src/polytool/pt-enumeration-helm.ts +2 -2
- package/src/polytool/pt-placeholders-breadth-input.ts +80 -39
- package/src/polytool/pt-placeholders-input.ts +96 -35
- package/src/polytool/pt-unrule-dialog.ts +1 -1
- package/src/polytool/pt-unrule.ts +2 -2
- package/src/polytool/types.ts +5 -1
- package/src/tests/polytool-chain-from-notation-tests.ts +9 -18
- package/src/tests/polytool-chain-parse-notation-tests.ts +3 -2
- package/src/tests/polytool-convert-tests.ts +5 -3
- package/src/tests/polytool-unrule-tests.ts +1 -1
- package/src/tests/toAtomicLevel-tests.ts +5 -6
- package/src/utils/cell-renderer-cyclized.ts +37 -0
- package/src/utils/context-menu.ts +1 -1
- package/src/utils/cyclized.ts +23 -26
- package/src/polytool/pt-rules.ts +0 -93
|
@@ -2,9 +2,10 @@ import * as ui from 'datagrok-api/ui';
|
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
|
-
import {Unsubscribable} from 'rxjs';
|
|
5
|
+
import {fromEvent, Unsubscribable} from 'rxjs';
|
|
6
6
|
import {PolyToolBreadthPlaceholder} from './types';
|
|
7
7
|
import {parseMonomerSymbolList} from './pt-placeholders-input';
|
|
8
|
+
import {GridCellRenderArgs} from 'datagrok-api/dg';
|
|
8
9
|
|
|
9
10
|
export class PolyToolPlaceholdersBreadthInput extends DG.JsInputBase<DG.DataFrame> {
|
|
10
11
|
get inputType(): string { return 'Breadth'; }
|
|
@@ -15,71 +16,110 @@ export class PolyToolPlaceholdersBreadthInput extends DG.JsInputBase<DG.DataFram
|
|
|
15
16
|
|
|
16
17
|
getValue(): DG.DataFrame { return this.grid.dataFrame; }
|
|
17
18
|
|
|
18
|
-
setValue(value: DG.DataFrame): void {
|
|
19
|
+
setValue(value: DG.DataFrame): void {
|
|
20
|
+
this.setDataFrame(value);
|
|
21
|
+
}
|
|
19
22
|
|
|
20
23
|
getStringValue(): string { return this.grid.dataFrame.toCsv(); }
|
|
21
24
|
|
|
22
|
-
setStringValue(str: string): void {
|
|
25
|
+
setStringValue(str: string): void {
|
|
26
|
+
this.setDataFrame(DG.DataFrame.fromCsv(str));
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
get placeholdersBreadthValue(): PolyToolBreadthPlaceholder[] {
|
|
25
30
|
return dfToPlaceholdersBreadth(this.grid.dataFrame);
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
private readonly gridHost: HTMLDivElement;
|
|
29
|
-
public
|
|
34
|
+
public grid: DG.Grid;
|
|
30
35
|
|
|
31
36
|
private subs: Unsubscribable[] = [];
|
|
32
37
|
|
|
33
|
-
protected constructor(
|
|
38
|
+
protected constructor(
|
|
39
|
+
private readonly name: string | undefined,
|
|
40
|
+
heightRowCount?: number, options?: {}
|
|
41
|
+
) {
|
|
34
42
|
super();
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.gridHost = ui.div([], {
|
|
44
|
+
this.caption = name ?? '';
|
|
45
|
+
this.root.classList.add('ui-input-polytool-pos-grid');
|
|
46
|
+
this.root.append(this.gridHost = ui.div([], {
|
|
39
47
|
classes: 'ui-input-editor',
|
|
40
48
|
style: {width: '100%', height: '100%', marginTop: '-8px', marginBottom: '8px', paddingBottom: '4px'},
|
|
49
|
+
}));
|
|
50
|
+
this.render(heightRowCount, options).then(() => {});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
detach(): void {
|
|
54
|
+
for (const sub of this.subs) sub.unsubscribe();
|
|
55
|
+
for (const sub of this.dataFrameSubs) sub.unsubscribe();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async render(heightRowCount?: number, options?: {}): Promise<void> {
|
|
59
|
+
let removeCol: DG.Column<boolean>;
|
|
60
|
+
const df: DG.DataFrame = DG.DataFrame.fromColumns([
|
|
61
|
+
removeCol = DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Remove', 0),
|
|
62
|
+
DG.Column.fromType(DG.COLUMN_TYPE.INT, 'Start', 0),
|
|
63
|
+
DG.Column.fromType(DG.COLUMN_TYPE.INT, 'End', 0),
|
|
64
|
+
DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Monomers', 0),
|
|
65
|
+
])!;
|
|
66
|
+
removeCol.setTag(DG.TAGS.FRIENDLY_NAME, '');
|
|
67
|
+
this.grid = (await df.plot.fromType(DG.VIEWER.GRID, options)) as DG.Grid;
|
|
68
|
+
this.grid.sort(['Start', 'End']);
|
|
69
|
+
this.grid.columns.byIndex(1)!.width = this.grid.props.rowHeight + 2;
|
|
70
|
+
|
|
71
|
+
this.grid.onCellRender.subscribe((eventArgs: GridCellRenderArgs) => {
|
|
72
|
+
const gridCell = eventArgs.cell;
|
|
73
|
+
if (gridCell.tableColumn?.name == removeCol.name && (gridCell?.tableRowIndex ?? -1) >= 0) {
|
|
74
|
+
gridCell.element = ui.div(ui.icons.delete(() => {
|
|
75
|
+
this.grid.dataFrame.rows.removeAt(gridCell.tableRowIndex!);
|
|
76
|
+
}, 'Delete'), {
|
|
77
|
+
style: {
|
|
78
|
+
height: `${gridCell.grid.props.rowHeight}px`, color: 'var(--grey-6)',
|
|
79
|
+
display: 'flex', flexDirection: 'row', justifyContent: 'center'
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
41
83
|
});
|
|
42
84
|
|
|
43
|
-
this.grid
|
|
44
|
-
this.
|
|
85
|
+
this.updateGridHeight(heightRowCount ?? this.grid.dataFrame.rowCount + 0.7);
|
|
86
|
+
this.subs.push(ui.onSizeChanged(this.grid.root)
|
|
87
|
+
.subscribe(this.gridRootOnSizeChanged.bind(this)));
|
|
88
|
+
this.subs.push(fromEvent<KeyboardEvent>(this.grid.root, 'keydown')
|
|
89
|
+
.subscribe((e: KeyboardEvent) => {
|
|
90
|
+
if (e.key === 'Enter') e.stopPropagation();
|
|
91
|
+
}));
|
|
92
|
+
this.setDataFrame(df);
|
|
45
93
|
|
|
46
|
-
if (heightRowCount != null) {
|
|
47
|
-
this.updateGridHeight(heightRowCount + 0.7);
|
|
48
|
-
} else {
|
|
49
|
-
this.updateGridHeight(this.grid.dataFrame.rowCount + 0.6);
|
|
50
|
-
this.subs.push(this.grid.dataFrame.onRowsAdded
|
|
51
|
-
.subscribe(() => { this.updateGridHeight(this.grid.dataFrame.rowCount + 0.6); }));
|
|
52
|
-
}
|
|
53
94
|
this.grid.root.style.width = `100%`;
|
|
95
|
+
this.gridHost.append(this.grid.root);
|
|
96
|
+
}
|
|
54
97
|
|
|
55
|
-
|
|
56
|
-
this.fireChanged();
|
|
57
|
-
}));
|
|
98
|
+
private dataFrameSubs: Unsubscribable[] = [];
|
|
58
99
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}));
|
|
100
|
+
private setDataFrame(dataFrame: DG.DataFrame): void {
|
|
101
|
+
for (const sub of this.dataFrameSubs) sub.unsubscribe();
|
|
102
|
+
this.grid.dataFrame = dataFrame;
|
|
63
103
|
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
104
|
+
this.dataFrameSubs.push(this.grid.dataFrame.onRowsRemoved
|
|
105
|
+
.subscribe(() => {
|
|
106
|
+
this.updateGridHeight(this.grid.dataFrame.rowCount + 0.7);
|
|
107
|
+
this.fireChanged();
|
|
108
|
+
}));
|
|
109
|
+
this.dataFrameSubs.push(this.grid.dataFrame.onRowsAdded
|
|
110
|
+
.subscribe(() => { this.updateGridHeight(this.grid.dataFrame.rowCount + 0.7); }));
|
|
111
|
+
this.dataFrameSubs.push(this.grid.dataFrame.onDataChanged.subscribe(() => {
|
|
112
|
+
this.fireChanged();
|
|
113
|
+
}));
|
|
67
114
|
|
|
68
|
-
|
|
69
|
-
|
|
115
|
+
this.updateGridHeight(this.grid.dataFrame.rowCount + 0.7);
|
|
116
|
+
this.fireChanged();
|
|
70
117
|
}
|
|
71
118
|
|
|
72
119
|
public static async create(
|
|
73
120
|
name?: string, options?: {}, heightRowCount?: number
|
|
74
121
|
): Promise<PolyToolPlaceholdersBreadthInput> {
|
|
75
|
-
|
|
76
|
-
DG.Column.fromType(DG.COLUMN_TYPE.INT, 'Start', 0),
|
|
77
|
-
DG.Column.fromType(DG.COLUMN_TYPE.INT, 'End', 0),
|
|
78
|
-
DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Monomers', 0),
|
|
79
|
-
])!;
|
|
80
|
-
const grid = (await df.plot.fromType(DG.VIEWER.GRID, options)) as DG.Grid;
|
|
81
|
-
grid.sort(['Start', 'End']);
|
|
82
|
-
return new PolyToolPlaceholdersBreadthInput(name, grid, heightRowCount);
|
|
122
|
+
return new PolyToolPlaceholdersBreadthInput(name, heightRowCount, options);
|
|
83
123
|
}
|
|
84
124
|
|
|
85
125
|
// -- Update view --
|
|
@@ -92,8 +132,9 @@ export class PolyToolPlaceholdersBreadthInput extends DG.JsInputBase<DG.DataFram
|
|
|
92
132
|
// -- Handle events --
|
|
93
133
|
|
|
94
134
|
private gridRootOnSizeChanged(): void {
|
|
95
|
-
this.grid.columns.byIndex(
|
|
96
|
-
this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width -
|
|
135
|
+
this.grid.columns.byIndex(4)!.width = this.grid.root.clientWidth - this.grid.horzScroll.root.offsetWidth -
|
|
136
|
+
this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width -
|
|
137
|
+
this.grid.columns.byIndex(2)!.width - this.grid.columns.byIndex(3)!.width - 10;
|
|
97
138
|
}
|
|
98
139
|
}
|
|
99
140
|
|
|
@@ -2,9 +2,10 @@ import * as ui from 'datagrok-api/ui';
|
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
|
-
import {Unsubscribable} from 'rxjs';
|
|
5
|
+
import {fromEvent, Unsubscribable} from 'rxjs';
|
|
6
6
|
|
|
7
7
|
import {PolyToolPlaceholder} from './types';
|
|
8
|
+
import {GridCellRenderArgs} from 'datagrok-api/dg';
|
|
8
9
|
|
|
9
10
|
export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
|
|
10
11
|
get inputType(): string { return 'Positions'; }
|
|
@@ -15,69 +16,126 @@ export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
|
|
|
15
16
|
|
|
16
17
|
getValue(): DG.DataFrame { return this.grid.dataFrame; }
|
|
17
18
|
|
|
18
|
-
setValue(value: DG.DataFrame): void {
|
|
19
|
+
setValue(value: DG.DataFrame): void {
|
|
20
|
+
this.setDataFrame(value);
|
|
21
|
+
}
|
|
19
22
|
|
|
20
23
|
getStringValue(): string { return this.grid.dataFrame.toCsv(); }
|
|
21
24
|
|
|
22
|
-
setStringValue(str: string): void {
|
|
25
|
+
setStringValue(str: string): void {
|
|
26
|
+
this.setDataFrame(DG.DataFrame.fromCsv(str));
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
get placeholdersValue(): PolyToolPlaceholder[] {
|
|
25
30
|
return dfToPlaceholders(this.grid.dataFrame);
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
private readonly gridHost: HTMLDivElement;
|
|
29
|
-
|
|
34
|
+
private grid!: DG.Grid;
|
|
30
35
|
|
|
31
36
|
private subs: Unsubscribable[] = [];
|
|
32
37
|
|
|
33
|
-
protected constructor(
|
|
38
|
+
protected constructor(
|
|
39
|
+
private readonly name: string | undefined,
|
|
40
|
+
heightRowCount?: number, options?: {},
|
|
41
|
+
) {
|
|
34
42
|
super();
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.gridHost = ui.div([], {
|
|
44
|
+
this.caption = name ?? '';
|
|
45
|
+
this.root.classList.add('ui-input-polytool-pos-grid');
|
|
46
|
+
this.root.append(this.gridHost = ui.div([], {
|
|
39
47
|
classes: 'ui-input-editor',
|
|
40
48
|
style: {width: '100%', height: '100%', marginTop: '-8px', marginBottom: '8px', paddingBottom: '4px'},
|
|
49
|
+
}));
|
|
50
|
+
this.render(heightRowCount, options).then(() => {});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
detach(): void {
|
|
54
|
+
for (const sub of this.subs) sub.unsubscribe();
|
|
55
|
+
for (const sub of this.dataFrameSubs) sub.unsubscribe();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async render(heightRowCount?: number, options?: {}): Promise<void> {
|
|
59
|
+
// this.captionLabel.appendChild(ui.divH([ui.divText(this.name ?? this.caption), ui.icons.add(() => {}, 'Add')]));
|
|
60
|
+
let removeCol: DG.Column<boolean>;
|
|
61
|
+
const df: DG.DataFrame = DG.DataFrame.fromColumns([
|
|
62
|
+
removeCol = DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Remove', 0),
|
|
63
|
+
DG.Column.fromType(DG.COLUMN_TYPE.INT, 'Position', 0),
|
|
64
|
+
DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Monomers', 0),])!;
|
|
65
|
+
removeCol.setTag(DG.TAGS.FRIENDLY_NAME, '');
|
|
66
|
+
this.grid = (await df.plot.fromType(DG.VIEWER.GRID, options)) as DG.Grid;
|
|
67
|
+
this.grid.sort(['Position']);
|
|
68
|
+
this.grid.columns.byIndex(1)!.width = this.grid.props.rowHeight + 2;
|
|
69
|
+
|
|
70
|
+
this.grid.onCellRender.subscribe((eventArgs: GridCellRenderArgs) => {
|
|
71
|
+
const gridCell = eventArgs.cell;
|
|
72
|
+
if (gridCell.tableColumn?.name == removeCol.name && (gridCell?.tableRowIndex ?? -1) >= 0) {
|
|
73
|
+
gridCell.element = ui.div(ui.icons.delete(() => {
|
|
74
|
+
this.grid.dataFrame.rows.removeAt(gridCell.tableRowIndex!);
|
|
75
|
+
}, 'Delete'), {
|
|
76
|
+
style: {
|
|
77
|
+
height: `${gridCell.grid.props.rowHeight}px`, color: 'var(--grey-6)',
|
|
78
|
+
display: 'flex', flexDirection: 'row', justifyContent: 'center'
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
41
82
|
});
|
|
42
83
|
|
|
43
|
-
this.grid
|
|
44
|
-
this.
|
|
84
|
+
this.updateGridHeight(heightRowCount ?? this.grid.dataFrame.rowCount + 0.7);
|
|
85
|
+
this.subs.push(ui.onSizeChanged(this.grid.root)
|
|
86
|
+
.subscribe(this.gridRootOnSizeChanged.bind(this)));
|
|
87
|
+
this.subs.push(fromEvent<KeyboardEvent>(this.grid.root, 'keydown')
|
|
88
|
+
.subscribe((e: KeyboardEvent) => {
|
|
89
|
+
if (e.key === 'Enter') e.stopPropagation();
|
|
90
|
+
}));
|
|
91
|
+
this.setDataFrame(df);
|
|
45
92
|
|
|
46
|
-
if (heightRowCount != null) {
|
|
47
|
-
this.updateGridHeight(heightRowCount + 0.7);
|
|
48
|
-
} else {
|
|
49
|
-
this.updateGridHeight(this.grid.dataFrame.rowCount + 0.6);
|
|
50
|
-
this.subs.push(this.grid.dataFrame.onRowsAdded
|
|
51
|
-
.subscribe(() => { this.updateGridHeight(this.grid.dataFrame.rowCount + 0.6); }));
|
|
52
|
-
}
|
|
53
93
|
this.grid.root.style.width = `100%`;
|
|
94
|
+
this.gridHost.append(this.grid.root);
|
|
95
|
+
}
|
|
54
96
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
97
|
+
private dataFrameSubs: Unsubscribable[] = [];
|
|
98
|
+
|
|
99
|
+
private setDataFrame(dataFrame: DG.DataFrame): void {
|
|
100
|
+
for (const sub of this.dataFrameSubs) sub.unsubscribe();
|
|
101
|
+
this.grid.dataFrame = dataFrame;
|
|
58
102
|
|
|
59
|
-
this.
|
|
60
|
-
|
|
61
|
-
this.
|
|
103
|
+
this.dataFrameSubs.push(this.grid.dataFrame.onRowsRemoved
|
|
104
|
+
.subscribe(() => {
|
|
105
|
+
this.updateGridHeight(this.grid.dataFrame.rowCount + 0.7);
|
|
106
|
+
this.fireChanged();
|
|
107
|
+
}));
|
|
108
|
+
this.dataFrameSubs.push(this.grid.dataFrame.onRowsAdded
|
|
109
|
+
.subscribe(() => { this.updateGridHeight(this.grid.dataFrame.rowCount + 0.7); }));
|
|
110
|
+
this.dataFrameSubs.push(this.grid.dataFrame.onDataChanged.subscribe(() => {
|
|
111
|
+
this.fireChanged();
|
|
62
112
|
}));
|
|
63
113
|
|
|
64
|
-
this.
|
|
65
|
-
this.
|
|
114
|
+
this.updateGridHeight(this.grid.dataFrame.rowCount + 0.7);
|
|
115
|
+
this.fireChanged();
|
|
66
116
|
}
|
|
67
117
|
|
|
68
|
-
|
|
69
|
-
|
|
118
|
+
/** @param {number} posOutIdx continuous (outer) position index, 0-based */
|
|
119
|
+
addPosition(posOutIdx: number): void {
|
|
120
|
+
const phDf = this.grid.dataFrame;
|
|
121
|
+
const posList = phDf.columns.byName('Position').toList();
|
|
122
|
+
let rowIdx = posList.indexOf(posOutIdx + 1);
|
|
123
|
+
if (rowIdx === -1) {
|
|
124
|
+
rowIdx = posList.findIndex((v) => isNaN(v));
|
|
125
|
+
if (rowIdx === -1)
|
|
126
|
+
rowIdx = phDf.rows.addNew(['', posOutIdx + 1, '']).idx;
|
|
127
|
+
const tgtCell = this.grid.cell('Monomers', rowIdx);
|
|
128
|
+
}
|
|
129
|
+
phDf.currentCell = phDf.cell(rowIdx, 'Monomers');
|
|
130
|
+
//const gridRowIdx = inputs.placeholders.grid.tableRowToGrid(rowIdx);
|
|
131
|
+
//const monomersGCell = inputs.placeholders.grid.cell('Monomers', gridRowIdx);
|
|
132
|
+
const k = 42;
|
|
70
133
|
}
|
|
71
134
|
|
|
72
135
|
public static async create(
|
|
73
136
|
name?: string, options?: {}, heightRowCount?: number
|
|
74
137
|
): Promise<PolyToolPlaceholdersInput> {
|
|
75
|
-
|
|
76
|
-
DG.Column.fromType(DG.COLUMN_TYPE.INT, 'Position', 0),
|
|
77
|
-
DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Monomers', 0),])!;
|
|
78
|
-
const grid = (await df.plot.fromType(DG.VIEWER.GRID, options)) as DG.Grid;
|
|
79
|
-
grid.sort(['Position']);
|
|
80
|
-
return new PolyToolPlaceholdersInput(name, grid, heightRowCount);
|
|
138
|
+
return new PolyToolPlaceholdersInput(name, heightRowCount, options);
|
|
81
139
|
}
|
|
82
140
|
|
|
83
141
|
// -- Update view --
|
|
@@ -90,8 +148,9 @@ export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
|
|
|
90
148
|
// -- Handle events --
|
|
91
149
|
|
|
92
150
|
private gridRootOnSizeChanged(): void {
|
|
93
|
-
this.grid.columns.byIndex(
|
|
94
|
-
this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width -
|
|
151
|
+
this.grid.columns.byIndex(3)!.width = this.grid.root.clientWidth - this.grid.horzScroll.root.offsetWidth -
|
|
152
|
+
this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width -
|
|
153
|
+
this.grid.columns.byIndex(2)!.width - 10;
|
|
95
154
|
}
|
|
96
155
|
}
|
|
97
156
|
|
|
@@ -111,6 +170,8 @@ export function getPlaceholdersFromText(src: string): PolyToolPlaceholder[] {
|
|
|
111
170
|
export function dfToPlaceholders(df: DG.DataFrame): PolyToolPlaceholder[] {
|
|
112
171
|
const res: PolyToolPlaceholder[] = [];
|
|
113
172
|
for (let rowI = 0; rowI < df.rowCount; rowI++) {
|
|
173
|
+
if (df.getCol('Position').isNone(rowI))
|
|
174
|
+
continue;
|
|
114
175
|
const pos = parseInt(df.get('Position', rowI)) - 1;
|
|
115
176
|
if (!isNaN(pos)) {
|
|
116
177
|
const monomerSymbolList = parseMonomerSymbolList(df.get('Monomers', rowI));
|
|
@@ -10,7 +10,7 @@ import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
|
10
10
|
|
|
11
11
|
import {defaultErrorHandler} from '../utils/err-info';
|
|
12
12
|
import {doPolyToolUnrule} from './pt-unrule';
|
|
13
|
-
import {getRules, RuleInputs, RULES_PATH, RULES_STORAGE_NAME} from './pt-rules';
|
|
13
|
+
import {getRules, RuleInputs, RULES_PATH, RULES_STORAGE_NAME} from './conversion/pt-rules';
|
|
14
14
|
import {PT_ERROR_DATAFRAME, PT_UI_DIALOG_UNRULE, PT_UI_RULES_USED} from './const';
|
|
15
15
|
|
|
16
16
|
import {_package} from '../package';
|
|
@@ -4,9 +4,9 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
6
6
|
|
|
7
|
-
import {Chain} from './pt-
|
|
7
|
+
import {Chain} from './conversion/pt-chain';
|
|
8
8
|
import {getPolyToolUnruleDialog} from './pt-unrule-dialog';
|
|
9
|
-
import {Rules} from './pt-rules';
|
|
9
|
+
import {Rules} from './conversion/pt-rules';
|
|
10
10
|
|
|
11
11
|
import {_package} from '../package';
|
|
12
12
|
import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
package/src/polytool/types.ts
CHANGED
|
@@ -13,7 +13,11 @@ export type PolyToolEnumeratorType = typeof PolyToolEnumeratorTypes[keyof typeof
|
|
|
13
13
|
|
|
14
14
|
export type PolyToolPlaceholder = { position: number, monomers: string[] };
|
|
15
15
|
|
|
16
|
-
export type PolyToolBreadthPlaceholder = {
|
|
16
|
+
export type PolyToolBreadthPlaceholder = {
|
|
17
|
+
/** 0-based monomer position index */ start: number,
|
|
18
|
+
/** 0-based monomer position index */ end: number,
|
|
19
|
+
monomers: string[]
|
|
20
|
+
};
|
|
17
21
|
|
|
18
22
|
export type PolyToolEnumeratorParams = {
|
|
19
23
|
type: PolyToolEnumeratorType;
|
|
@@ -3,8 +3,8 @@ import * as ui from 'datagrok-api/ui';
|
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
5
|
import {before, after, category, expect, test, expectArray, testEvent, delay} from '@datagrok-libraries/utils/src/test';
|
|
6
|
-
import {Chain} from '../polytool/pt-
|
|
7
|
-
import {getRules} from '../polytool/pt-rules';
|
|
6
|
+
import {Chain} from '../polytool/conversion/pt-chain';
|
|
7
|
+
import {getRules} from '../polytool/conversion/pt-rules';
|
|
8
8
|
import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
9
9
|
|
|
10
10
|
category('PolyTool: Chain', () => {
|
|
@@ -23,7 +23,7 @@ category('PolyTool: Chain', () => {
|
|
|
23
23
|
},
|
|
24
24
|
tgt: {
|
|
25
25
|
templateChain: {monomerCount: [11], linkageCount: 0},
|
|
26
|
-
mmChain: {monomerCount: [11], linkageCount: 1
|
|
26
|
+
mmChain: {monomerCount: [11], linkageCount: 1}
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
29
|
'reaction1': {
|
|
@@ -54,15 +54,11 @@ category('PolyTool: Chain', () => {
|
|
|
54
54
|
templateHelm: 'PEPTIDE1{[(#3)Succ]}' + '|' +
|
|
55
55
|
'PEPTIDE2{[A(CHOL)].F.[C(1)].T.G.H.Y.P.[C(1)].[NH2]}' + '$' +
|
|
56
56
|
'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '$$$' + 'V2.0',
|
|
57
|
-
mmHelm: 'PEPTIDE1{[Succ].[A(CHOL)].F.C.T.G.H.Y.P.C.[NH2]}'
|
|
58
|
-
'PEPTIDE2{[A(CHOL)].F.C.T.G.H.Y.P.C.[NH2]}' + '$' +
|
|
59
|
-
'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '|' +
|
|
60
|
-
'PEPTIDE1,PEPTIDE1,4:R3-10:R3' + '|' +
|
|
61
|
-
'PEPTIDE2,PEPTIDE2,3:R3-9:R3' + '$$$V2.0',
|
|
57
|
+
mmHelm: 'PEPTIDE1{[(#3)Succ].[{A(CHOL)].F.C.T.G.H.Y.P.C.[NH2}]}$PEPTIDE1,PEPTIDE1,4:R3-10:R3$$$V2.0',
|
|
62
58
|
},
|
|
63
59
|
tgt: {
|
|
64
60
|
templateChain: {monomerCount: [1, 10], linkageCount: 1},
|
|
65
|
-
mmChain: {monomerCount: [11
|
|
61
|
+
mmChain: {monomerCount: [11], linkageCount: 1}
|
|
66
62
|
}
|
|
67
63
|
},
|
|
68
64
|
'dimerized2': {
|
|
@@ -72,15 +68,11 @@ category('PolyTool: Chain', () => {
|
|
|
72
68
|
'PEPTIDE2{R.F.[C(1)].T.G.H.F.P.[C(1)].[NH2]}' + '|' +
|
|
73
69
|
'PEPTIDE3{[($3)A(CHOL)].F.[C(1)].Y.H.G.D.N.[C(1)].[meI]}' + '$' +
|
|
74
70
|
'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '$$$' + 'V2.0',
|
|
75
|
-
mmHelm: 'PEPTIDE1{[Succ].R.F.C.T.G.H.F.P.C.[NH2]}'
|
|
76
|
-
'PEPTIDE2{[A(CHOL)].F.C.Y.H.G.D.N.C.[meI]}' + '$' +
|
|
77
|
-
'PEPTIDE1,PEPTIDE2,1:R1-1:R1' + '|' +
|
|
78
|
-
'PEPTIDE1,PEPTIDE1,4:R3-10:R3' + '|' +
|
|
79
|
-
'PEPTIDE2,PEPTIDE2,3:R3-9:R3' + '$$$V2.0',
|
|
71
|
+
mmHelm: 'PEPTIDE1{[($3)Succ].[{R].F.C.T.G.H.F.P.C.[NH2}($3){A(CHOL)].F.[C(1)].Y.H.G.D.N.[C(1)].[meI}]}$PEPTIDE1,PEPTIDE1,4:R3-10:R3$$$V2.0',
|
|
80
72
|
},
|
|
81
73
|
tgt: {
|
|
82
|
-
templateChain: {monomerCount: [1, 10, 10], linkageCount: 1
|
|
83
|
-
mmChain: {monomerCount: [
|
|
74
|
+
templateChain: {monomerCount: [1, 10, 10], linkageCount: 1},
|
|
75
|
+
mmChain: {monomerCount: [20], linkageCount: 1}
|
|
84
76
|
}
|
|
85
77
|
}
|
|
86
78
|
};
|
|
@@ -124,12 +116,11 @@ category('PolyTool: Chain', () => {
|
|
|
124
116
|
test(`applyRules-${testName}`, async () => {
|
|
125
117
|
const rules = await getRules(['rules_example.json']);
|
|
126
118
|
const resTemplateChain = Chain.parseNotation(data.templateSeq, helmHelper);
|
|
127
|
-
const resMmChain = resTemplateChain.applyRules(rules);
|
|
119
|
+
const resMmChain = await resTemplateChain.applyRules(rules);
|
|
128
120
|
resMmChain.check(true);
|
|
129
121
|
expectArray(resMmChain.monomers.map((mL) => mL.length), tgt.mmChain.monomerCount);
|
|
130
122
|
expect(resMmChain.linkages.length, tgt.mmChain.linkageCount);
|
|
131
123
|
expect(resMmChain.getHelm(), data.mmHelm);
|
|
132
124
|
}, {skipReason: 'applyRules is not implemented'});
|
|
133
125
|
}
|
|
134
|
-
|
|
135
126
|
});
|
|
@@ -3,8 +3,9 @@ import * as ui from 'datagrok-api/ui';
|
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
5
|
import {before, after, category, expect, test, expectArray, testEvent, delay} from '@datagrok-libraries/utils/src/test';
|
|
6
|
-
import {Chain
|
|
7
|
-
import {
|
|
6
|
+
import {Chain} from '../polytool/conversion/pt-chain';
|
|
7
|
+
import {getInnerIdx, getOuterIdx} from '../polytool/conversion/pt-misc';
|
|
8
|
+
import {getRules} from '../polytool/conversion/pt-rules';
|
|
8
9
|
import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
9
10
|
|
|
10
11
|
category('PolyTool: Chain: parseNotation', () => {
|
|
@@ -2,7 +2,8 @@ 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
|
-
import {before, after, category, expect, test, expectArray, testEvent,
|
|
5
|
+
import {before, after, category, expect, test, expectArray, testEvent, expectObject}
|
|
6
|
+
from '@datagrok-libraries/utils/src/test';
|
|
6
7
|
import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
7
8
|
import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
8
9
|
import {
|
|
@@ -14,8 +15,9 @@ import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
|
14
15
|
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
15
16
|
import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
16
17
|
|
|
17
|
-
import {doPolyToolConvert
|
|
18
|
-
import {
|
|
18
|
+
import {doPolyToolConvert} from '../polytool/conversion/pt-conversion';
|
|
19
|
+
import {getOverriddenLibrary} from '../polytool/conversion/pt-misc';
|
|
20
|
+
import {getRules} from '../polytool/conversion/pt-rules';
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
import {_package} from '../package-test';
|
|
@@ -5,6 +5,6 @@ import * as DG from 'datagrok-api/dg';
|
|
|
5
5
|
import {before, after, category, expect, test, expectArray, testEvent, delay} from '@datagrok-libraries/utils/src/test';
|
|
6
6
|
|
|
7
7
|
import {doPolyToolUnrule} from '../polytool/pt-unrule';
|
|
8
|
-
import {getRules} from '../polytool/pt-rules';
|
|
8
|
+
import {getRules} from '../polytool/conversion/pt-rules';
|
|
9
9
|
|
|
10
10
|
import {_package} from '../package-test';
|
|
@@ -15,8 +15,8 @@ import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
|
15
15
|
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
16
16
|
|
|
17
17
|
import {_package} from '../package-test';
|
|
18
|
-
import {
|
|
19
|
-
import {getRules, RuleReaction} from '../polytool/pt-rules';
|
|
18
|
+
import {getNewMonomers} from '../polytool/conversion/pt-misc';
|
|
19
|
+
import {getRules, RuleReaction} from '../polytool/conversion/pt-rules';
|
|
20
20
|
|
|
21
21
|
category('toAtomicLevel', () => {
|
|
22
22
|
let userLibSettings: UserLibSettings;
|
|
@@ -24,7 +24,6 @@ category('toAtomicLevel', () => {
|
|
|
24
24
|
let rdKitModule: RDModule;
|
|
25
25
|
|
|
26
26
|
before(async () => {
|
|
27
|
-
|
|
28
27
|
monomerLibHelper = await getMonomerLibHelper();
|
|
29
28
|
userLibSettings = await getUserLibSettings();
|
|
30
29
|
rdKitModule = await getRdKitModule();
|
|
@@ -79,10 +78,10 @@ category('toAtomicLevel', () => {
|
|
|
79
78
|
const rules = await getRules(['rules_example.json']);
|
|
80
79
|
const reactionRule = rules.reactionRules.find((r) => r.name == 'GGaz')!;
|
|
81
80
|
|
|
82
|
-
const [
|
|
83
|
-
expect(
|
|
81
|
+
const [newSymbols, newMonomers] = getNewMonomers(rdKitModule, systemMonomerLib, reactionRule);
|
|
82
|
+
expect(newSymbols[0], reactionRule.name);
|
|
84
83
|
|
|
85
|
-
const mol = rdKitModule.get_mol(
|
|
84
|
+
const mol = rdKitModule.get_mol(newMonomers[0].molfile);
|
|
86
85
|
try {
|
|
87
86
|
const molInchi = mol.get_inchi();
|
|
88
87
|
const molInchiKey = rdKitModule.get_inchikey_for_inchi(molInchi);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import {MonomerPlacer} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
|
|
6
|
+
import {monomerToShort} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
7
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
8
|
+
|
|
9
|
+
import {_package} from '../package';
|
|
10
|
+
|
|
11
|
+
export class CyclizedCellRendererBack extends MonomerPlacer {
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
gridCol: DG.GridColumn | null, tableCol: DG.Column,
|
|
15
|
+
maxLengthOfMonomer: number, seqHelper: ISeqHelper
|
|
16
|
+
) {
|
|
17
|
+
super(gridCol, tableCol, _package.logger, maxLengthOfMonomer, () => {
|
|
18
|
+
const sh = seqHelper.getSeqHandler(tableCol);
|
|
19
|
+
return {
|
|
20
|
+
seqHandler: sh,
|
|
21
|
+
monomerCharWidth: 7,
|
|
22
|
+
separatorWidth: 11,
|
|
23
|
+
monomerToShort: monomerToShort,
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override onMouseMove(gridCell: DG.GridCell, e: MouseEvent) {
|
|
29
|
+
const gridCellBounds: DG.Rect = gridCell.bounds;
|
|
30
|
+
const argsX = e.offsetX - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCellBounds.x);
|
|
31
|
+
const left: number | null = this.getPosition(gridCell.tableRowIndex!, argsX, gridCellBounds.width);
|
|
32
|
+
if(left != null) {
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
super.onMouseMove(gridCell, e);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -3,7 +3,7 @@ import * as DG from 'datagrok-api/dg';
|
|
|
3
3
|
import * as ui from 'datagrok-api/ui';
|
|
4
4
|
|
|
5
5
|
import {defaultErrorHandler} from './err-info';
|
|
6
|
-
import {polyToolEnumerateHelmUI} from '../polytool/pt-
|
|
6
|
+
import {polyToolEnumerateHelmUI} from '../polytool/pt-enumerate-seq-dialog';
|
|
7
7
|
import {polyToolEnumerateChemUI} from '../polytool/pt-dialog';
|
|
8
8
|
|
|
9
9
|
import {_package} from '../package';
|