@datagrok/bio 2.11.35 → 2.11.37

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.11.35",
8
+ "version": "2.11.37",
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",
@@ -40,7 +40,7 @@ export class SequenceDiversityViewer extends SequenceSearchBaseViewer {
40
40
  this.tags.forEach((tag) => resCol.setTag(tag, this.moleculeColumn!.getTag(tag)));
41
41
  const resDf = DG.DataFrame.fromColumns([resCol]);
42
42
  resDf.onCurrentRowChanged.subscribe(
43
- (_) => { this.dataFrame.currentRowIdx = this.renderMolIds![resDf.currentRowIdx]; });
43
+ (_: any) => { this.dataFrame.currentRowIdx = this.renderMolIds![resDf.currentRowIdx]; });
44
44
  updateDivInnerHTML(this.root, resDf.plot.grid().root);
45
45
  this.computeCompleted.next(true);
46
46
  }
@@ -61,7 +61,7 @@ export class SequenceDiversityViewer extends SequenceSearchBaseViewer {
61
61
 
62
62
  private async computeByMM() {
63
63
  const encodedSequences =
64
- (await getEncodedSeqSpaceCol(this.moleculeColumn!, MmDistanceFunctionsNames.LEVENSHTEIN)).seqList;
64
+ (await getEncodedSeqSpaceCol(this.moleculeColumn!, MmDistanceFunctionsNames.LEVENSHTEIN)).seqList;
65
65
  const distanceMatrixService = new DistanceMatrixService(true, false);
66
66
  const distanceMatrixData = await distanceMatrixService.calc(encodedSequences, MmDistanceFunctionsNames.LEVENSHTEIN);
67
67
  distanceMatrixService.terminate();
@@ -60,7 +60,7 @@ export class SequenceSimilarityViewer extends SequenceSearchBaseViewer {
60
60
  this.molCol.semType = DG.SEMTYPE.MACROMOLECULE;
61
61
  this.tags.forEach((tag) => this.molCol!.setTag(tag, this.moleculeColumn!.getTag(tag)));
62
62
  const resDf = DG.DataFrame.fromColumns([this.idxs!, this.molCol!, this.scores!]);
63
- resDf.onCurrentRowChanged.subscribe((_) => {
63
+ resDf.onCurrentRowChanged.subscribe((_: any) => {
64
64
  this.dataFrame.currentRowIdx = resDf.col('indexes')!.get(resDf.currentRowIdx);
65
65
  setTimeout(() => { this.createPropertyPanel(resDf); }, 1000);
66
66
  this.gridSelect = true;
@@ -81,12 +81,12 @@ MWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHP
81
81
  test('isCorrectHelm', async () => {
82
82
  await awaitContainerStart();
83
83
  await _testMSAOnColumn(helmFromCsv, helmToCsv, NOTATION.HELM, NOTATION.SEPARATOR, undefined, 'mafft');
84
- }, {timeout: 60000});
84
+ }, {timeout: 60000 /* docker */});
85
85
 
86
86
  test('isCorrectHelmLong', async () => {
87
87
  await awaitContainerStart();
88
88
  await _testMSAOnColumn(longHelmFromCsv, longHelmToCsv, NOTATION.HELM, NOTATION.SEPARATOR, undefined, 'mafft');
89
- }, {timeout: 60000});
89
+ }, {timeout: 60000 /* docker */});
90
90
 
91
91
  test('isCorrectSeparator', async () => {
92
92
  await _testMSAOnColumn(
@@ -1,6 +1,6 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
 
3
- import {category, expect, test} from '@datagrok-libraries/utils/src/test';
3
+ import {before, category, expect, test} from '@datagrok-libraries/utils/src/test';
4
4
  import {runPepsea} from '../utils/pepsea';
5
5
  import {awaitContainerStart} from './utils';
6
6
 
@@ -12,13 +12,16 @@ category('PepSeA', () => {
12
12
  "PEPTIDE1{F.L.R.G.Y.[MeF].Y.W.S.N.D.C}$$$$","F.L.R.G.Y.MeF.Y.W.S.N.D.C"
13
13
  "PEPTIDE1{F.V.R.G.Y.[MeF].Y.W.S.N.C}$$$$","F.V.R.G.Y.MeF.Y.W.S..N.C"`;
14
14
 
15
- test('Basic alignment', async () => {
15
+ before(async () => {
16
16
  await awaitContainerStart();
17
+ });
18
+
19
+ test('Basic alignment', async () => {
17
20
  const table = DG.DataFrame.fromCsv(testCsv);
18
21
  const alignedCol = await runPepsea(table.getCol('HELM'), 'msa(HELM)');
19
22
  expect(alignedCol !== null, true, 'PepSeA container has not started');
20
23
  const alignedTestCol = table.getCol('MSA');
21
24
  for (let i = 0; i < alignedCol!.length; ++i)
22
25
  expect(alignedCol!.get(i) == alignedTestCol.get(i), true);
23
- }, {timeout: 60000});
26
+ }, {timeout: 60000 /* docker */});
24
27
  });
@@ -28,7 +28,7 @@ async function _testSimilaritySearchViewer() {
28
28
  const viewer: SequenceSimilarityViewer = (await moleculesView.dataFrame.plot
29
29
  .fromType('Sequence Similarity Search')) as SequenceSimilarityViewer;
30
30
  let computeCompleted: boolean = false;
31
- viewer.computeCompleted.subscribe((value) => {
31
+ viewer.computeCompleted.subscribe((value: any) => {
32
32
  if (value) computeCompleted = true;
33
33
  });
34
34
  moleculesView.dockManager.dock(viewer, DG.DOCK_TYPE.RIGHT, null, 'Similarity');
@@ -78,7 +78,7 @@ async function _testDiversitySearchViewer() {
78
78
  const viewer: SequenceDiversityViewer = (await moleculesView.dataFrame.plot
79
79
  .fromType('Sequence Diversity Search')) as SequenceDiversityViewer;
80
80
  let computeCompleted: boolean = false;
81
- viewer.computeCompleted.subscribe((value) => {
81
+ viewer.computeCompleted.subscribe((value: boolean) => {
82
82
  if (value) computeCompleted = true;
83
83
  });
84
84
  moleculesView.dockManager.dock(viewer, DG.DOCK_TYPE.DOWN, null, 'Diversity');
@@ -102,7 +102,7 @@ export function convert(col?: DG.Column): void {
102
102
  })
103
103
  .show({x: 350, y: 100});
104
104
 
105
- convertDialogSubs.push(convertDialog.onClose.subscribe((_value) => {
105
+ convertDialogSubs.push(convertDialog.onClose.subscribe((_: any) => {
106
106
  convertDialogSubs.forEach((s) => { s.unsubscribe(); });
107
107
  convertDialogSubs = [];
108
108
  convertDialog = null;
@@ -106,7 +106,9 @@ export class HelmToMolfileConverter {
106
106
  return DG.Column.fromStrings(columnName, beautifiedMols.map((mol) => {
107
107
  if (mol === null)
108
108
  return '';
109
- return mol.get_molblock();
109
+ const molBlock = mol.get_v3Kmolblock();
110
+ mol!.delete();
111
+ return molBlock;
110
112
  }));
111
113
  }
112
114
 
@@ -9,6 +9,8 @@ import {HELM_WRAPPER} from './const';
9
9
  import {getMolColumnFromHelm} from '../helm-to-molfile';
10
10
  import {ALIGNMENT, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
11
11
 
12
+ const RULE_PATH = 'System:AppData/Bio/polytool-rules/';
13
+
12
14
  type ConnectionData = {
13
15
  allPos1: number[],
14
16
  allPos2: number[],
@@ -17,6 +19,7 @@ type ConnectionData = {
17
19
  }
18
20
 
19
21
  type Rule = {
22
+ code: number,
20
23
  firstMonomer: string,
21
24
  secondMonomer: string,
22
25
  firstModification: string,
@@ -48,27 +51,58 @@ class TransformationCommon {
48
51
  return isLinkable;
49
52
  }
50
53
 
51
- protected getLinkedPositions(helm: string, ruleCount: number): [number, number][] {
54
+ protected getLinkedPositions(helm: string, rules: Rule[]): [number, number][] {
52
55
  const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
53
- const monomers = seq.split('.');
54
- const result:[number, number][] = new Array<[number, number]>(ruleCount);
56
+ const monomers = seq.split('.').map((m) => { return m.replace('[', '').replace(']', ''); });
57
+ const result:[number, number][] = new Array<[number, number]>(rules.length);
55
58
 
56
- for (let i = 0; i < ruleCount; i++) {
59
+ for (let i = 0; i < rules.length; i++) {
57
60
  let firstFound = false;
61
+ let secondFound = false;
62
+ let firstIsFirst = false;
63
+ let firstEntryIndex = -1;
64
+ let secondEntryIndex = -1;
65
+ const add = `(${rules[i].code})`;
58
66
  for (let j = 0; j < monomers.length; j++) {
59
- if (monomers[j].includes(`(${i + 1})`)) {
67
+ if (monomers[j].includes(add)) {
60
68
  if (firstFound) {
61
- result[i][1] = j;
62
- break;
69
+ if (firstIsFirst && monomers[j] == rules[i].secondMonomer + add) {
70
+ secondFound = true;
71
+ secondEntryIndex = j;
72
+ break;
73
+ } else if (!firstIsFirst && monomers[j] == rules[i].firstMonomer + add) {
74
+ secondFound = true;
75
+ secondEntryIndex = j;
76
+ break;
77
+ } else {
78
+ continue;
79
+ }
80
+ //result[i][1] = j;
81
+ // secondFound = true;
82
+ // break;
63
83
  } else {
64
- firstFound = true;
65
- result[i] = [j, 0];
84
+ if (monomers[j] == rules[i].firstMonomer + add) {
85
+ firstFound = true;
86
+ firstIsFirst = true;
87
+ firstEntryIndex = j;
88
+ } else if (monomers[j] == rules[i].secondMonomer + add) {
89
+ firstFound = true;
90
+ firstIsFirst = false;
91
+ firstEntryIndex = j;
92
+ } else {
93
+ continue;
94
+ }
95
+ //result[i] = [j, 0];
66
96
  }
67
97
  }
68
98
  }
69
99
 
70
- if (!firstFound)
100
+ if (!(firstFound && secondFound))
71
101
  result[i] = [-1, -1];
102
+ else if (firstIsFirst)
103
+ result[i] = [firstEntryIndex, secondEntryIndex];
104
+ else
105
+ result[i] = [secondEntryIndex, firstEntryIndex];
72
106
  }
73
107
 
74
108
 
@@ -88,6 +122,7 @@ class TransformationCommon {
88
122
 
89
123
  for (let i = 0; i < ruleCount; i++) {
90
124
  rules[i] = {
125
+ code: codeCol.get(i),
91
126
  firstMonomer: monomer1Col.get(i),
92
127
  secondMonomer: monomer2Col.get(i),
93
128
  firstModification: modification1Col.get(i),
@@ -102,7 +137,7 @@ class TransformationCommon {
102
137
 
103
138
  protected getTransformedHelm(helm: string, rules: Rule[]): string {
104
139
  const ruleCount = rules.length;
105
- const positions = this.getLinkedPositions(helm, ruleCount);
140
+ const positions = this.getLinkedPositions(helm, rules);
106
141
 
107
142
  const allPos1: number [] = [];
108
143
  const allPos2: number [] = [];
@@ -113,31 +148,19 @@ class TransformationCommon {
113
148
  if (positions[i][0] == -1)
114
149
  continue;
115
150
 
116
- helm = helm.replaceAll(`(${i + 1})`, '');
151
+ //helm = helm.replaceAll(`(${i + 1})`, '');
117
152
  const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
118
153
  const monomers = seq.split('.');
119
154
  const firstMonomer = monomers[positions[i][0]].replace('[', '').replace(']', '');
120
155
  const secondMonomer = monomers[positions[i][1]].replace('[', '').replace(']', '');
121
- let attach1 = 0;
122
- let attach2 = 0;
123
- if (firstMonomer === rules[i].firstMonomer && secondMonomer === rules[i].secondMonomer) {
124
- monomers[positions[i][0]] = monomers[positions[i][0]].replace(firstMonomer, rules[i].firstModification);
125
- monomers[positions[i][1]] = monomers[positions[i][1]].replace(secondMonomer, rules[i].secondModification);
126
- attach1 = rules[i].firstR;
127
- attach2 = rules[i].secondR;
128
- } else if (secondMonomer === rules[i].firstModification && firstMonomer === rules[i].secondModification) {
129
- monomers[positions[i][0]] = monomers[positions[i][1]].replace(secondMonomer, rules[i].secondModification);
130
- monomers[positions[i][1]] = rules[i].firstModification.replace(firstMonomer, rules[i].firstModification);
131
- attach1 = rules[i].secondR;
132
- attach2 = rules[i].firstR;
133
- } else {
134
- continue;
135
- }
156
+
157
+ monomers[positions[i][0]] = monomers[positions[i][0]].replace(firstMonomer, rules[i].firstModification);
158
+ monomers[positions[i][1]] = monomers[positions[i][1]].replace(secondMonomer, rules[i].secondModification);
136
159
 
137
160
  allPos1.push(positions[i][0] + 1);
138
161
  allPos2.push(positions[i][1] + 1);
139
- allAttaches1.push(attach1);
140
- allAttaches2.push(attach2);
162
+ allAttaches1.push(rules[i].firstR);
163
+ allAttaches2.push(rules[i].secondR);
141
164
 
142
165
  helm = HELM_WRAPPER.LEFT;
143
166
  for (let i = 0; i < monomers.length; i ++) {
@@ -203,12 +226,15 @@ function getHelmCycle(helm: string, source: ConnectionData): string {
203
226
  }
204
227
 
205
228
  export async function addTransformedColumn(
206
- molColumn: DG.Column<string>, rulesTable: DG.DataFrame, addHelm: boolean
229
+ molColumn: DG.Column<string>, addHelm: boolean
207
230
  ): Promise<void> {
208
231
  const df = molColumn.dataFrame;
209
232
  const uh = UnitsHandler.getOrCreate(molColumn);
210
233
  const sourceHelmCol = uh.convert(NOTATION.HELM);
211
234
  const pt = PolymerTransformation.getInstance(sourceHelmCol);
235
+ const fileSource = new DG.FileSource(RULE_PATH);
236
+ const rulesRaw = await fileSource.readAsText('rules.csv');
237
+ const rulesTable = DG.DataFrame.fromCsv(rulesRaw);
212
238
  const targetList = pt.transform(rulesTable);
213
239
  const helmColName = df.columns.getUnusedName('transformed(' + molColumn.name + ')');
214
240
  const targetHelmCol = DG.Column.fromList('string', helmColName, targetList);
@@ -10,6 +10,8 @@ import {addTransformedColumn} from './transformation';
10
10
  import * as rxjs from 'rxjs';
11
11
  //import {MetaData} from './types';
12
12
 
13
+ const RULE_PATH = 'System:AppData/Bio/polytool-rules/';
14
+
13
15
  export function getPolyToolDialog(): DG.Dialog {
14
16
  //const monomerLib = MonomerLibManager.instance.getBioLib();
15
17
  const targetColumns = grok.shell.t.columns.bySemTypeAll(DG.SEMTYPE.MACROMOLECULE);
@@ -24,41 +26,19 @@ export function getPolyToolDialog(): DG.Dialog {
24
26
  const generateHelmChoiceInput = ui.boolInput('Get HELM', true);
25
27
  ui.tooltip.bind(generateHelmChoiceInput.root, 'Add HELM column');
26
28
 
27
- let rulesTable: DG.DataFrame = DG.DataFrame.create();
29
+ // let rulesTable: DG.DataFrame = DG.DataFrame.create();
28
30
 
29
31
  const ruleFileInput = ui.button('ADD RULES', () => {
30
32
  DG.Utils.openFile({
31
33
  accept: '.csv',
32
34
  open: async (selectedFile) => {
33
35
  const content = await selectedFile.text();
34
- rulesTable = DG.DataFrame.fromCsv(content);
36
+ // rulesTable = DG.DataFrame.fromCsv(content);
37
+ await grok.dapi.files.writeAsText(RULE_PATH + `${selectedFile.name}`, content);
35
38
  //console.log(df.toCsv());
36
39
  },
37
40
  });
38
41
  });
39
- // dialog.addButton(
40
- // 'Add',
41
- // () => eventManager.addLibraryFile(),
42
- // undefined,
43
- // 'Upload new HELM monomer library'
44
- // );
45
-
46
-
47
- // const ruleFileInput = DG.Utils.openFile({
48
- // accept: '.csv',
49
- // open: async (selectedFile) => {
50
- // const content = await selectedFile.text();
51
- // const name = selectedFile.name;
52
- // const df = DG.DataFrame.fromCsv(content);
53
-
54
- // console.log(df.toCsv());
55
- // },
56
- // });
57
-
58
- //grok.data.files.openTable('Samples:Files/chem/smiles_10K_with_activities.csv')
59
- // const file = await loadFileAsText(tableName);
60
- // const df = DG.DataFrame.fromCsv(file);
61
- // df.name = tableName.replace('.csv', '');
62
42
 
63
43
  const div = ui.div([
64
44
  targetColumnInput,
@@ -74,7 +54,7 @@ export function getPolyToolDialog(): DG.Dialog {
74
54
  grok.shell.warning('No marcomolecule column chosen!');
75
55
  return;
76
56
  }
77
- addTransformedColumn(molCol!, rulesTable!, generateHelmChoiceInput.value!);
57
+ addTransformedColumn(molCol!, generateHelmChoiceInput.value!);
78
58
  }
79
59
  );
80
60
 
@@ -87,7 +87,7 @@ export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements I
87
87
  // webEditor = undefined;
88
88
  // });
89
89
  }));
90
- this.viewSubs.push(ui.onSizeChanged(this._filterPanel).subscribe((_) => {
90
+ this.viewSubs.push(ui.onSizeChanged(this._filterPanel).subscribe((_: any) => {
91
91
  try {
92
92
  if (!!webEditorApp) {
93
93
  const helmString = webEditorApp.canvas.getHelm(true)
@@ -110,7 +110,7 @@ export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements I
110
110
 
111
111
  applyProps() {
112
112
  if (!this.helmEditor) return; // helmEditor is not created, the filter is not in dom yet
113
- this.updateFilterPanel(this.props.substructure);
113
+ this.updateFilterPanel(this.props.substructure);
114
114
  }
115
115
 
116
116
  get filterPanel() {
package/webpack.config.js CHANGED
@@ -3,6 +3,9 @@ const FuncGeneratorPlugin = require('datagrok-tools/plugins/func-gen-plugin');
3
3
  const packageName = path.parse(require('./package.json').name).name.toLowerCase().replace(/-/g, '');
4
4
 
5
5
  module.exports = {
6
+ cache: {
7
+ type: 'filesystem',
8
+ },
6
9
  mode: 'development',
7
10
  entry: {
8
11
  package: ['./src/package.ts'],