@datagrok/sequence-translator 1.10.18 → 1.10.20

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.
@@ -0,0 +1,5 @@
1
+ Core
2
+ n1nc([*:3])n([*:2])c1[*:1]
3
+ C1C2CN([*:2])CC2CN1[*:1]
4
+ OC1CN([*:2])CCC1N[*:1]
5
+ CC1(N[*:1])CCN([*:2])C1
@@ -0,0 +1,5 @@
1
+ R1,R2,R3
2
+ CC1CCN([*:1])C1C,O=C(C[*:2])NCC(F)(F)F,Cc1cccc([*:3])n1
3
+ NCCC(=O)[*:1],O=C1NC(C(=O)[*:2])CO1,
4
+ CC(=O)[*:1],O=C(CCCF)[*:2],
5
+ O=C(c1cc[nH]n1)[*:1],c1ccc(C[*:2])nc1,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/sequence-translator",
3
3
  "friendlyName": "Sequence Translator",
4
- "version": "1.10.18",
4
+ "version": "1.10.20",
5
5
  "author": {
6
6
  "name": "Davit Rizhinashvili",
7
7
  "email": "drizhinashvili@datagrok.ai"
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-params */
1
2
  /**
2
3
  * Canvas drawing for the OligoNucleotide cell renderer.
3
4
  *
@@ -41,7 +42,7 @@ export interface RenderOpts {
41
42
  scheme?: string;
42
43
  }
43
44
 
44
- const DEFAULT_OPTS: RenderOpts = {showLetters: true, pairAlign: true};
45
+ export const DEFAULT_OPTS: RenderOpts = {showLetters: true, pairAlign: true};
45
46
 
46
47
  /* Visual tuning. */
47
48
  const ASPECT_H_OVER_W = 1.25;
@@ -329,11 +330,11 @@ function fitsInBudget(widths: number[], leadW: number, chipGap: number, budget:
329
330
  export function drawDuplex(
330
331
  g: CanvasRenderingContext2D, cellX: number, cellY: number,
331
332
  cellW: number, cellH: number, model: ParsedDuplex,
332
- opts: Partial<RenderOpts> = {},
333
+ opts: Partial<RenderOpts> = {}, skipDrawing = false,
333
334
  ): DuplexLayout {
334
335
  const o: RenderOpts = {...DEFAULT_OPTS, ...opts};
335
336
  const layout = computeLayout(cellW, cellH, model, o);
336
-
337
+ if (skipDrawing) return layout;
337
338
  g.save();
338
339
  g.beginPath();
339
340
  g.rect(cellX, cellY, cellW, cellH);
@@ -14,7 +14,7 @@
14
14
  import * as DG from 'datagrok-api/dg';
15
15
  import * as ui from 'datagrok-api/ui';
16
16
 
17
- import {drawDuplex, hitTest, DuplexLayout} from './canvas-renderer';
17
+ import {drawDuplex, hitTest, DuplexLayout, RenderOpts, DEFAULT_OPTS} from './canvas-renderer';
18
18
  import {looksLikeHelm, parseHelmDuplex} from './helm-parser';
19
19
  import {ParsedDuplex} from './types';
20
20
  import {showMonomerTooltip} from './tooltip';
@@ -23,9 +23,9 @@ const CELL_TYPE = 'OligoNucleotide';
23
23
 
24
24
  export class OligoNucleotideCellRenderer extends DG.GridCellRenderer {
25
25
  /** WeakMap-by-value cache of parsed HELM. Avoids reparsing on redraw. */
26
- private modelCache = new Map<string, ParsedDuplex>();
26
+ private modelCache = new DG.LruCache<string, ParsedDuplex>();
27
27
  /** Last-rendered layout per cell key, for hit-testing on subsequent moves. */
28
- private layoutCache = new Map<string, DuplexLayout>();
28
+ private layoutCache = new DG.LruCache<string, DuplexLayout>();
29
29
 
30
30
  get name(): string { return CELL_TYPE; }
31
31
  get cellType(): string { return CELL_TYPE; }
@@ -54,11 +54,16 @@ export class OligoNucleotideCellRenderer extends DG.GridCellRenderer {
54
54
  }
55
55
 
56
56
  const model = this.getOrParse(value);
57
+ if (!gridCell.cell?.dart || !gridCell.cell.column) {
58
+ w = g.canvas.width;
59
+ h = g.canvas.height;
60
+ x = 0;
61
+ y = 0;
62
+ // this happens in forms....
63
+ }
57
64
  const layout = drawDuplex(g, x, y, w, h, model);
58
65
  // Cache for hit-test on subsequent mouse moves over the same cell.
59
- this.layoutCache.set(this.cellKey(gridCell), layout);
60
- // Avoid unbounded growth on big tables.
61
- if (this.layoutCache.size > 5000) this.layoutCache.clear();
66
+ this.layoutCache.set(this.cellKey(value, w, h, DEFAULT_OPTS), layout);
62
67
  }
63
68
 
64
69
  override onMouseMove(gridCell: DG.GridCell, e: MouseEvent): void {
@@ -68,7 +73,11 @@ export class OligoNucleotideCellRenderer extends DG.GridCellRenderer {
68
73
  return;
69
74
  }
70
75
  const model = this.getOrParse(value);
71
- const layout = this.layoutCache.get(this.cellKey(gridCell));
76
+ const layout = this.layoutCache.getOrCreate(
77
+ this.cellKey(value, gridCell.bounds.width, gridCell.bounds.height, DEFAULT_OPTS), (v) => drawDuplex(
78
+ null as unknown as CanvasRenderingContext2D, 0, 0, gridCell.bounds.width, gridCell.bounds.height,
79
+ model, DEFAULT_OPTS, true,
80
+ ));
72
81
  if (!layout) return;
73
82
 
74
83
  const bounds = gridCell.bounds;
@@ -88,24 +97,14 @@ export class OligoNucleotideCellRenderer extends DG.GridCellRenderer {
88
97
  }
89
98
 
90
99
  private getOrParse(helm: string): ParsedDuplex {
91
- let m = this.modelCache.get(helm);
92
- if (!m) {
93
- m = parseHelmDuplex(helm);
94
- // Cap cache to avoid unbounded growth on huge tables.
95
- if (this.modelCache.size > 5000) this.modelCache.clear();
96
- this.modelCache.set(helm, m);
97
- }
98
- return m;
100
+ return this.modelCache.getOrCreate(helm, (h) => parseHelmDuplex(h));
99
101
  }
100
102
 
101
103
  /** Cache key for a cell's layout. Includes the column's `version` so any
102
104
  * edit to the column (which bumps version) orphans previous cache entries
103
105
  * — preventing onMouseMove from hit-testing a stale layout that was cached
104
106
  * before the edit and not yet replaced by a fresh render(). */
105
- private cellKey(gridCell: DG.GridCell): string {
106
- const col = gridCell.tableColumn;
107
- const colName = col?.name ?? gridCell.gridColumn?.name ?? '?';
108
- const ver = col?.version ?? 0;
109
- return `${colName}@${ver}::${gridCell.tableRowIndex ?? -1}`;
107
+ private cellKey(value: string, width: number, height: number, opts: RenderOpts): string {
108
+ return `${value}::${Math.floor(width)}x${Math.floor(height)}::${JSON.stringify(opts)}`;
110
109
  }
111
110
  }
@@ -95,18 +95,11 @@ export namespace funcs {
95
95
  return await grok.functions.call('SequenceTranslator:PolyToolEnumerateHelmTopMenu', {});
96
96
  }
97
97
 
98
- /**
99
- Perform enumeration of a molecule using different fragments at specified positions
100
- */
101
- export async function polyToolEnumerateChemTopMenu(): Promise<void> {
102
- return await grok.functions.call('SequenceTranslator:PolyToolEnumerateChemTopMenu', {});
103
- }
104
-
105
98
  /**
106
99
  Enumerate cores and R-group lists into a molecule table (Zip or Cartesian)
107
100
  */
108
- export async function chemEnumerateReactionsTopMenu(): Promise<void> {
109
- return await grok.functions.call('SequenceTranslator:ChemEnumerateReactionsTopMenu', {});
101
+ export async function chemEnumerateMarkushTopMenu(): Promise<void> {
102
+ return await grok.functions.call('SequenceTranslator:ChemEnumerateMarkushTopMenu', {});
110
103
  }
111
104
 
112
105
  export async function polyToolColumnChoice(df: DG.DataFrame , macroMolecule: DG.Column ): Promise<void> {
package/src/package.g.ts CHANGED
@@ -141,18 +141,11 @@ export async function polyToolEnumerateHelmTopMenu() : Promise<void> {
141
141
  await PackageFunctions.polyToolEnumerateHelmTopMenu();
142
142
  }
143
143
 
144
- //name: polyToolEnumerateChem
145
- //description: Perform enumeration of a molecule using different fragments at specified positions
146
- //top-menu: Bio | PolyTool | Enumerate Chem...
147
- export async function polyToolEnumerateChemTopMenu() : Promise<void> {
148
- await PackageFunctions.polyToolEnumerateChemTopMenu();
149
- }
150
-
151
- //name: chemEnumerateReactions
144
+ //name: Markush Enumerator
152
145
  //description: Enumerate cores and R-group lists into a molecule table (Zip or Cartesian)
153
- //top-menu: Chem | Transform | Reactions | Enumerate...
154
- export async function chemEnumerateReactionsTopMenu() : Promise<void> {
155
- await PackageFunctions.chemEnumerateReactionsTopMenu();
146
+ //top-menu: Chem | Transform | Markush Enumeration...
147
+ export async function chemEnumerateMarkushTopMenu() : Promise<void> {
148
+ await PackageFunctions.chemEnumerateMarkushTopMenu();
156
149
  }
157
150
 
158
151
  //input: dataframe df { description: Input data table }
@@ -175,11 +168,11 @@ export async function ptEnumeratorHelmApp() : Promise<void> {
175
168
  await PackageFunctions.ptEnumeratorHelmApp();
176
169
  }
177
170
 
178
- //name: Chem Enumerator
171
+ //name: Markush Enumerator
179
172
  //tags: app
180
173
  //output: view result
181
174
  //meta.icon: img/icons/structure.png
182
- //meta.browsePath: Chem | PolyTool
175
+ //meta.browsePath: Chem
183
176
  //meta.role: app
184
177
  export async function ptEnumeratorChemApp() {
185
178
  return await PackageFunctions.ptEnumeratorChemApp();
package/src/package.ts CHANGED
@@ -274,22 +274,15 @@ export class PackageFunctions {
274
274
 
275
275
 
276
276
  @grok.decorators.func({
277
- 'top-menu': 'Bio | PolyTool | Enumerate Chem...',
278
- 'name': 'polyToolEnumerateChem',
279
- 'description': 'Perform enumeration of a molecule using different fragments at specified positions'
280
- })
281
- static async polyToolEnumerateChemTopMenu(): Promise<void> {
282
- polyToolEnumerateChemUI();
283
- }
284
-
285
-
286
- @grok.decorators.func({
287
- 'top-menu': 'Chem | Transform | Reactions | Enumerate...',
288
- 'name': 'chemEnumerateReactions',
277
+ 'top-menu': 'Chem | Transform | Markush Enumeration...',
278
+ 'name': 'Markush Enumerator',
289
279
  'description': 'Enumerate cores and R-group lists into a molecule table (Zip or Cartesian)'
290
280
  })
291
- static async chemEnumerateReactionsTopMenu(): Promise<void> {
292
- polyToolEnumerateChemUI();
281
+ static async chemEnumerateMarkushTopMenu(): Promise<void> {
282
+ let cell: DG.Cell | undefined = undefined;
283
+ if (grok.shell.tv?.dataFrame && grok.shell.tv.dataFrame.currentCell && grok.shell.tv.dataFrame.currentCell.column.semType === DG.SEMTYPE.MOLECULE)
284
+ cell = grok.shell.tv.dataFrame.currentCell;
285
+ polyToolEnumerateChemUI(cell);
293
286
  }
294
287
 
295
288
 
@@ -331,10 +324,10 @@ export class PackageFunctions {
331
324
  @grok.decorators.func({
332
325
  meta: {
333
326
  icon: 'img/icons/structure.png',
334
- browsePath: 'Chem | PolyTool',
327
+ browsePath: 'Chem',
335
328
  role: 'app'
336
329
  },
337
- name: 'Chem Enumerator',
330
+ name: 'Markush Enumerator',
338
331
  tags: ['app'],
339
332
  outputs: [{type: 'view', name: 'result'}]
340
333
  })