@datagrok/helm 2.1.9 → 2.1.11

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/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@datagrok/helm",
3
3
  "friendlyName": "Helm",
4
- "version": "2.1.9",
4
+ "version": "2.1.11",
5
5
  "author": {
6
6
  "name": "Oleksandra Serhiienko",
7
7
  "email": "oserhiienko@datagrok.ai"
8
8
  },
9
9
  "description": "Provides support for HELM notation (importing, detecting, rendering, conversion).",
10
10
  "dependencies": {
11
- "@datagrok-libraries/bio": "^5.22.1",
11
+ "@datagrok-libraries/bio": "^5.32.3",
12
12
  "@datagrok-libraries/utils": "^1.19.1",
13
13
  "cash-dom": "^8.1.1",
14
14
  "datagrok-api": "^1.10.2",
@@ -6,6 +6,10 @@ import {findMonomers, parseHelm, getParts} from './utils';
6
6
  import {printLeftOrCentered} from '@datagrok-libraries/bio/src/utils/cell-renderer';
7
7
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
8
8
 
9
+ // Global flag is for replaceAll
10
+ const helmGapStartRe = /\{(\*\.)+/g;
11
+ const helmGapIntRe = /\.(\*\.)+/g;
12
+ const helmGapEndRe = /(\.\*)+\}/g;
9
13
 
10
14
  export class HelmCellRenderer extends DG.GridCellRenderer {
11
15
  get name() { return 'helm'; }
@@ -50,7 +54,7 @@ export class HelmCellRenderer extends DG.GridCellRenderer {
50
54
  for (let i = 0; i < allParts.length; ++i) {
51
55
  if (monomers.has(allParts[i])) {
52
56
  tooltipMessage[i] = ui.divV([
53
- ui.divText(`Monomer ${allParts[i]} not found.`),
57
+ ui.divText(`Monomer '${allParts[i]}' not found.`),
54
58
  ui.divText('Open the Context Panel, then expand Manage Libraries')
55
59
  ]);
56
60
  }
@@ -70,13 +74,15 @@ export class HelmCellRenderer extends DG.GridCellRenderer {
70
74
  const grid = gridCell.gridRow !== -1 ? gridCell.grid : undefined;
71
75
  const undefinedColor = 'rgb(100,100,100)';
72
76
  const grayColor = '#808080';
73
- const monomers = findMonomers(gridCell.cell.value);
74
- const s: string = gridCell.cell.value ?? '';
77
+
78
+ const s: string = !gridCell.cell.value ? '' : gridCell.cell.value
79
+ .replaceAll(helmGapStartRe, '{').replaceAll(helmGapIntRe, '.').replaceAll(helmGapEndRe, '}');
80
+ const monomers = findMonomers(s);
75
81
  const subParts: string[] = parseHelm(s);
76
82
  if (monomers.size == 0 && grid) {
77
83
  const host = ui.div([], {style: {width: `${w}px`, height: `${h}px`}});
78
84
  host.setAttribute('dataformat', 'helm');
79
- host.setAttribute('data', gridCell.cell.value);
85
+ host.setAttribute('data', s);
80
86
  gridCell.element = host;
81
87
  //@ts-ignore
82
88
  const canvas = new JSDraw2.Editor(host, {width: w, height: h, skin: 'w8', viewonly: true});
@@ -85,7 +91,7 @@ export class HelmCellRenderer extends DG.GridCellRenderer {
85
91
  if (!grid) {
86
92
  const r = window.devicePixelRatio;
87
93
  h = 28;
88
- g.canvas.height = h*r;
94
+ g.canvas.height = h * r;
89
95
  g.canvas.style.height = `${h}px`;
90
96
  }
91
97
  w = grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
package/src/package.ts CHANGED
@@ -10,7 +10,7 @@ import {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types';
10
10
  import {NotationConverter} from '@datagrok-libraries/bio/src/utils/notation-converter';
11
11
  import {findMonomers} from './utils';
12
12
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
13
- import { NOTATION } from '@datagrok-libraries/bio/src/utils/macromolecule';
13
+ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
14
14
 
15
15
  export const _package = new DG.Package();
16
16
  let monomerLib: IMonomerLib | null = null;
@@ -27,10 +27,10 @@ export async function initHelm(): Promise<void> {
27
27
  try {
28
28
  rewriteLibraries(); // initHelm()
29
29
 
30
- const monTypeList: string[] = monomerLib.getTypes();
30
+ const polymerTypeList: string[] = monomerLib.getPolymerTypes();
31
31
  const msgStr: string = 'Monomer lib updated:<br />' + (
32
- monTypeList.length == 0 ? 'empty' : monTypeList.map((monType) => {
33
- return `${monType} ${monomerLib.getMonomerNamesByType(monType).length}`;
32
+ polymerTypeList.length == 0 ? 'empty' : polymerTypeList.map((polymerType) => {
33
+ return `${polymerType} ${monomerLib.getMonomerSymbolsByType(polymerType).length}`;
34
34
  }).join('<br />'));
35
35
 
36
36
  grok.shell.info(msgStr);
@@ -45,13 +45,13 @@ export async function initHelm(): Promise<void> {
45
45
 
46
46
  function rewriteLibraries() {
47
47
  org.helm.webeditor.Monomers.clear();
48
- monomerLib.getTypes().forEach((type) => {
49
- const mms = monomerLib.getMonomerNamesByType(type);
50
- mms.forEach((symbol) => {
48
+ monomerLib.getPolymerTypes().forEach((polymerType) => {
49
+ const monomerSymbols = monomerLib.getMonomerSymbolsByType(polymerType);
50
+ monomerSymbols.forEach((monomerSymbol) => {
51
51
  let isBroken = false;
52
- const monomer: Monomer = monomerLib.getMonomer(type, symbol);
52
+ const monomer: Monomer = monomerLib.getMonomer(polymerType, monomerSymbol);
53
53
  const webEditorMonomer: WebEditorMonomer = {
54
- id: symbol,
54
+ id: monomerSymbol,
55
55
  m: monomer.molfile,
56
56
  n: monomer.name,
57
57
  na: monomer.naturalAnalog,
@@ -64,13 +64,13 @@ function rewriteLibraries() {
64
64
  if (monomer.rgroups.length > 0) {
65
65
  webEditorMonomer.rs = monomer.rgroups.length;
66
66
  const at = {};
67
- monomer.rgroups.forEach(it => {
67
+ monomer.rgroups.forEach((it) => {
68
68
  at[it[RGROUP_LABEL]] = it[RGROUP_CAP_GROUP_NAME];
69
69
  });
70
70
  webEditorMonomer.at = at;
71
- } else if (monomer.data[SMILES] != null) {
72
- webEditorMonomer.rs = Object.keys(getRS(monomer.data[SMILES].toString())).length;
73
- webEditorMonomer.at = getRS(monomer.data[SMILES].toString());
71
+ } else if (monomer[SMILES] != null) {
72
+ webEditorMonomer.rs = Object.keys(getRS(monomer[SMILES].toString())).length;
73
+ webEditorMonomer.at = getRS(monomer[SMILES].toString());
74
74
  } else {
75
75
  isBroken = true;
76
76
  }
@@ -81,7 +81,7 @@ function rewriteLibraries() {
81
81
  });
82
82
 
83
83
  // Obsolete
84
- let grid: DG.Grid = grok.shell.tv.grid;
84
+ const grid: DG.Grid = grok.shell.tv.grid;
85
85
  if (grid) grid.invalidate();
86
86
  }
87
87
 
@@ -97,16 +97,17 @@ export function helmCellRenderer(): HelmCellRenderer {
97
97
  function checkMonomersAndOpenWebEditor(cell?: DG.Cell, value?: string, units?: string) {
98
98
  const cellValue = typeof units === 'undefined' ? cell.value : value;
99
99
  const monomers = findMonomers(cellValue);
100
- if (monomers.size == 0)
100
+ if (monomers.size == 0) {
101
101
  webEditor(cell, value, units);
102
- else
102
+ } else {
103
103
  grok.shell.warning(`Monomers ${Array.from(monomers).join(', ')} are absent! <br/>` +
104
104
  `Please, upload the monomer library! <br/>` +
105
105
  `<a href="https://datagrok.ai/help/domains/bio/macromolecules" target="_blank">Learn more</a>`);
106
+ }
106
107
  }
107
108
 
108
109
  //tags: cellEditor
109
- //description: Macromolecule
110
+ //description: Macromolecule
110
111
  //input: grid_cell cell
111
112
  //meta.columnTags: quality=Macromolecule, units=helm
112
113
  export function editMoleculeCell(cell: DG.GridCell): void {
@@ -118,13 +119,13 @@ export function editMoleculeCell(cell: DG.GridCell): void {
118
119
  //meta.action: Open Helm Web Editor
119
120
  //input: string mol { semType: Macromolecule }
120
121
  export function openEditor(mol: string): void {
121
- let df = grok.shell.tv.grid.dataFrame;
122
- let col = df.columns.bySemType('Macromolecule');
122
+ const df = grok.shell.tv.grid.dataFrame;
123
+ const col = df.columns.bySemType('Macromolecule');
123
124
  const colUnits = col.getTag(DG.TAGS.UNITS);
124
- if (colUnits === NOTATION.HELM)
125
+ if (colUnits === NOTATION.HELM)
125
126
  checkMonomersAndOpenWebEditor(df.currentCell, undefined, undefined);
126
- let converter = new NotationConverter(col);
127
- const resStr = converter.convertStringToHelm(mol, '/');
127
+ const converter = new NotationConverter(col);
128
+ const resStr = converter.convertStringToHelm(mol, '/');
128
129
  checkMonomersAndOpenWebEditor(df.currentCell, resStr, col.getTag(DG.TAGS.UNITS));
129
130
  }
130
131
 
@@ -133,17 +134,17 @@ export function openEditor(mol: string): void {
133
134
  //input: string helmString {semType: Macromolecule}
134
135
  //output: widget result
135
136
  export async function propertiesPanel(helmString: string) {
136
- let grid = grok.shell.tv.grid;
137
- let parent = grid.root.parentElement;
137
+ const grid = grok.shell.tv.grid;
138
+ const parent = grid.root.parentElement;
138
139
  const host = ui.div([]);
139
140
  parent.appendChild(host);
140
- let editor = new JSDraw2.Editor(host, {viewonly: true});
141
+ const editor = new JSDraw2.Editor(host, {viewonly: true});
141
142
  host.style.width = '0px';
142
143
  host.style.height = '0px';
143
144
  editor.setHelm(helmString);
144
- let formula = editor.getFormula(true);
145
- let molWeight = Math.round(editor.getMolWeight() * 100) / 100;
146
- let coef = Math.round(editor.getExtinctionCoefficient(true) * 100) / 100;
145
+ const formula = editor.getFormula(true);
146
+ const molWeight = Math.round(editor.getMolWeight() * 100) / 100;
147
+ const coef = Math.round(editor.getExtinctionCoefficient(true) * 100) / 100;
147
148
  parent.lastChild.remove();
148
149
  return new DG.Widget(
149
150
  ui.tableFromMap({
@@ -155,11 +156,11 @@ export async function propertiesPanel(helmString: string) {
155
156
  }
156
157
 
157
158
  function webEditor(cell?: DG.Cell, value?: string, units?: string) {
158
- let view = ui.div();
159
- let df = grok.shell.tv.grid.dataFrame;
160
- let converter = new NotationConverter(df.columns.bySemType('Macromolecule'));
159
+ const view = ui.div();
160
+ const df = grok.shell.tv.grid.dataFrame;
161
+ const converter = new NotationConverter(df.columns.bySemType('Macromolecule'));
161
162
  org.helm.webeditor.MolViewer.molscale = 0.8;
162
- let app = new scil.helm.App(view, {
163
+ const app = new scil.helm.App(view, {
163
164
  showabout: false,
164
165
  mexfontsize: '90%',
165
166
  mexrnapinontab: true,
@@ -169,9 +170,9 @@ function webEditor(cell?: DG.Cell, value?: string, units?: string) {
169
170
  mexfavoritefirst: true,
170
171
  mexfilter: true
171
172
  });
172
- var sizes = app.calculateSizes();
173
+ const sizes = app.calculateSizes();
173
174
  app.canvas.resize(sizes.rightwidth - 100, sizes.topheight - 210);
174
- var s = {width: sizes.rightwidth - 100 + 'px', height: sizes.bottomheight + 'px'};
175
+ let s = {width: sizes.rightwidth - 100 + 'px', height: sizes.bottomheight + 'px'};
175
176
  //@ts-ignore
176
177
  scil.apply(app.sequence.style, s);
177
178
  //@ts-ignore
@@ -181,22 +182,22 @@ function webEditor(cell?: DG.Cell, value?: string, units?: string) {
181
182
  scil.apply(app.properties.parent.style, s);
182
183
  app.structureview.resize(sizes.rightwidth, sizes.bottomheight + app.toolbarheight);
183
184
  app.mex.resize(sizes.topheight - 80);
184
- setTimeout(function() {
185
- if (typeof units === 'undefined') {
185
+ setTimeout(() => {
186
+ if (typeof units === 'undefined')
186
187
  app.canvas.helm.setSequence(cell.value, 'HELM');
187
- } else {
188
+ else
188
189
  app.canvas.helm.setSequence(value, 'HELM');
189
- }
190
190
  }, 200);
191
191
  //@ts-ignore
192
192
  ui.dialog({showHeader: false, showFooter: true})
193
193
  .add(view)
194
194
  .onOK(() => {
195
- let helmValue = app.canvas.getHelm(true).replace(/<\/span>/g, '').replace(/<span style='background:#bbf;'>/g, '');
195
+ const helmValue = app.canvas.getHelm(true).replace(/<\/span>/g, '')
196
+ .replace(/<span style='background:#bbf;'>/g, '');
196
197
  if (typeof units === 'undefined') {
197
198
  cell.value = helmValue;
198
199
  } else {
199
- let convertedRes = converter.convertHelmToFastaSeparator(helmValue, units);
200
+ const convertedRes = converter.convertHelmToFastaSeparator(helmValue, units);
200
201
  cell.value = convertedRes;
201
202
  }
202
203
  }).show({modal: true, fullScreen: true});
@@ -226,19 +227,19 @@ function getRS(smiles: string) {
226
227
 
227
228
  //name: getMolfiles
228
229
  //input: column col {semType: Macromolecule}
229
- //output: column res
230
+ //output: column res
230
231
  export function getMolfiles(col: DG.Column): DG.Column {
231
- let grid = grok.shell.tv.grid;
232
- let parent = grid.root.parentElement;
233
- let res = DG.Column.string('mols', col.length);
232
+ const grid = grok.shell.tv.grid;
233
+ const parent = grid.root.parentElement;
234
+ const res = DG.Column.string('mols', col.length);
234
235
  const host = ui.div([]);
235
236
  parent.appendChild(host);
236
- let editor = new JSDraw2.Editor(host, {viewonly: true});
237
+ const editor = new JSDraw2.Editor(host, {viewonly: true});
237
238
  host.style.width = '0px';
238
239
  host.style.height = '0px';
239
240
  res.init((i) => {
240
241
  editor.setHelm(col.get(i));
241
- let mol = editor.getMolfile();
242
+ const mol = editor.getMolfile();
242
243
  return mol;
243
244
  });
244
245
  parent.lastChild.remove();