@datagrok/peptides 0.8.9 → 0.8.13

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.
Files changed (39) hide show
  1. package/.eslintrc.json +2 -1
  2. package/dist/package-test.js +22626 -0
  3. package/dist/package.js +21429 -0
  4. package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +8840 -0
  5. package/jest.config.js +33 -0
  6. package/package.json +75 -62
  7. package/src/__jest__/remote.test.ts +50 -0
  8. package/src/__jest__/test-node.ts +96 -0
  9. package/src/model.ts +950 -86
  10. package/src/monomer-library.ts +8 -0
  11. package/src/package-test.ts +3 -2
  12. package/src/package.ts +57 -22
  13. package/src/peptides.ts +165 -119
  14. package/src/styles.css +8 -0
  15. package/src/tests/peptides-tests.ts +17 -78
  16. package/src/tests/utils.ts +1 -7
  17. package/src/utils/SAR-multiple-filter.ts +439 -0
  18. package/src/utils/SAR-multiple-selection.ts +177 -0
  19. package/src/utils/cell-renderer.ts +49 -50
  20. package/src/utils/chem-palette.ts +61 -163
  21. package/src/utils/constants.ts +56 -0
  22. package/src/utils/filtering-statistics.ts +62 -0
  23. package/src/utils/multiple-sequence-alignment.ts +33 -2
  24. package/src/utils/multivariate-analysis.ts +79 -0
  25. package/src/utils/peptide-similarity-space.ts +12 -31
  26. package/src/utils/types.ts +10 -0
  27. package/src/viewers/logo-viewer.ts +2 -1
  28. package/src/viewers/peptide-space-viewer.ts +121 -0
  29. package/src/viewers/sar-viewer.ts +111 -313
  30. package/src/viewers/stacked-barchart-viewer.ts +126 -173
  31. package/src/widgets/analyze-peptides.ts +39 -18
  32. package/src/widgets/distribution.ts +61 -0
  33. package/src/widgets/manual-alignment.ts +3 -3
  34. package/src/widgets/peptide-molecule.ts +4 -4
  35. package/src/widgets/subst-table.ts +30 -22
  36. package/test-Peptides-f8114def7953-4bf59d70.html +256 -0
  37. package/src/describe.ts +0 -534
  38. package/src/utils/split-aligned.ts +0 -72
  39. package/src/viewers/subst-viewer.ts +0 -320
@@ -1,8 +1,11 @@
1
1
  /** HELM associated sdf libraries with monomer processing*/
2
2
  export class MonomerLibrary {
3
+ private static _name = 'monomerLibrary';
4
+
3
5
  private monomerFields: string[] = [
4
6
  'molecule', 'MonomerType', 'MonomerNaturalAnalogCode', 'MonomerName', 'MonomerCode', 'MonomerCaps', 'BranchMonomer',
5
7
  ];
8
+
6
9
  private library: {
7
10
  [name: string]: {
8
11
  mol: string,
@@ -11,6 +14,7 @@ export class MonomerLibrary {
11
14
  linkages: { [link: string]: { atomNumber: number, type: string } }
12
15
  }
13
16
  } = {};
17
+
14
18
  private monomers: string[] = [];
15
19
 
16
20
  constructor(sdf: string) {
@@ -72,6 +76,10 @@ export class MonomerLibrary {
72
76
  return this.monomers;
73
77
  }
74
78
 
79
+ static get id(): string {
80
+ return MonomerLibrary._name;
81
+ }
82
+
75
83
  private getLinkData(mol: string, caps: string, name: string) {
76
84
  const rawData = mol.match(/M RGP .+/);
77
85
  if (rawData === null)
@@ -1,12 +1,13 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
 
3
- import {runTests} from '@datagrok-libraries/utils/src/test';
3
+ import {runTests, tests} from '@datagrok-libraries/utils/src/test';
4
4
 
5
5
  import './tests/peptide-space-test';
6
6
  import './tests/peptides-tests';
7
7
  import './tests/msa-tests';
8
8
 
9
- export const _package = new DG.Package();
9
+ export const _packageTest = new DG.Package();
10
+ export {tests};
10
11
 
11
12
  //name: test
12
13
  //input: string category {optional: true}
package/src/package.ts CHANGED
@@ -3,6 +3,8 @@ 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 * as C from './utils/constants';
7
+
6
8
  import {
7
9
  AlignedSequenceCellRenderer,
8
10
  AlignedSequenceDifferenceCellRenderer,
@@ -16,9 +18,11 @@ import {PeptideSimilaritySpaceWidget} from './utils/peptide-similarity-space';
16
18
  import {manualAlignmentWidget} from './widgets/manual-alignment';
17
19
  import {SARViewer, SARViewerVertical} from './viewers/sar-viewer';
18
20
  import {peptideMoleculeWidget, getMolecule} from './widgets/peptide-molecule';
19
- import {SubstViewer} from './viewers/subst-viewer';
20
- import {substTableWidget} from './widgets/subst-table';
21
+ import {runKalign, testMSAEnoughMemory} from './utils/multiple-sequence-alignment';
22
+ import {substitutionsWidget} from './widgets/subst-table';
21
23
  import {msaWidget} from './widgets/multiple-sequence-alignment';
24
+ import {getDistributionWidget} from './widgets/distribution';
25
+ import {PeptideSpaceViewer} from './viewers/peptide-space-viewer';
22
26
 
23
27
  export const _package = new DG.Package();
24
28
  let currentGrid: DG.Grid;
@@ -31,7 +35,6 @@ async function main(chosenFile: string) {
31
35
  const path = _package.webRoot + 'files/' + chosenFile;
32
36
  const peptides = (await grok.data.loadTable(path));
33
37
  peptides.name = 'Peptides';
34
- peptides.setTag('dataType', 'peptides');
35
38
  const view = grok.shell.addTableView(peptides);
36
39
  currentGrid = view.grid;
37
40
  view.name = 'PeptidesView';
@@ -77,6 +80,7 @@ export async function Peptides() {
77
80
  ui.divH([
78
81
  ui.button('Simple demo', () => main('aligned.csv'), ''),
79
82
  ui.button('Complex demo', () => main('aligned_2.csv'), ''),
83
+
80
84
  ]),
81
85
  ]);
82
86
  }
@@ -90,8 +94,8 @@ export async function peptidesPanel(col: DG.Column): Promise<DG.Widget> {
90
94
  return new DG.Widget(ui.divText('Analysis is not applicable'));
91
95
 
92
96
  [currentView, currentGrid, currentTable, alignedSequenceColumn] =
93
- getOrDefineWIP(currentView, currentGrid, currentTable, col);
94
- return await analyzePeptidesWidget(col, currentView, currentGrid, currentTable);
97
+ getOrDefine(undefined, undefined, col.dataFrame, col);
98
+ return analyzePeptidesWidget(currentTable, alignedSequenceColumn);
95
99
  }
96
100
 
97
101
  //name: peptide-sar-viewer
@@ -110,12 +114,12 @@ export function sarVertical(): SARViewerVertical {
110
114
  return new SARViewerVertical();
111
115
  }
112
116
 
113
- //name: substitution-analysis-viewer
114
- //description: Substitution Analysis Viewer
117
+ //name: peptide-space-viewer
118
+ //description: Peptide Space Viewer
115
119
  //tags: viewer
116
120
  //output: viewer result
117
- export function subst(): SubstViewer {
118
- return new SubstViewer();
121
+ export function peptideSpace(): PeptideSpaceViewer {
122
+ return new PeptideSpaceViewer();
119
123
  }
120
124
 
121
125
  //name: StackedBarchart Widget
@@ -133,7 +137,7 @@ export async function stackedBarchartWidget(col: DG.Column): Promise<DG.Widget>
133
137
  //input: string peptide {semType: alignedSequence}
134
138
  //output: widget result
135
139
  export async function peptideMolecule(peptide: string): Promise<DG.Widget> {
136
- return await peptideMoleculeWidget(peptide);
140
+ return peptideMoleculeWidget(peptide);
137
141
  }
138
142
 
139
143
  //name: Peptide Molecule
@@ -142,9 +146,9 @@ export async function peptideMolecule(peptide: string): Promise<DG.Widget> {
142
146
  //output: widget result
143
147
  export async function peptideMolecule2(aar: string): Promise<DG.Widget> {
144
148
  [currentView, currentGrid, currentTable, alignedSequenceColumn] =
145
- getOrDefineWIP(currentView, currentGrid, currentTable, alignedSequenceColumn);
149
+ getOrDefine();
146
150
  const peptide = alignedSequenceColumn.get(currentTable.currentRowIdx);
147
- return await peptideMolecule(peptide);
151
+ return peptideMolecule(peptide);
148
152
  }
149
153
 
150
154
  //name: StackedBarChartAA
@@ -183,7 +187,7 @@ export function logov() {
183
187
  //output: widget result
184
188
  export function manualAlignment(monomer: string) {
185
189
  [currentView, currentGrid, currentTable, alignedSequenceColumn] =
186
- getOrDefineWIP(currentView, currentGrid, currentTable, alignedSequenceColumn);
190
+ getOrDefine();
187
191
  //TODO: recalculate Molfile and Molecule panels on sequence update
188
192
  return manualAlignmentWidget(alignedSequenceColumn, currentTable);
189
193
  }
@@ -194,9 +198,9 @@ export function manualAlignment(monomer: string) {
194
198
  //output: widget result
195
199
  export async function peptideSpacePanel(col: DG.Column): Promise<DG.Widget> {
196
200
  [currentView, currentGrid, currentTable, alignedSequenceColumn] =
197
- getOrDefineWIP(currentView, currentGrid, currentTable, col);
201
+ getOrDefine(undefined, undefined, col.dataFrame, col);
198
202
  const widget = new PeptideSimilaritySpaceWidget(col, currentView);
199
- return await widget.draw();
203
+ return widget.draw();
200
204
  }
201
205
 
202
206
  //name: Molfile
@@ -205,7 +209,7 @@ export async function peptideSpacePanel(col: DG.Column): Promise<DG.Widget> {
205
209
  //output: widget result
206
210
  export async function peptideMolfile(peptide: string): Promise<DG.Widget> {
207
211
  const smiles = getMolecule(peptide);
208
- return await grok.functions.call('Chem:molfile', {'smiles': smiles});
212
+ return grok.functions.call('Chem:molfile', {'smiles': smiles});
209
213
  }
210
214
 
211
215
  //name: Molfile
@@ -214,9 +218,9 @@ export async function peptideMolfile(peptide: string): Promise<DG.Widget> {
214
218
  //output: widget result
215
219
  export async function peptideMolfile2(aar: string): Promise<DG.Widget> {
216
220
  [currentView, currentGrid, currentTable, alignedSequenceColumn] =
217
- getOrDefineWIP(currentView, currentGrid, currentTable, alignedSequenceColumn);
221
+ getOrDefine();
218
222
  const peptide = alignedSequenceColumn.get(currentTable.currentRowIdx);
219
- return await peptideMolfile(peptide);
223
+ return peptideMolfile(peptide);
220
224
  }
221
225
 
222
226
  //name: Multiple sequence alignment
@@ -224,7 +228,26 @@ export async function peptideMolfile2(aar: string): Promise<DG.Widget> {
224
228
  //input: column col {semType: alignedSequence}
225
229
  //output: dataframe result
226
230
  export async function multipleSequenceAlignment(col: DG.Column): Promise<DG.DataFrame> {
227
- return await msaWidget(col);
231
+ return msaWidget(col);
232
+ }
233
+
234
+ //name: Multiple sequence alignment for any column
235
+ //input: dataframe table
236
+ //input: column col
237
+ //output: dataframe result
238
+ export async function multipleSequenceAlignmentAny(table: DG.DataFrame, col: DG.Column): Promise<DG.DataFrame> {
239
+ const msaCol = await runKalign(col, false);
240
+ table.columns.add(msaCol);
241
+ return table;
242
+ }
243
+
244
+ //name: Test multiple sequence alignment for any column
245
+ //input: dataframe table
246
+ //input: column col
247
+ //output: column result
248
+ export async function runTestMSAEnoughMemory(table: DG.DataFrame, col: DG.Column) {
249
+ await testMSAEnoughMemory(col);
250
+ return col;
228
251
  }
229
252
 
230
253
  //name: Substitution
@@ -232,7 +255,19 @@ export async function multipleSequenceAlignment(col: DG.Column): Promise<DG.Data
232
255
  //input: dataframe table {semType: Substitution}
233
256
  //output: widget result
234
257
  export async function peptideSubstitution(table: DG.DataFrame): Promise<DG.Widget> {
235
- return substTableWidget(table);
258
+ if (!table.temp[C.PEPTIDES_ANALYSIS])
259
+ return new DG.Widget(ui.divText('This widget is only applicable for peptides analysis'));
260
+ return substitutionsWidget(table);
261
+ }
262
+
263
+ //name: Distribution
264
+ //tags: panel, widgets
265
+ //input: dataframe table {semType: viewerTable}
266
+ //output: widget result
267
+ export function peptideDistribution(table: DG.DataFrame): DG.Widget {
268
+ if (!table.temp[C.PEPTIDES_ANALYSIS])
269
+ return new DG.Widget(ui.divText('This widget is only applicable for peptides analysis'));
270
+ return getDistributionWidget(table);
236
271
  }
237
272
 
238
273
  //name: alignedSequenceDifferenceCellRenderer
@@ -243,13 +278,13 @@ export function alignedSequenceDifferenceCellRenderer() {
243
278
  return new AlignedSequenceDifferenceCellRenderer();
244
279
  }
245
280
 
246
- function getOrDefineWIP(
281
+ function getOrDefine(
247
282
  view?: DG.TableView, grid?: DG.Grid, dataframe?: DG.DataFrame, column?: DG.Column | null,
248
283
  ): [DG.TableView, DG.Grid, DG.DataFrame, DG.Column] {
249
284
  view ??= (grok.shell.v as DG.TableView);
250
285
  grid ??= view.grid;
251
286
  dataframe ??= grok.shell.t;
252
- column ??= (dataframe.columns as DG.ColumnList).bySemType('alignedSequence');
287
+ column ??= (dataframe.columns as DG.ColumnList).bySemType(C.SEM_TYPES.ALIGNED_SEQUENCE);
253
288
  if (column === null)
254
289
  throw new Error('Table does not contain aligned sequence columns');
255
290
 
package/src/peptides.ts CHANGED
@@ -1,80 +1,90 @@
1
- import * as ui from 'datagrok-api/ui';
1
+ import * as grok from 'datagrok-api/grok';
2
2
  import * as DG from 'datagrok-api/dg';
3
- import {createPeptideSimilaritySpaceViewer} from './utils/peptide-similarity-space';
4
3
  import {PeptidesModel} from './model';
5
- import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
6
4
  import {SARViewer, SARViewerVertical} from './viewers/sar-viewer';
7
- import {SubstViewer} from './viewers/subst-viewer';
8
5
  import {ChemPalette} from './utils/chem-palette';
9
6
  import {Observable} from 'rxjs';
10
-
11
- type viewerTypes = SARViewer | SARViewerVertical | SubstViewer;
7
+ import {MonomerLibrary} from './monomer-library';
8
+ import {_package} from './package';
9
+ import {setAARRenderer} from './utils/cell-renderer';
10
+ import * as C from './utils/constants';
11
+ import {PeptideSpaceViewer} from './viewers/peptide-space-viewer';
12
+ import { FilteringStatistics } from './utils/filtering-statistics';
13
+
14
+ type viewerTypes = SARViewer | SARViewerVertical;
12
15
  export class PeptidesController {
13
16
  private static _controllerName: string = 'peptidesController';
14
17
  private helpUrl = '/help/domains/bio/peptides.md';
15
- private _dataFrame: DG.DataFrame;
18
+
16
19
  private _model: PeptidesModel;
20
+ sarViewer!: SARViewer;
21
+ sarViewerVertical!: SARViewerVertical;
22
+ isInitialized = false;
17
23
 
18
24
  private constructor(dataFrame: DG.DataFrame) {
19
- this._dataFrame = dataFrame;
20
- this._model = PeptidesModel.getOrInit(this._dataFrame);
21
- // this.getOrInitModel(this._dataFrame);
25
+ this._model = PeptidesModel.getInstance(dataFrame);
22
26
  }
23
27
 
24
- static getInstance(dataFrame: DG.DataFrame): PeptidesController {
28
+ static async getInstance(dataFrame: DG.DataFrame): Promise<PeptidesController> {
25
29
  dataFrame.temp[PeptidesController.controllerName] ??= new PeptidesController(dataFrame);
30
+ if (dataFrame.temp[MonomerLibrary.id] === null) {
31
+ const sdf = await _package.files.readAsText('HELMMonomers_June10.sdf');
32
+ dataFrame.temp[MonomerLibrary.id] ??= new MonomerLibrary(sdf);
33
+ }
26
34
  return dataFrame.temp[PeptidesController.controllerName];
27
35
  }
28
36
 
29
- static get controllerName() {
30
- return PeptidesController._controllerName;
31
- }
37
+ static get controllerName() {return PeptidesController._controllerName;}
32
38
 
33
- // getOrInitModel(): PeptidesModel {
34
- // this._model ??= PeptidesModel.getOrInit(this._dataFrame);
35
- // return this._model;
36
- // }
39
+ get dataFrame() {return this._model.dataFrame;}
37
40
 
38
- get onStatsDataFrameChanged(): Observable<DG.DataFrame> {
39
- return this._model.onStatsDataFrameChanged;
41
+ static setAARRenderer(col: DG.Column, grid: DG.Grid) {
42
+ return setAARRenderer(col, grid);
40
43
  }
41
44
 
42
- get onSARGridChanged(): Observable<DG.Grid> {
43
- return this._model.onSARGridChanged;
44
- }
45
+ get onStatsDataFrameChanged(): Observable<DG.DataFrame> {return this._model.onStatsDataFrameChanged;}
45
46
 
46
- get onSARVGridChanged(): Observable<DG.Grid> {
47
- return this._model.onSARVGridChanged;
48
- }
47
+ get onSARGridChanged(): Observable<DG.Grid> {return this._model.onSARGridChanged;}
49
48
 
50
- get onGroupMappingChanged(): Observable<StringDictionary> {
51
- return this._model.onGroupMappingChanged;
52
- }
49
+ get onSARVGridChanged(): Observable<DG.Grid> {return this._model.onSARVGridChanged;}
53
50
 
54
- get onSubstFlagChanged(): Observable<boolean> {
55
- return this._model.onSubstFlagChanged;
56
- }
51
+ // get onGroupMappingChanged(): Observable<StringDictionary> {return this._model.onGroupMappingChanged;}
57
52
 
58
- async updateDefault() {
59
- await this._model.updateDefault();
60
- }
53
+ get onSubstTableChanged(): Observable<DG.DataFrame> {return this._model.onSubstTableChanged;}
54
+
55
+ async updateDefault() {await this._model.updateDefault();}
56
+
57
+ get sarGrid() {return this._model._sarGrid;}
58
+
59
+ get sarVGrid() {return this._model._sarVGrid;}
60
+
61
+ get sourceGrid() {return this._model._sourceGrid!; }
61
62
 
62
63
  async updateData(
63
- dataFrame: DG.DataFrame | null, activityCol: string | null, activityScaling: string | null,
64
- sourceGrid: DG.Grid | null, twoColorMode: boolean | null, initialBitset: DG.BitSet | null,
65
- grouping: boolean | null) {
64
+ activityScaling?: string, sourceGrid?: DG.Grid, twoColorMode?: boolean, activityLimit?: number,
65
+ maxSubstitutions?: number, isSubstitutionOn?: boolean, filterMode?: boolean,
66
+ ) {
67
+ filterMode ??= false;
66
68
  await this._model.updateData(
67
- dataFrame, activityCol, activityScaling, sourceGrid, twoColorMode, initialBitset, grouping);
69
+ activityScaling, sourceGrid, twoColorMode, activityLimit, maxSubstitutions, isSubstitutionOn, filterMode);
70
+ }
71
+
72
+ getSubstitutions() {
73
+ return this._model.getSubstitutionTable();
68
74
  }
69
75
 
70
76
  static async scaleActivity(
71
- activityScaling: string, activityColumn: string, activityColumnScaled: string, df: DG.DataFrame,
77
+ activityScaling: string, df: DG.DataFrame, originalActivityName?: string, cloneBitset = false,
72
78
  ): Promise<[DG.DataFrame, string]> {
73
79
  // const df = sourceGrid.dataFrame!;
74
- const tempDf = df.clone(null, [activityColumn]);
75
-
76
- let formula = '${' + activityColumn + '}';
77
- let newColName = activityColumn;
80
+ let currentActivityColName = originalActivityName ?? C.COLUMNS_NAMES.ACTIVITY;
81
+ const flag = (df.columns as DG.ColumnList).names().includes(currentActivityColName) &&
82
+ currentActivityColName === originalActivityName;
83
+ currentActivityColName = flag ? currentActivityColName : C.COLUMNS_NAMES.ACTIVITY;
84
+ const tempDf = df.clone(cloneBitset ? df.filter : null, [currentActivityColName]);
85
+
86
+ let formula = '${' + currentActivityColName + '}';
87
+ let newColName = 'activity'; //originalActivityName ?? df.temp[C.COLUMNS_NAMES.ACTIVITY] ?? currentActivityColName;
78
88
  switch (activityScaling) {
79
89
  case 'none':
80
90
  break;
@@ -90,11 +100,16 @@ export class PeptidesController {
90
100
  throw new Error(`ScalingError: method \`${activityScaling}\` is not available.`);
91
101
  }
92
102
 
93
- await (tempDf.columns as DG.ColumnList).addNewCalculated(activityColumnScaled, formula);
103
+ await (tempDf.columns as DG.ColumnList).addNewCalculated(C.COLUMNS_NAMES.ACTIVITY_SCALED, formula);
104
+ df.tags['scaling'] = activityScaling;
94
105
 
95
106
  return [tempDf, newColName];
96
107
  }
97
108
 
109
+ get originalActivityColumnName(): string {return this.dataFrame.temp[C.COLUMNS_NAMES.ACTIVITY];}
110
+
111
+ get substTooltipData() {return this._model.substTooltipData;}
112
+
98
113
  static splitAlignedPeptides(peptideColumn: DG.Column, filter: boolean = true): [DG.DataFrame, number[]] {
99
114
  const splitPeptidesArray: string[][] = [];
100
115
  let currentSplitPeptide: string[];
@@ -136,8 +151,8 @@ export class PeptidesController {
136
151
 
137
152
  //create column names list
138
153
  const columnNames = Array.from({length: modeMonomerCount}, (_, index) => `${index + 1 < 10 ? 0 : ''}${index + 1 }`);
139
- columnNames.splice(0, 0, 'N-terminal');
140
- columnNames.push('C-terminal');
154
+ columnNames.splice(0, 0, 'Nterminal');
155
+ columnNames.push('Cterminal');
141
156
 
142
157
  // filter out the columns with the same values
143
158
  if (filter) {
@@ -158,23 +173,91 @@ export class PeptidesController {
158
173
  ];
159
174
  }
160
175
 
161
- static getChemPalette() {
162
- return ChemPalette;
176
+ static get chemPalette() { return ChemPalette; }
177
+
178
+ assertVar(variable: string, init = false): boolean {
179
+ //@ts-ignore
180
+ let foundVariable: any = this[variable];
181
+ if (!foundVariable && init) {
182
+ //@ts-ignore
183
+ this[variable] = foundVariable = this.dataFrame.temp[variable];
184
+ }
185
+
186
+ const assertionResult = foundVariable ? true : false
187
+ if (init && !assertionResult)
188
+ throw new Error(`Variable assertion error: variable '${variable}' is not found in dataFrame`);
189
+
190
+ return assertionResult;
191
+ }
192
+
193
+ assertVariables(variables: string[], init = false) {
194
+ let result = true;
195
+ for (const variable of variables)
196
+ result &&= this.assertVar(variable, init);
197
+
198
+ return result;
199
+ }
200
+
201
+ syncProperties(isSourceSAR = true) {
202
+ this.assertVariables(['sarViewer', 'sarViewerVertical'], true);
203
+ const sourceViewer = isSourceSAR ? this.sarViewer : this.sarViewerVertical;
204
+ const targetViewer = isSourceSAR ? this.sarViewerVertical : this.sarViewer;
205
+ const properties = sourceViewer.props.getProperties();
206
+ for (const property of properties)
207
+ targetViewer.props.set(property.name, property.get(sourceViewer));
208
+ }
209
+
210
+ modifyOrCreateSplitCol(aar: string, position: string, notify: boolean = true) {
211
+ this._model.modifyOrCreateSplitCol(aar, position);
212
+ if (notify)
213
+ this._model.fireBitsetChanged();
214
+ }
215
+
216
+ setSARGridCellAt(aar: string, position: string) {
217
+ const sarDf = this.sarGrid.dataFrame;
218
+ const aarCol = sarDf.getCol(C.COLUMNS_NAMES.AMINO_ACID_RESIDUE);
219
+ const aarColLen = aarCol.length;
220
+ let index = -1;
221
+ for (let i = 0; i < aarColLen; i++) {
222
+ if (aarCol.get(i) === aar) {
223
+ index = i;
224
+ break;
225
+ }
226
+ }
227
+ position = position === C.CATEGORIES.ALL ? C.COLUMNS_NAMES.AMINO_ACID_RESIDUE : position;
228
+ sarDf.currentCell = sarDf.cell(index, position);
163
229
  }
164
230
 
165
231
  /**
166
232
  * Class initializer
167
233
  *
168
- * @param {DG.Grid} tableGrid Working talbe grid.
169
- * @param {DG.TableView} view Working view.
234
+ * @param {DG.Grid} sourceGrid Working talbe grid.
235
+ * @param {DG.TableView} currentView Working view.
170
236
  * @param {DG.DataFrame} currentDf Working table.
171
237
  * @param {StringDictionary} options SAR viewer options
172
238
  * @param {DG.Column} col Aligned sequences column.
173
239
  * @memberof Peptides
174
240
  */
175
- async init(
176
- tableGrid: DG.Grid, view: DG.TableView, options: StringDictionary, col: DG.Column,
177
- originalDfColumns: string[]) {
241
+ async init(table: DG.DataFrame) {
242
+ if (this.isInitialized)
243
+ return;
244
+ this.isInitialized = true;
245
+ //calculate initial stats
246
+ const stats = new FilteringStatistics();
247
+ const activityScaledCol = table.getCol(C.COLUMNS_NAMES.ACTIVITY_SCALED);
248
+ stats.setData(activityScaledCol.getRawData() as Float32Array);
249
+ stats.setMask(table.selection);
250
+ table.temp[C.STATS] = stats;
251
+
252
+ //set up views
253
+ let currentView = grok.shell.v as DG.TableView ;
254
+ if (currentView.dataFrame.tags['isPeptidesAnalysis'] !== 'true')
255
+ currentView = grok.shell.addTableView(table);
256
+ const sourceGrid = currentView.grid;
257
+ sourceGrid.col(C.COLUMNS_NAMES.ACTIVITY_SCALED)!.name = table.temp[C.COLUMNS_NAMES.ACTIVITY_SCALED];
258
+ sourceGrid.columns.setOrder([table.temp[C.COLUMNS_NAMES.ACTIVITY_SCALED]]);
259
+
260
+ this.dataFrame.temp[C.EMBEDDING_STATUS] = false;
178
261
  function adjustCellSize(grid: DG.Grid) {
179
262
  const colNum = grid.columns.length;
180
263
  for (let i = 0; i < colNum; ++i) {
@@ -184,82 +267,45 @@ export class PeptidesController {
184
267
  grid.props.rowHeight = 20;
185
268
  }
186
269
 
187
- for (let i = 0; i < tableGrid.columns.length; i++) {
188
- const aarCol = tableGrid.columns.byIndex(i);
189
- if (aarCol &&
190
- aarCol.name &&
191
- aarCol.column?.semType != 'aminoAcids'
192
- ) {
193
- //@ts-ignore
194
- tableGrid.columns.byIndex(i)?.visible = false;
195
- }
270
+ for (let i = 0; i < sourceGrid.columns.length; i++) {
271
+ const aarCol = sourceGrid.columns.byIndex(i);
272
+ if (aarCol && aarCol.name && aarCol.column?.semType !== C.SEM_TYPES.AMINO_ACIDS &&
273
+ aarCol.name !== this.dataFrame.temp[C.COLUMNS_NAMES.ACTIVITY_SCALED]
274
+ )
275
+ sourceGrid.columns.byIndex(i)!.visible = false;
196
276
  }
197
277
 
198
- const originalDfName = this._dataFrame.name;
199
- const dockManager = view.dockManager;
200
-
201
- const sarViewer = await this._dataFrame.plot.fromType('peptide-sar-viewer', options) as SARViewer;
202
- sarViewer.helpUrl = this.helpUrl;
203
-
204
- const sarViewerVertical = await this._dataFrame.plot.fromType('peptide-sar-viewer-vertical') as SARViewerVertical;
205
- sarViewerVertical.helpUrl = this.helpUrl;
206
-
207
- const sarViewersGroup: viewerTypes[] = [sarViewer, sarViewerVertical];
208
-
209
- const peptideSpaceViewer = await createPeptideSimilaritySpaceViewer(
210
- this._dataFrame, col, 't-SNE', 'Levenshtein', 100, view, `${options['activityColumnName']}Scaled`);
211
- dockManager.dock(peptideSpaceViewer, DG.DOCK_TYPE.RIGHT, null, 'Peptide Space viewer');
278
+ const options = {scaling: table.tags['scaling']};
279
+ await this.updateData(table.tags['scaling'], sourceGrid, false, 1, 2, false, false);
212
280
 
213
- let nodeList = dockViewers(sarViewersGroup, DG.DOCK_TYPE.RIGHT, dockManager, DG.DOCK_TYPE.DOWN);
281
+ const dockManager = currentView.dockManager;
214
282
 
215
- const substViewer = await this._dataFrame.plot.fromType(
216
- 'substitution-analysis-viewer', {'activityColumnName': `${options['activityColumnName']}Scaled`}) as SubstViewer;
217
- const substViewersGroup = [substViewer];
283
+ this.dataFrame.temp['sarViewer'] = this.sarViewer =
284
+ await this.dataFrame.plot.fromType('peptide-sar-viewer', options) as SARViewer;
285
+ this.sarViewer.helpUrl = this.helpUrl;
218
286
 
219
- tableGrid.props.allowEdit = false;
220
- adjustCellSize(tableGrid);
287
+ this.dataFrame.temp['sarViewerVertical'] = this.sarViewerVertical =
288
+ await this.dataFrame.plot.fromType('peptide-sar-viewer-vertical', options) as SARViewerVertical;
289
+ this.sarViewerVertical.helpUrl = this.helpUrl;
221
290
 
222
- const hideIcon = ui.iconFA('window-close', () => {
223
- const viewers = [];
224
- for (const viewer of view.viewers) {
225
- if (viewer.type !== DG.VIEWER.GRID)
226
- viewers.push(viewer);
227
- }
228
- viewers.forEach((v) => v.close());
229
-
230
- const cols = (this._dataFrame.columns as DG.ColumnList);
231
- for (const colName of cols.names()) {
232
- if (!originalDfColumns.includes(colName))
233
- cols.remove(colName);
234
- }
291
+ const sarViewersGroup: viewerTypes[] = [this.sarViewer, this.sarViewerVertical];
235
292
 
236
- this._dataFrame.selection.setAll(false);
237
- this._dataFrame.filter.setAll(true);
293
+ const peptideSpaceViewerOptions = {method: 't-SNE', measure: 'Levenshtein', cyclesCount: 100};
294
+ const peptideSpaceViewer =
295
+ await this.dataFrame.plot.fromType('peptide-space-viewer', peptideSpaceViewerOptions) as PeptideSpaceViewer;
296
+ dockManager.dock(peptideSpaceViewer, DG.DOCK_TYPE.RIGHT, null, 'Peptide Space Viewer');
238
297
 
239
- tableGrid.setOptions({'colHeaderHeight': 20});
240
- tableGrid.columns.setVisible(originalDfColumns);
241
- tableGrid.props.allowEdit = true;
242
- this._dataFrame.name = originalDfName;
298
+ dockViewers(sarViewersGroup, DG.DOCK_TYPE.RIGHT, dockManager, DG.DOCK_TYPE.DOWN);
243
299
 
244
- view.setRibbonPanels(ribbonPanels);
245
- }, 'Close viewers and restore dataframe');
300
+ sourceGrid.props.allowEdit = false;
301
+ adjustCellSize(sourceGrid);
246
302
 
247
- let isSA = false;
248
- const switchViewers = ui.iconFA('toggle-on', () => {
249
- $(switchViewers).toggleClass('fa-toggle-off').toggleClass('fa-toggle-on');
250
- nodeList?.forEach((node) => {
251
- view.dockManager.close(node);
252
- node.container.destroy();
253
- });
254
- const getCurrentViewerGroup = () => isSA ? substViewersGroup : sarViewersGroup;
255
- getCurrentViewerGroup().forEach((v) => v.removeFromView());
256
- isSA = !isSA;
257
- nodeList = dockViewers(getCurrentViewerGroup(), DG.DOCK_TYPE.LEFT, dockManager, DG.DOCK_TYPE.DOWN);
258
- }, 'Toggle viewer group');
259
-
260
- const ribbonPanels = view.getRibbonPanels();
261
- view.setRibbonPanels([[hideIcon, switchViewers]]);
303
+ // this._model._sarGrid.invalidate();
304
+ // this._model._sarVGrid.invalidate();
305
+ this._model.invalidateGrids();
262
306
  }
307
+
308
+ invalidateSourceGrid() { this.sourceGrid.invalidate(); }
263
309
  }
264
310
 
265
311
  function dockViewers(
package/src/styles.css CHANGED
@@ -44,3 +44,11 @@
44
44
  height: unset;
45
45
  width: 100%;
46
46
  }
47
+
48
+ #pep-viewer-title {
49
+ height: 23px;
50
+ font-size: 1.2rem;
51
+ font-family: 'Roboto', 'Roboto Local', sans-serif;
52
+ color: #4D5261;
53
+ text-align: center;
54
+ }