@datagrok/bio 2.16.8 → 2.17.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/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "Aleksandr Tanas",
6
6
  "email": "atanas@datagrok.ai"
7
7
  },
8
- "version": "2.16.8",
8
+ "version": "2.17.0",
9
9
  "description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
10
10
  "repository": {
11
11
  "type": "git",
@@ -37,7 +37,7 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@biowasm/aioli": "^3.1.0",
40
- "@datagrok-libraries/bio": "^5.45.6",
40
+ "@datagrok-libraries/bio": "^5.45.7",
41
41
  "@datagrok-libraries/chem-meta": "^1.2.7",
42
42
  "@datagrok-libraries/math": "^1.2.2",
43
43
  "@datagrok-libraries/ml": "^6.7.4",
package/src/package.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /* eslint-disable max-params */
2
+ /* eslint-disable max-len */
1
3
  /* eslint max-lines: "off" */
2
4
  import * as grok from 'datagrok-api/grok';
3
5
  import * as ui from 'datagrok-api/ui';
@@ -9,7 +11,7 @@ import {getActivityCliffs} from '@datagrok-libraries/ml/src/viewers/activity-cli
9
11
  import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
10
12
  import {BitArrayMetrics, KnownMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
11
13
  import {NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
- import {IMonomerLib, IMonomerLibBase, IMonomerSet} from '@datagrok-libraries/bio/src/types';
14
+ import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
13
15
  import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
14
16
  import {FastaFileHandler} from '@datagrok-libraries/bio/src/utils/fasta-handler';
15
17
  import {SCORE} from '@datagrok-libraries/bio/src/utils/macromolecule/scoring';
@@ -24,14 +26,13 @@ import {ITSNEOptions, IUMAPOptions} from '@datagrok-libraries/ml/src/multi-colum
24
26
  import {generateLongSequence, generateLongSequence2} from '@datagrok-libraries/bio/src/utils/generator';
25
27
  import {getUserLibSettings, setUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
26
28
  import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
27
- import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
29
+ import {RDModule as _RDMoule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
28
30
  import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
29
31
  import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
30
32
  import {MmcrTemps} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
31
33
 
32
34
  import {getMacromoleculeColumns} from './utils/ui-utils';
33
35
  import {MacromoleculeDifferenceCellRenderer, MacromoleculeSequenceCellRenderer,} from './utils/cell-renderer';
34
- import {MacromoleculeCustomCellRenderer} from './utils/cell-renderer-custom';
35
36
  import {VdRegionsViewer} from './viewers/vd-regions-viewer';
36
37
  import {SequenceAlignment} from './seq_align';
37
38
  import {getEncodedSeqSpaceCol} from './analysis/sequence-space';
@@ -102,52 +103,46 @@ let initBioPromise: Promise<void> | null = null;
102
103
 
103
104
  //tags: init
104
105
  export async function initBio(): Promise<void> {
105
- if (initBioPromise === null) {
106
+ if (initBioPromise === null)
106
107
  initBioPromise = initBioInt();
107
- }
108
+
108
109
  await initBioPromise;
109
110
  }
110
111
 
111
112
  async function initBioInt() {
112
113
  const logPrefix = 'Bio: _package.initBio()';
113
114
  _package.logger.debug(`${logPrefix}, start`);
114
- let monomerLib!: IMonomerLib;
115
- let monomerSets!: IMonomerSet;
116
- let rdKitModule!: RDModule;
117
- let libHelper!: MonomerLibManager;
118
115
  const t1: number = window.performance.now();
119
- await Promise.all([
120
- (async () => {
121
- libHelper = await MonomerLibManager.getInstance();
122
- // Fix user lib settings for explicit stuck from a terminated test
123
- const libSettings = await getUserLibSettings();
124
- if (libSettings.explicit) {
125
- libSettings.explicit = [];
126
- await setUserLibSettings(libSettings);
127
- }
128
- libHelper.awaitLoaded(Infinity).then(() => {
129
- // Do not wait for monomers and sets loaded
130
- return Promise.all([libHelper.loadMonomerLib(), libHelper.loadMonomerSets()]);
131
- });
132
- monomerLib = libHelper.getMonomerLib();
133
- monomerSets = libHelper.getMonomerSets();
134
- })(),
135
- (async () => {
136
- const pkgProps = await _package.getProperties();
137
- const bioPkgProps = new BioPackageProperties(pkgProps);
138
- _package.properties = bioPkgProps;
139
- })(),
140
- (async () => { rdKitModule = await getRdKitModule(); })(),
141
- ]).finally(() => {
142
- const t2: number = window.performance.now();
143
- _package.logger.debug(`${logPrefix}, loading ET: ${t2 - t1} ms`);
116
+ // very important that loading should happen in correct order!
117
+ // first make sure chem and rdkit module are loaded
118
+ const rdKitModule = await getRdKitModule();
119
+ // then load package settings
120
+ const pkgProps = await _package.getProperties();
121
+ const bioPkgProps = new BioPackageProperties(pkgProps);
122
+ _package.properties = bioPkgProps;
123
+ // then load monomer lib
124
+ const libHelper = await MonomerLibManager.getInstance();
125
+ // Fix user lib settings for explicit stuck from a terminated test
126
+ const libSettings = await getUserLibSettings();
127
+ if (libSettings.explicit) {
128
+ libSettings.explicit = [];
129
+ await setUserLibSettings(libSettings);
130
+ }
131
+ libHelper.awaitLoaded(Infinity).then(() => {
132
+ // Do not wait for monomers and sets loaded
133
+ return Promise.all([libHelper.loadMonomerLib(), libHelper.loadMonomerSets()]);
144
134
  });
145
- const seqHelper = new SeqHelper(libHelper, rdKitModule);
146
- _package.completeInit(seqHelper, monomerLib, monomerSets, rdKitModule);
135
+ const monomerLib = libHelper.getMonomerLib();
136
+ const monomerSets = libHelper.getMonomerSets();
137
+ // finally log
138
+ const t2: number = window.performance.now();
139
+ _package.logger.debug(`${logPrefix}, loading ET: ${t2 - t1} ms`);
147
140
 
148
141
  const monomers: string[] = [];
149
142
  const logPs: number[] = [];
150
143
 
144
+ const seqHelper = new SeqHelper(libHelper, rdKitModule);
145
+ _package.completeInit(seqHelper, monomerLib, monomerSets, rdKitModule);
151
146
  const series = monomerLib!.getMonomerMolsByPolymerType('PEPTIDE')!;
152
147
  Object.keys(series).forEach((symbol) => {
153
148
  monomers.push(symbol);
@@ -324,7 +319,7 @@ export function SeqActivityCliffsEditor(call: DG.FuncCall) {
324
319
  //meta.columnTags: quality=Macromolecule, units=custom
325
320
  //output: grid_cell_renderer result
326
321
  export function customSequenceCellRenderer(): DG.GridCellRenderer {
327
- return new MacromoleculeCustomCellRenderer();
322
+ return new MacromoleculeSequenceCellRenderer();
328
323
  }
329
324
 
330
325
  //name: fastaSequenceCellRenderer
@@ -770,7 +765,7 @@ export function convertDialog() {
770
765
  export async function convertSeqNotation(sequence: string, targetNotation: NOTATION, separator?: string): Promise<string | undefined | null> {
771
766
  try {
772
767
  const col = DG.Column.fromStrings('sequence', [sequence]);
773
- const df = DG.DataFrame.fromColumns([col]);
768
+ const _df = DG.DataFrame.fromColumns([col]);
774
769
  const semType = await grok.functions.call('Bio:detectMacromolecule', {col: col});
775
770
  if (semType)
776
771
  col.semType = semType;
@@ -1216,6 +1211,7 @@ export async function detectMacromoleculeProbe(file: DG.FileInfo, colName: strin
1216
1211
  //name: getSeqHelper
1217
1212
  //output: object result
1218
1213
  export async function getSeqHelper(): Promise<ISeqHelper> {
1214
+ await initBio();
1219
1215
  return _package.seqHelper;
1220
1216
  }
1221
1217
 
@@ -44,7 +44,7 @@ category('activityCliffs', async () => {
44
44
  test('activityCliffsOpens', async () => {
45
45
  const testData = !DG.Test.isInBenchmark ?
46
46
  {fileName: 'tests/100_3_clustests.csv', tgt: {cliffCount: 3}} :
47
- {fileName: 'tests/peptides_motif-with-random_10000.csv', tgt: {cliffCount: 53}};
47
+ {fileName: 'tests/peptides_with_random_motif_1600.csv', tgt: {cliffCount: 64}};
48
48
  const actCliffsDf = await readDataframe(testData.fileName);
49
49
  const actCliffsTableView = grok.shell.addTableView(actCliffsDf);
50
50
 
@@ -16,7 +16,7 @@ category('sequenceSpace', async () => {
16
16
  test('sequenceSpaceOpens', async () => {
17
17
  const testData = !DG.Test.isInBenchmark ?
18
18
  {fileName: 'tests/100_3_clustests.csv'} :
19
- {fileName: 'tests/peptides_motif-with-random_10000.csv'};
19
+ {fileName: 'tests/peptides_with_random_motif_1600.csv'};
20
20
  testFastaDf = await readDataframe(testData.fileName);
21
21
  testFastaTableView = grok.shell.addTableView(testFastaDf);
22
22
  await _testSequenceSpaceReturnsResult(testFastaDf, DimReductionMethods.UMAP, 'sequence');
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-len */
1
2
  import * as grok from 'datagrok-api/grok';
2
3
  import * as DG from 'datagrok-api/dg';
3
4
  import * as ui from 'datagrok-api/ui';
@@ -8,6 +9,7 @@ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
8
9
 
9
10
  import {_package} from '../package';
10
11
 
12
+ /// NB! UNUSED LEGACY CODE
11
13
  export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
12
14
  private readonly seqHelper: ISeqHelper;
13
15
 
@@ -41,7 +43,7 @@ export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
41
43
  back?.onMouseEnter(gridCell, e);
42
44
  }
43
45
 
44
- override onMouseLeave(gridCell: DG.GridCell, e: MouseEvent) {
46
+ override onMouseLeave(_gridCell: DG.GridCell, _e: MouseEvent) {
45
47
  // TODO: We get gridCell from another column here, so we can not get back object from the column rendered.
46
48
  ui.tooltip.hide();
47
49
  // const back = this.getRendererBack(gridCell);
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-len */
1
2
  /* eslint-disable max-lines */
2
3
  /* eslint-disable max-params */
3
4
  /* eslint-disable max-lines-per-function */
@@ -22,7 +23,7 @@ import {getSplitter} from '@datagrok-libraries/bio/src/utils/macromolecule/utils
22
23
  import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
23
24
  import {GapOriginals} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
24
25
  import {execMonomerHoverLinks} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
25
- import {getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
26
+ import {CellRendererBackBase, getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
26
27
  import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
27
28
  import {MmcrTemps, rendererSettingsChangedState, tempTAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
28
29
 
@@ -53,6 +54,7 @@ export function processSequence(subParts: string[]): [string[], boolean] {
53
54
  return [text, simplified];
54
55
  }
55
56
 
57
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
56
58
  type RendererGridCellTemp = {
57
59
  [MmcrTemps.monomerPlacer]: MonomerPlacer
58
60
  }
@@ -73,21 +75,58 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
73
75
  this.seqHelper = _package.seqHelper;
74
76
  }
75
77
 
76
- onClick(gridCell: DG.GridCell, _e: MouseEvent): void {
78
+ getRendererBack(gridCell: DG.GridCell): CellRendererBackBase<string> | null {
79
+ const [gridCol, tableCol, _temp] = getGridCellColTemp<string, any>(gridCell);
80
+ if (tableCol.meta.units !== NOTATION.CUSTOM)
81
+ return _temp.rendererBack;
82
+ let back: CellRendererBackBase<string> | null = null;
83
+
84
+ if (this.seqHelper) {
85
+ const sh = this.seqHelper.getSeqHandler(tableCol);
86
+ back = sh.getRendererBack(gridCol, tableCol);
87
+ }
88
+ return back;
89
+ }
90
+
91
+ override onClick(gridCell: DG.GridCell, _e: MouseEvent): void {
77
92
  const colTemp: TempType = gridCell.cell.column.temp;
78
93
  colTemp[tempTAGS.currentWord] = gridCell.cell.value;
79
94
  gridCell.grid.invalidate();
95
+ if (gridCell.cell.column.meta.units === NOTATION.CUSTOM) {
96
+ const back = this.getRendererBack(gridCell);
97
+ back?.onClick(gridCell, _e);
98
+ }
99
+ }
100
+
101
+ override onMouseEnter(gridCell: DG.GridCell, e: MouseEvent) {
102
+ const back = this.getRendererBack(gridCell);
103
+ back?.onMouseEnter(gridCell, e);
80
104
  }
81
105
 
82
106
  override onMouseMove(gridCell: DG.GridCell, e: MouseEvent): void {
83
- const [gridCol, tableCol, temp] = getGridCellColTemp<string, MonomerPlacer>(gridCell);
84
- temp.rendererBack?.onMouseMove(gridCell, e);
107
+ const back = this.getRendererBack(gridCell);
108
+ back?.onMouseMove(gridCell, e);
85
109
  }
86
110
 
87
- override onMouseLeave(gridCell: DG.GridCell, e: MouseEvent) {
111
+ override onMouseLeave(gridCell: DG.GridCell, _e: MouseEvent) {
88
112
  execMonomerHoverLinks(gridCell, null);
89
113
  }
90
114
 
115
+ override onDoubleClick(gridCell: DG.GridCell, e: MouseEvent) {
116
+ const back = this.getRendererBack(gridCell);
117
+ back?.onDoubleClick(gridCell, e);
118
+ }
119
+
120
+ override onKeyDown(gridCell: DG.GridCell, e: KeyboardEvent) {
121
+ const back = this.getRendererBack(gridCell);
122
+ back?.onKeyDown(gridCell, e);
123
+ }
124
+
125
+ override onKeyPress(gridCell: DG.GridCell, e: KeyboardEvent) {
126
+ const back = this.getRendererBack(gridCell);
127
+ back?.onKeyPress(gridCell, e);
128
+ }
129
+
91
130
  /**
92
131
  * Cell renderer function.
93
132
  *
@@ -99,11 +138,11 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
99
138
  * @param {DG.GridCell} gridCell Grid cell.
100
139
  * @param {DG.GridCellStyle} _cellStyle Cell style.
101
140
  */
102
- render(
141
+ renderInt(
103
142
  g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
104
143
  _cellStyle: DG.GridCellStyle
105
144
  ): void {
106
- const logPrefix: string = 'MacromoleculeSequenceCellRenderer.render()';
145
+ const _logPrefix: string = 'MacromoleculeSequenceCellRenderer.render()';
107
146
 
108
147
  const [gridCol, tableCol, temp] =
109
148
  getGridCellColTemp<string, MonomerPlacer>(gridCell);
@@ -111,7 +150,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
111
150
  const tableColTemp: TempType = tableCol.temp;
112
151
  const sh = this.seqHelper.getSeqHandler(tableCol);
113
152
 
114
- let gapLength = 0;
153
+ const gapLength = 0;
115
154
  const msaGapLength = 8;
116
155
 
117
156
  // Cell renderer settings
@@ -140,6 +179,15 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
140
179
 
141
180
  seqColTemp.render(g, x, y, w, h, gridCell, _cellStyle);
142
181
  }
182
+
183
+ override render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell, cellStyle: DG.GridCellStyle): void {
184
+ if (gridCell.cell.column?.meta?.units === NOTATION.CUSTOM) {
185
+ const back = this.getRendererBack(gridCell);
186
+ back?.render(g, x, y, w, h, gridCell, cellStyle);
187
+ return;
188
+ }
189
+ this.renderInt(g, x, y, w, h, gridCell, cellStyle);
190
+ }
143
191
  }
144
192
 
145
193
  export class MacromoleculeDifferenceCellRendererBack extends CellRendererWithMonomerLibBackBase {
@@ -151,7 +199,7 @@ export class MacromoleculeDifferenceCellRendererBack extends CellRendererWithMon
151
199
  }
152
200
 
153
201
  render(g: CanvasRenderingContext2D,
154
- x: number, y: number, w: number, h: number, gridCell: DG.GridCell, cellStyle: DG.GridCellStyle
202
+ x: number, y: number, w: number, h: number, gridCell: DG.GridCell, _cellStyle: DG.GridCellStyle
155
203
  ): void {
156
204
  const dpr = window.devicePixelRatio;
157
205
  const grid = gridCell.grid;
@@ -172,7 +220,7 @@ export class MacromoleculeDifferenceCellRendererBack extends CellRendererWithMon
172
220
  drawMoleculeDifferenceOnCanvas(g, x, y, w, h, subParts1, subParts2, biotype, this.monomerLib, undefined, undefined);
173
221
  }
174
222
 
175
- async awaitRendered(timeout: number = 10000, reason: string = `${timeout} timeout`): Promise<void> {
223
+ async awaitRendered(timeout: number = 10000, _reason: string = `${timeout} timeout`): Promise<void> {
176
224
  return Promise.resolve();
177
225
  }
178
226
 
@@ -258,15 +306,15 @@ export function drawMoleculeDifferenceOnCanvas(
258
306
  const amino2 = subParts2[i];
259
307
 
260
308
  let color1 = undefinedColor;
261
- if (monomerLib) {
309
+ if (monomerLib)
262
310
  color1 = monomerLib.getMonomerTextColor(biotype, amino1);
263
- }
311
+
264
312
 
265
313
  if (amino1 != amino2) {
266
314
  let color2 = undefinedColor;
267
- if (monomerLib) {
315
+ if (monomerLib)
268
316
  color2 = monomerLib.getMonomerTextColor(biotype, amino2);
269
- }
317
+
270
318
  const subX0 = printLeftOrCentered(g, amino1, updatedX, updatedY - vShift, w, h,
271
319
  {color: color1, pivot: 0, left: true});
272
320
  const subX1 = printLeftOrCentered(g, amino2, updatedX, updatedY + vShift, w, h,