@datagrok/sequence-translator 1.4.8 → 1.4.10

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.
@@ -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));
@@ -4,7 +4,7 @@ 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
9
  import {Rules} from './pt-rules';
10
10
 
@@ -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,7 +3,7 @@ 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';
6
+ import {Chain} from '../polytool/conversion/pt-chain';
7
7
  import {getRules} from '../polytool/pt-rules';
8
8
  import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
9
9
 
@@ -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': {
@@ -124,12 +124,11 @@ category('PolyTool: Chain', () => {
124
124
  test(`applyRules-${testName}`, async () => {
125
125
  const rules = await getRules(['rules_example.json']);
126
126
  const resTemplateChain = Chain.parseNotation(data.templateSeq, helmHelper);
127
- const resMmChain = resTemplateChain.applyRules(rules);
127
+ const resMmChain = await resTemplateChain.applyRules(rules);
128
128
  resMmChain.check(true);
129
129
  expectArray(resMmChain.monomers.map((mL) => mL.length), tgt.mmChain.monomerCount);
130
130
  expect(resMmChain.linkages.length, tgt.mmChain.linkageCount);
131
131
  expect(resMmChain.getHelm(), data.mmHelm);
132
132
  }, {skipReason: 'applyRules is not implemented'});
133
133
  }
134
-
135
134
  });
@@ -3,7 +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, getInnerIdx, getOuterIdx} from '../polytool/pt-conversion';
6
+ import {Chain} from '../polytool/conversion/pt-chain';
7
+ import {getInnerIdx, getOuterIdx} from '../polytool/conversion/pt-misc';
7
8
  import {getRules} from '../polytool/pt-rules';
8
9
  import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
9
10
 
@@ -14,7 +14,8 @@ import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
14
14
  import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
15
15
  import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
16
16
 
17
- import {doPolyToolConvert, getOverriddenLibrary} from '../polytool/pt-conversion';
17
+ import {doPolyToolConvert} from '../polytool/conversion/pt-conversion';
18
+ import {getOverriddenLibrary} from '../polytool/conversion/pt-misc';
18
19
  import {getRules} from '../polytool/pt-rules';
19
20
 
20
21
 
@@ -15,7 +15,7 @@ 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';
18
+ import {getNewMonomer} from '../polytool/conversion/pt-misc';
19
19
  import {getRules, RuleReaction} from '../polytool/pt-rules';
20
20
 
21
21
  category('toAtomicLevel', () => {
@@ -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();
@@ -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';
@@ -13,11 +13,12 @@ import {CellRendererBackBase} from '@datagrok-libraries/bio/src/utils/cell-rende
13
13
  import {MonomerPlacer} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
14
14
  import {monomerToShort, StringListSeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
15
15
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
16
- import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
16
+ import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
17
17
 
18
- import {Chain} from '../polytool/pt-conversion';
18
+ import {Chain} from '../polytool/conversion/pt-chain';
19
19
 
20
20
  import {_package} from '../package';
21
+ import {CyclizedCellRendererBack} from './cell-renderer-cyclized';
21
22
 
22
23
  /* eslint-enable max-len */
23
24
 
@@ -25,14 +26,18 @@ export class CyclizedNotationProvider implements INotationProvider {
25
26
  private readonly separatorSplitter: SplitterFunc;
26
27
  public readonly splitter: SplitterFunc;
27
28
 
29
+ get defaultGapOriginal(): string { return ''; }
30
+
28
31
  constructor(
29
32
  public readonly separator: string,
30
- protected readonly seqHelper: ISeqHelper
33
+ protected readonly helmHelper: IHelmHelper
31
34
  ) {
32
35
  this.separatorSplitter = getSplitterWithSeparator(this.separator);
33
36
  this.splitter = this._splitter.bind(this);
34
37
  }
35
38
 
39
+ setUnits(): void {}
40
+
36
41
  private _splitter(seq: string): ISeqSplitted {
37
42
  const baseSS: ISeqSplitted = this.separatorSplitter(seq);
38
43
  return new CyclizedSeqSplitted(
@@ -40,25 +45,17 @@ export class CyclizedNotationProvider implements INotationProvider {
40
45
  GapOriginals[NOTATION.SEPARATOR]);
41
46
  }
42
47
 
43
- public async getHelm(seq: string, options?: any): Promise<string> {
44
- const helmHelper = await getHelmHelper();
45
- const seqChain = await Chain.parseNotation(seq, helmHelper);
48
+ public getHelm(seq: string, options?: any): string {
49
+ const seqChain = Chain.parseNotation(seq, this.helmHelper);
46
50
  const resPseudoHelm = seqChain.getNotationHelm();
47
51
  return resPseudoHelm;
48
52
  }
49
53
 
50
54
  public createCellRendererBack(gridCol: DG.GridColumn | null, tableCol: DG.Column<string>): CellRendererBackBase<string> {
51
55
  let maxLengthOfMonomer: number = 4; // (_package.bioProperties ? _package.bioProperties.maxMonomerLength : 4) ?? 50;
52
- const back = new MonomerPlacer(gridCol, tableCol, _package.logger, maxLengthOfMonomer,
53
- () => {
54
- const sh = this.seqHelper.getSeqHandler(tableCol);
55
- return {
56
- seqHandler: sh,
57
- monomerCharWidth: 7,
58
- separatorWidth: 11,
59
- monomerToShort: monomerToShort,
60
- };
61
- });
56
+ const back = new CyclizedCellRendererBack(gridCol, tableCol,
57
+ maxLengthOfMonomer, this.helmHelper.seqHelper);
58
+
62
59
  back.init().then(() => {});
63
60
  return back;
64
61
  }
@@ -66,23 +63,23 @@ export class CyclizedNotationProvider implements INotationProvider {
66
63
 
67
64
  /** Gets canonical monomers for original ones with cyclization marks */
68
65
  export class CyclizedSeqSplitted extends StringListSeqSplitted {
69
- private readonly seqCList: (string | null)[];
70
-
71
66
  override getCanonical(posIdx: number): string {
72
67
  if (this.isGap(posIdx)) return GAP_SYMBOL;
73
68
 
74
- let cmRes: string | null = this.seqCList[posIdx];
75
- if (cmRes === null) {
76
- const om = this.getOriginal(posIdx);
77
- cmRes = om;
78
- if (om[om.length - 1] === ')')
79
- cmRes = this.seqCList[posIdx] = om.replace(/\(\d+\)$/, '');
80
- }
69
+ const om = this.getOriginal(posIdx);
70
+ let cmRes = om;
71
+ if (om.startsWith('{'))
72
+ cmRes = om.slice(1);
73
+ else if (om.endsWith('}'))
74
+ cmRes = om.slice(0, -1);
75
+ else if (om.startsWith('('))
76
+ cmRes = om.replace(/^\(.\d+\)/, '');
77
+ else if (om.endsWith(')'))
78
+ cmRes = om.replace(/\(\d+\)$/, '');
81
79
  return cmRes;
82
80
  }
83
81
 
84
82
  constructor(seqOList: SeqSplittedBase, gapOriginalMonomer: string) {
85
83
  super(seqOList, gapOriginalMonomer);
86
- this.seqCList = new Array<string | null>(this.length).fill(null);
87
84
  }
88
85
  }