@datagrok/bio 2.10.28 → 2.11.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": "Leonid Stolbov",
6
6
  "email": "lstolbov@datagrok.ai"
7
7
  },
8
- "version": "2.10.28",
8
+ "version": "2.11.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",
@@ -34,7 +34,7 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@biowasm/aioli": "^3.1.0",
37
- "@datagrok-libraries/bio": "^5.38.13",
37
+ "@datagrok-libraries/bio": "^5.39.0",
38
38
  "@datagrok-libraries/chem-meta": "^1.0.1",
39
39
  "@datagrok-libraries/ml": "^6.3.50",
40
40
  "@datagrok-libraries/tutorials": "^1.3.6",
@@ -4,7 +4,7 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import wu from 'wu';
6
6
 
7
- import {IWebLogoViewer} from '@datagrok-libraries/bio/src/viewers/web-logo';
7
+ import {IWebLogoViewer, WebLogoProps} from '@datagrok-libraries/bio/src/viewers/web-logo';
8
8
 
9
9
  import {PROPS as wlPROPS} from '../viewers/web-logo-viewer';
10
10
 
@@ -14,7 +14,11 @@ export class WebLogoApp {
14
14
  df: DG.DataFrame;
15
15
  view: DG.TableView;
16
16
 
17
- constructor(private readonly urlParams: URLSearchParams, private readonly funcName: string) {}
17
+ constructor(
18
+ private readonly urlParams: URLSearchParams,
19
+ private readonly funcName: string,
20
+ private readonly options: Partial<WebLogoProps> = {}
21
+ ) {}
18
22
 
19
23
  async init(df: DG.DataFrame): Promise<void> {
20
24
  this.df = df;
@@ -32,7 +36,7 @@ export class WebLogoApp {
32
36
  this.view = grok.shell.addTableView(this.df);
33
37
  this.view.path = this.view.basePath = `func/${_package.name}.${this.funcName}?${urlParamsTxt}`;
34
38
 
35
- const options: { [p: string]: any } = {sequenceColumnName: 'sequence'};
39
+ const options: { [p: string]: any } = {...this.options, ...{sequenceColumnName: 'sequence'}};
36
40
  for (const [optName, optValue] of this.urlParams.entries()) {
37
41
  switch (optName) {
38
42
  // boolean
package/src/package.ts CHANGED
@@ -65,7 +65,8 @@ import {PackageSettingsEditorWidget} from './widgets/package-settings-editor-wid
65
65
  import {getCompositionAnalysisWidget} from './widgets/composition-analysis-widget';
66
66
  import {MacromoleculeColumnWidget} from './utils/macromolecule-column-widget';
67
67
  import {addCopyMenuUI} from './utils/context-menu';
68
- import {_getEnumeratorWidget, _setPeptideColumn} from './utils/enumerator-tools';
68
+ import {getPolyToolDialog} from './utils/poly-tool/enumerator-tools';
69
+ import {_setPeptideColumn} from './utils/poly-tool/utils';
69
70
  import {getRegionDo} from './utils/get-region';
70
71
  import {GetRegionApp} from './apps/get-region-app';
71
72
  import {GetRegionFuncEditor} from './utils/get-region-func-editor';
@@ -763,6 +764,19 @@ export function convertDialog() {
763
764
  convert(col);
764
765
  }
765
766
 
767
+ //top-menu: Bio | Convert | PolyTool
768
+ //name: polyTool
769
+ //description: Perform cyclization of polymers
770
+ export function polyTool(): void {
771
+ let dialog: DG.Dialog;
772
+ try {
773
+ dialog = getPolyToolDialog();
774
+ dialog.show();
775
+ } catch (err: any) {
776
+ grok.shell.warning('To run PolyTool, open a dataframe with macromolecules');
777
+ }
778
+ }
779
+
766
780
  //name: monomerCellRenderer
767
781
  //tags: cellRenderer
768
782
  //meta.cellType: Monomer
@@ -962,6 +976,20 @@ export async function webLogoLargeApp(): Promise<void> {
962
976
  }
963
977
  }
964
978
 
979
+ //name: webLogoAggApp
980
+ export async function webLogoAggApp(): Promise<void> {
981
+ const pi = DG.TaskBarProgressIndicator.create('WebLogo ...');
982
+ try {
983
+ const urlParams = new URLSearchParams(window.location.search);
984
+ const app = new WebLogoApp(urlParams, 'webLogoAggApp');
985
+ const df: DG.DataFrame = await _package.files.readCsv('data/sample_FASTA_PT_activity.csv');
986
+ await grok.data.detectSemanticTypes(df);
987
+ await app.init(df);
988
+ } finally {
989
+ pi.close();
990
+ }
991
+ }
992
+
965
993
  //name: getRegionApp
966
994
  export async function getRegionApp(): Promise<void> {
967
995
  const pi = DG.TaskBarProgressIndicator.create('getRegion ...');
@@ -1056,15 +1084,6 @@ export async function enumeratorColumnChoice(df: DG.DataFrame, macroMolecule: DG
1056
1084
  await grok.data.detectSemanticTypes(df);
1057
1085
  }
1058
1086
 
1059
- //name: PolyTool
1060
- //input: column molColumn {semType: Macromolecule}
1061
- //tags: panel, exclude-actions-panel
1062
- //output: widget result
1063
- export function getEnumeratorWidget(molColumn: DG.Column): DG.Widget {
1064
- return _getEnumeratorWidget(molColumn);
1065
- }
1066
-
1067
-
1068
1087
  //top-menu: Bio | Convert | SDF to JSON Library...
1069
1088
  //name: SDF to JSON Library
1070
1089
  //input: dataframe table
@@ -55,7 +55,7 @@ ATC-G-TTGC--
55
55
  for (let i = 0; i < positions.length; i++) {
56
56
  expect(positions[i].name, resAllDf1[i].name);
57
57
  for (const m of positions[i].getMonomers())
58
- expect(positions[i].getFreq(m).count, resAllDf1[i].getFreq(m).count);
58
+ expect(positions[i].getFreq(m).rowCount, resAllDf1[i].getFreq(m).rowCount);
59
59
  }
60
60
  });
61
61
 
@@ -104,7 +104,7 @@ ATC-G-TTGC--
104
104
  for (let i = 0; i < positions.length; i++) {
105
105
  expect(positions[i].name, resAllDf1[i].name);
106
106
  for (const m of positions[i].getMonomers())
107
- expect(positions[i].getFreq(m).count, resAllDf1[i].getFreq(m).count);
107
+ expect(positions[i].getFreq(m).rowCount, resAllDf1[i].getFreq(m).rowCount);
108
108
  }
109
109
  });
110
110
 
@@ -204,7 +204,7 @@ function expectPositionInfo(actualPos: PI, expectedPos: PI): void {
204
204
  expectArray(actualPos.getMonomers(), expectedPos.getMonomers());
205
205
  for (const key of actualPos.getMonomers()) {
206
206
  //
207
- expect(actualPos.getFreq(key).count, expectedPos.getFreq(key).count);
207
+ expect(actualPos.getFreq(key).rowCount, expectedPos.getFreq(key).rowCount);
208
208
  }
209
209
  }
210
210
 
@@ -0,0 +1,29 @@
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
+ export type AggValueListType = (number | null)[] | Float32Array | Int32Array;
6
+ export type AggFunc = (valueList: AggValueListType) => number | null;
7
+
8
+ export function getAgg(agg: DG.AggregationType): AggFunc {
9
+ let res: AggFunc;
10
+
11
+ function buildCol(valueList: AggValueListType): DG.Column<number> {
12
+ let resCol: DG.Column<number>;
13
+ const resColName = `agg`;
14
+ if (valueList instanceof Float32Array)
15
+ resCol = DG.Column.fromFloat32Array(resColName, valueList as Float32Array);
16
+ else if (valueList instanceof Int32Array)
17
+ resCol = DG.Column.fromInt32Array(resColName, valueList as Int32Array);
18
+ else
19
+ resCol = DG.Column.fromList(DG.COLUMN_TYPE.FLOAT, resColName, valueList as (number | null)[]);
20
+
21
+ return resCol;
22
+ }
23
+
24
+ return (valueList: AggValueListType): number | null => {
25
+ const aggCol = buildCol(valueList);
26
+ const res = aggCol.aggregate(agg);
27
+ return res;
28
+ };
29
+ }
@@ -0,0 +1,16 @@
1
+ export const enum HELM_WRAPPER {
2
+ LEFT = 'PEPTIDE1{',
3
+ RIGHT = '}$$$$',
4
+ }
5
+ export const ALL_MONOMERS = '<All>';
6
+
7
+ export const enum TRANSFORMATION_TYPE {
8
+ CYCLIZATION = 'Cyclization',
9
+ }
10
+
11
+ export const enum CYCLIZATION_TYPE {
12
+ NO = 'N-O',
13
+ NCys = 'N-Cys',
14
+ R3 = 'R3-R3',
15
+ }
16
+
@@ -3,51 +3,15 @@ import * as grok from 'datagrok-api/grok';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
  import * as DG from 'datagrok-api/dg';
5
5
 
6
- import {NOTATION, ALIGNMENT, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
6
+ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
7
7
  import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
8
8
  import {HELM_POLYMER_TYPE} from '@datagrok-libraries/bio/src/utils/const';
9
- import {MonomerLibHelper} from '../utils/monomer-lib';
10
- import {_package} from '../package';
9
+ import {MonomerLibHelper} from '../../utils/monomer-lib';
10
+ import {_package} from '../../package';
11
+ import {addCommonTags} from './utils';
11
12
  import * as rxjs from 'rxjs';
12
-
13
- const LEFT_HELM_WRAPPER = 'PEPTIDE1{';
14
- const RIGHT_HELM_WRAPPER = '}$$$$';
15
- const ALL_MONOMERS = '<All>';
16
-
17
- type MetaData = {
18
- leftTerminal: string,
19
- rightTerminal: string,
20
- transformationType: TRANSFORMATION_TYPE,
21
- cyclizationType: CYCLIZATION_TYPE,
22
- }
23
-
24
- type ConnectionData = {
25
- monomerPosition: number,
26
- attachmentPoint: number,
27
- }
28
-
29
- const enum TRANSFORMATION_TYPE {
30
- CYCLIZATION = 'Cyclization',
31
- }
32
-
33
- const enum CYCLIZATION_TYPE {
34
- NO = 'N-O',
35
- NCys = 'N-Cys',
36
- R3 = 'R3-R3',
37
- }
38
-
39
- function addCommonTags(col: DG.Column):void {
40
- col.setTag('quality', DG.SEMTYPE.MACROMOLECULE);
41
- col.setTag('aligned', ALIGNMENT.SEQ);
42
- col.setTag('alphabet', ALPHABET.PT);
43
- }
44
-
45
- export function _setPeptideColumn(col: DG.Column): void {
46
- addCommonTags(col);
47
- col.setTag('units', NOTATION.SEPARATOR);
48
- col.setTag('separator', '-');
49
- // col.setTag('cell.renderer', 'sequence');
50
- }
13
+ import {HELM_WRAPPER, ALL_MONOMERS, CYCLIZATION_TYPE, TRANSFORMATION_TYPE} from './const';
14
+ import {MetaData, ConnectionData} from './types';
51
15
 
52
16
  abstract class TransformationBase {
53
17
  constructor(helmColumn: DG.Column<string>, meta: MetaData) {
@@ -80,11 +44,11 @@ class TransformationNCys extends TransformationBase {
80
44
  }
81
45
 
82
46
  protected hasTerminals(helm: string): boolean {
83
- if (! helm.includes(this.rightTerminal + RIGHT_HELM_WRAPPER))
47
+ if (! helm.includes(this.rightTerminal + HELM_WRAPPER.RIGHT))
84
48
  return false;
85
49
  if (this.leftTerminal === ALL_MONOMERS)
86
50
  return true;
87
- return helm.includes(LEFT_HELM_WRAPPER + this.leftTerminal);
51
+ return helm.includes(HELM_WRAPPER.LEFT + this.leftTerminal);
88
52
  }
89
53
 
90
54
  protected getLinkedPositions(helm: string): [number, number] {
@@ -107,8 +71,8 @@ class TransformationNO extends TransformationBase {
107
71
  protected hasTerminals(helm: string): boolean {
108
72
  if (this.leftTerminal === ALL_MONOMERS || this.rightTerminal === ALL_MONOMERS)
109
73
  return true;
110
- return helm.includes(LEFT_HELM_WRAPPER + this.leftTerminal) &&
111
- helm.includes(this.rightTerminal + RIGHT_HELM_WRAPPER);
74
+ return helm.includes(HELM_WRAPPER.LEFT + this.leftTerminal) &&
75
+ helm.includes(this.rightTerminal + HELM_WRAPPER.RIGHT);
112
76
  }
113
77
 
114
78
  protected getLinkedPositions(helm: string): [number, number] {
@@ -136,7 +100,7 @@ class TransformationR3 extends TransformationBase {
136
100
  }
137
101
 
138
102
  protected getLinkedPositions(helm: string): [number, number] {
139
- const seq = helm.replace(LEFT_HELM_WRAPPER, '').replace(RIGHT_HELM_WRAPPER, '');
103
+ const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
140
104
  const monomers = seq.split('.');
141
105
  const start = monomers.findIndex((el) => el === this.leftTerminal);
142
106
  const end = monomers.findIndex((el, idx) => el === this.rightTerminal && idx > start);
@@ -163,12 +127,12 @@ class PolymerTransformation {
163
127
  }
164
128
 
165
129
  function getNumberOfMonomers(helm: string): number {
166
- const seq = helm.replace(LEFT_HELM_WRAPPER, '').replace(RIGHT_HELM_WRAPPER, '');
130
+ const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
167
131
  return seq.split('.').length;
168
132
  }
169
133
 
170
134
  function getHelmCycle(helm: string, source: ConnectionData, target: ConnectionData): string {
171
- return helm.replace(RIGHT_HELM_WRAPPER,
135
+ return helm.replace(HELM_WRAPPER.RIGHT,
172
136
  `}$PEPTIDE1,PEPTIDE1,${
173
137
  source.monomerPosition
174
138
  }:R${
@@ -200,7 +164,7 @@ async function addTransformedColumn(
200
164
  await grok.data.detectSemanticTypes(df);
201
165
  }
202
166
 
203
- export function _getEnumeratorWidget(molColumn: DG.Column): DG.Widget {
167
+ export function getPolyToolDialog(): DG.Dialog {
204
168
  function getMonomerList(cyclizationType: CYCLIZATION_TYPE): string[] {
205
169
  if (cyclizationType === cyclizationTypes[0]) {
206
170
  return [ALL_MONOMERS].concat(
@@ -280,16 +244,34 @@ export function _getEnumeratorWidget(molColumn: DG.Column): DG.Widget {
280
244
 
281
245
  updateMeta();
282
246
 
283
- const btn = ui.bigButton('Run', async () =>
284
- addTransformedColumn(molColumn, meta)
247
+ const targetColumns = grok.shell.t.columns.bySemTypeAll(DG.SEMTYPE.MACROMOLECULE);
248
+ if (!targetColumns)
249
+ throw new Error('No dataframe with maceomolecule columns open');
250
+
251
+
252
+ const targetColumnInput = ui.columnInput(
253
+ 'Column', grok.shell.t, targetColumns[0], null,
254
+ {filter: (col: DG.Column) => col.semType === DG.SEMTYPE.MACROMOLECULE}
285
255
  );
286
256
 
287
257
  const div = ui.div([
258
+ targetColumnInput,
288
259
  transformationChoice,
289
260
  cyclizationTypeChoice,
290
261
  terminalControls,
291
- btn
292
262
  ]);
293
263
 
294
- return new DG.Widget(div);
264
+ const dialog = ui.dialog('Poly Tool')
265
+ .add(div)
266
+ .onOK(async () => {
267
+ const molCol = targetColumnInput.value;
268
+ if (!molCol) {
269
+ grok.shell.warning('No marcomolecule column chosen!');
270
+ return;
271
+ }
272
+ addTransformedColumn(molCol!, meta);
273
+ }
274
+ );
275
+
276
+ return dialog;
295
277
  }
@@ -0,0 +1,14 @@
1
+ import {TRANSFORMATION_TYPE, CYCLIZATION_TYPE} from './const';
2
+
3
+ export type MetaData = {
4
+ leftTerminal: string,
5
+ rightTerminal: string,
6
+ transformationType: TRANSFORMATION_TYPE,
7
+ cyclizationType: CYCLIZATION_TYPE,
8
+ }
9
+
10
+ export type ConnectionData = {
11
+ monomerPosition: number,
12
+ attachmentPoint: number,
13
+ }
14
+
@@ -0,0 +1,20 @@
1
+ /* Do not change these import lines to match external modules in webpack configuration */
2
+ import * as grok from 'datagrok-api/grok';
3
+ import * as ui from 'datagrok-api/ui';
4
+ import * as DG from 'datagrok-api/dg';
5
+
6
+ import {NOTATION, ALIGNMENT, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
7
+
8
+ export function addCommonTags(col: DG.Column):void {
9
+ col.setTag('quality', DG.SEMTYPE.MACROMOLECULE);
10
+ col.setTag('aligned', ALIGNMENT.SEQ);
11
+ col.setTag('alphabet', ALPHABET.PT);
12
+ }
13
+
14
+ export function _setPeptideColumn(col: DG.Column): void {
15
+ addCommonTags(col);
16
+ col.setTag('units', NOTATION.SEPARATOR);
17
+ col.setTag('separator', '-');
18
+ // col.setTag('cell.renderer', 'sequence');
19
+ }
20
+