@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.
Files changed (34) hide show
  1. package/.eslintrc.json +1 -1
  2. package/CHANGELOG.md +24 -0
  3. package/dist/package-test.js +1 -1
  4. package/dist/package-test.js.map +1 -1
  5. package/dist/package.js +1 -1
  6. package/dist/package.js.map +1 -1
  7. package/files/polytool-rules/rules_example.json +35 -38
  8. package/package.json +9 -9
  9. package/src/apps/common/model/oligo-toolkit-package.ts +13 -7
  10. package/src/package.ts +8 -7
  11. package/src/polytool/const.ts +1 -0
  12. package/src/polytool/{pt-conversion.ts → conversion/pt-chain.ts} +118 -285
  13. package/src/polytool/conversion/pt-conversion.ts +26 -0
  14. package/src/polytool/conversion/pt-misc.ts +193 -0
  15. package/src/polytool/conversion/pt-rules.ts +231 -0
  16. package/src/polytool/conversion/rule-manager.ts +205 -0
  17. package/src/polytool/pt-convert-editor.ts +1 -1
  18. package/src/polytool/pt-dialog.ts +133 -6
  19. package/src/polytool/{pt-enumeration-helm-dialog.ts → pt-enumerate-seq-dialog.ts} +243 -114
  20. package/src/polytool/pt-enumeration-helm.ts +2 -2
  21. package/src/polytool/pt-placeholders-breadth-input.ts +80 -39
  22. package/src/polytool/pt-placeholders-input.ts +96 -35
  23. package/src/polytool/pt-unrule-dialog.ts +1 -1
  24. package/src/polytool/pt-unrule.ts +2 -2
  25. package/src/polytool/types.ts +5 -1
  26. package/src/tests/polytool-chain-from-notation-tests.ts +9 -18
  27. package/src/tests/polytool-chain-parse-notation-tests.ts +3 -2
  28. package/src/tests/polytool-convert-tests.ts +5 -3
  29. package/src/tests/polytool-unrule-tests.ts +1 -1
  30. package/src/tests/toAtomicLevel-tests.ts +5 -6
  31. package/src/utils/cell-renderer-cyclized.ts +37 -0
  32. package/src/utils/context-menu.ts +1 -1
  33. package/src/utils/cyclized.ts +23 -26
  34. 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 { this.grid.dataFrame = value; }
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 { this.grid.dataFrame = DG.DataFrame.fromCsv(str); }
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 readonly grid: DG.Grid;
34
+ public grid: DG.Grid;
30
35
 
31
36
  private subs: Unsubscribable[] = [];
32
37
 
33
- protected constructor(name: string | undefined, grid: DG.Grid, heightRowCount?: number) {
38
+ protected constructor(
39
+ private readonly name: string | undefined,
40
+ heightRowCount?: number, options?: {}
41
+ ) {
34
42
  super();
35
43
 
36
- if (name) this.captionLabel.innerText = name;
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 = grid;
44
- this.gridHost.append(this.grid.root);
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
- this.subs.push(this.grid.dataFrame.onDataChanged.subscribe(() => {
56
- this.fireChanged();
57
- }));
98
+ private dataFrameSubs: Unsubscribable[] = [];
58
99
 
59
- this.subs.push(ui.onSizeChanged(this.grid.root).subscribe(() => {
60
- this.grid.columns.byIndex(3)!.width = this.grid.root.clientWidth - this.grid.horzScroll.root.offsetWidth -
61
- this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width - this.grid.columns.byIndex(2)!.width - 10;
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.root.classList.add('ui-input-polytool-pos-grid');
65
- this.root.append(this.gridHost);
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
- detach(): void {
69
- for (const sub of this.subs) sub.unsubscribe();
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
- const df: DG.DataFrame = DG.DataFrame.fromColumns([
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(3)!.width = this.grid.root.clientWidth - this.grid.horzScroll.root.offsetWidth -
96
- this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width - this.grid.columns.byIndex(2)!.width - 10;
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 { this.grid.dataFrame = value; }
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 { this.grid.dataFrame = DG.DataFrame.fromCsv(str); }
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
- public readonly grid: DG.Grid;
34
+ private grid!: DG.Grid;
30
35
 
31
36
  private subs: Unsubscribable[] = [];
32
37
 
33
- protected constructor(name: string | undefined, grid: DG.Grid, heightRowCount?: number) {
38
+ protected constructor(
39
+ private readonly name: string | undefined,
40
+ heightRowCount?: number, options?: {},
41
+ ) {
34
42
  super();
35
43
 
36
- if (name) this.captionLabel.innerText = name;
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 = grid;
44
- this.gridHost.append(this.grid.root);
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
- this.subs.push(this.grid.dataFrame.onDataChanged.subscribe(() => {
56
- this.fireChanged();
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.subs.push(ui.onSizeChanged(this.grid.root).subscribe(() => {
60
- this.grid.columns.byIndex(2)!.width = this.grid.root.clientWidth - this.grid.horzScroll.root.offsetWidth -
61
- this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width - 10;
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.root.classList.add('ui-input-polytool-pos-grid');
65
- this.root.append(this.gridHost);
114
+ this.updateGridHeight(this.grid.dataFrame.rowCount + 0.7);
115
+ this.fireChanged();
66
116
  }
67
117
 
68
- detach(): void {
69
- for (const sub of this.subs) sub.unsubscribe();
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
- const df: DG.DataFrame = DG.DataFrame.fromColumns([
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(2)!.width = this.grid.root.clientWidth - this.grid.horzScroll.root.offsetWidth -
94
- this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width - 10;
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-conversion';
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';
@@ -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 = { start: number, end: number, monomers: string[] };
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-conversion';
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, 10], linkageCount: 3,}
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: [11, 10], linkageCount: 3,}
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, getInnerIdx, getOuterIdx} from '../polytool/pt-conversion';
7
- import {getRules} from '../polytool/pt-rules';
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, delay, expectObject} from '@datagrok-libraries/utils/src/test';
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, getOverriddenLibrary} from '../polytool/pt-conversion';
18
- import {getRules} from '../polytool/pt-rules';
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 {getNewMonomer} from '../polytool/pt-conversion';
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 [newSymbol, newMonomer] = getNewMonomer(rdKitModule, systemMonomerLib, reactionRule);
83
- expect(newSymbol, reactionRule.name);
81
+ const [newSymbols, newMonomers] = getNewMonomers(rdKitModule, systemMonomerLib, reactionRule);
82
+ expect(newSymbols[0], reactionRule.name);
84
83
 
85
- const mol = rdKitModule.get_mol(newMonomer.molfile);
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-enumeration-helm-dialog';
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';