@datagrok/peptides 0.8.8 → 0.8.9
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 +10 -10
- package/src/describe.ts +96 -97
- package/src/model.ts +96 -75
- package/src/monomer-library.ts +10 -12
- package/src/package-test.ts +3 -3
- package/src/package.ts +39 -59
- package/src/peptides.ts +218 -108
- package/src/tests/peptide-space-test.ts +1 -1
- package/src/tests/peptides-tests.ts +6 -6
- package/src/tests/utils.ts +3 -2
- package/src/utils/cell-renderer.ts +89 -61
- package/src/utils/chem-palette.ts +66 -32
- package/src/utils/peptide-similarity-space.ts +18 -28
- package/src/utils/split-aligned.ts +55 -55
- package/src/viewers/logo-viewer.ts +5 -4
- package/src/viewers/sar-viewer.ts +88 -110
- package/src/viewers/stacked-barchart-viewer.ts +359 -359
- package/src/viewers/subst-viewer.ts +108 -73
- package/src/widgets/analyze-peptides.ts +26 -26
- package/src/widgets/manual-alignment.ts +7 -4
- package/src/widgets/multiple-sequence-alignment.ts +9 -0
- package/src/widgets/peptide-molecule.ts +5 -3
- package/src/widgets/subst-table.ts +65 -0
- package/src/workers/dimensionality-reducer.ts +1 -1
package/src/package.ts
CHANGED
|
@@ -17,14 +17,14 @@ import {manualAlignmentWidget} from './widgets/manual-alignment';
|
|
|
17
17
|
import {SARViewer, SARViewerVertical} from './viewers/sar-viewer';
|
|
18
18
|
import {peptideMoleculeWidget, getMolecule} from './widgets/peptide-molecule';
|
|
19
19
|
import {SubstViewer} from './viewers/subst-viewer';
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
20
|
+
import {substTableWidget} from './widgets/subst-table';
|
|
21
|
+
import {msaWidget} from './widgets/multiple-sequence-alignment';
|
|
22
22
|
|
|
23
23
|
export const _package = new DG.Package();
|
|
24
|
-
let
|
|
25
|
-
let
|
|
26
|
-
let
|
|
27
|
-
let
|
|
24
|
+
let currentGrid: DG.Grid;
|
|
25
|
+
let currentTable: DG.DataFrame;
|
|
26
|
+
let alignedSequenceColumn: DG.Column;
|
|
27
|
+
let currentView: DG.TableView;
|
|
28
28
|
|
|
29
29
|
async function main(chosenFile: string) {
|
|
30
30
|
const pi = DG.TaskBarProgressIndicator.create('Loading Peptides');
|
|
@@ -33,7 +33,7 @@ async function main(chosenFile: string) {
|
|
|
33
33
|
peptides.name = 'Peptides';
|
|
34
34
|
peptides.setTag('dataType', 'peptides');
|
|
35
35
|
const view = grok.shell.addTableView(peptides);
|
|
36
|
-
|
|
36
|
+
currentGrid = view.grid;
|
|
37
37
|
view.name = 'PeptidesView';
|
|
38
38
|
grok.shell.windows.showProperties = true;
|
|
39
39
|
|
|
@@ -86,14 +86,12 @@ export async function Peptides() {
|
|
|
86
86
|
//input: column col {semType: alignedSequence}
|
|
87
87
|
//output: widget result
|
|
88
88
|
export async function peptidesPanel(col: DG.Column): Promise<DG.Widget> {
|
|
89
|
-
if (col.
|
|
89
|
+
if (!(col.temp['isAnalysisApplicable'] ?? true))
|
|
90
90
|
return new DG.Widget(ui.divText('Analysis is not applicable'));
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
alignedSequenceCol = col;
|
|
96
|
-
return await analyzePeptidesWidget(col, view, tableGrid, currentDf);
|
|
92
|
+
[currentView, currentGrid, currentTable, alignedSequenceColumn] =
|
|
93
|
+
getOrDefineWIP(currentView, currentGrid, currentTable, col);
|
|
94
|
+
return await analyzePeptidesWidget(col, currentView, currentGrid, currentTable);
|
|
97
95
|
}
|
|
98
96
|
|
|
99
97
|
//name: peptide-sar-viewer
|
|
@@ -143,7 +141,9 @@ export async function peptideMolecule(peptide: string): Promise<DG.Widget> {
|
|
|
143
141
|
//input: string aar {semType: aminoAcids}
|
|
144
142
|
//output: widget result
|
|
145
143
|
export async function peptideMolecule2(aar: string): Promise<DG.Widget> {
|
|
146
|
-
|
|
144
|
+
[currentView, currentGrid, currentTable, alignedSequenceColumn] =
|
|
145
|
+
getOrDefineWIP(currentView, currentGrid, currentTable, alignedSequenceColumn);
|
|
146
|
+
const peptide = alignedSequenceColumn.get(currentTable.currentRowIdx);
|
|
147
147
|
return await peptideMolecule(peptide);
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -182,8 +182,10 @@ export function logov() {
|
|
|
182
182
|
//input: string monomer {semType: aminoAcids}
|
|
183
183
|
//output: widget result
|
|
184
184
|
export function manualAlignment(monomer: string) {
|
|
185
|
+
[currentView, currentGrid, currentTable, alignedSequenceColumn] =
|
|
186
|
+
getOrDefineWIP(currentView, currentGrid, currentTable, alignedSequenceColumn);
|
|
185
187
|
//TODO: recalculate Molfile and Molecule panels on sequence update
|
|
186
|
-
return manualAlignmentWidget(
|
|
188
|
+
return manualAlignmentWidget(alignedSequenceColumn, currentTable);
|
|
187
189
|
}
|
|
188
190
|
|
|
189
191
|
//name: Peptide Space
|
|
@@ -191,7 +193,9 @@ export function manualAlignment(monomer: string) {
|
|
|
191
193
|
//input: column col {semType: alignedSequence}
|
|
192
194
|
//output: widget result
|
|
193
195
|
export async function peptideSpacePanel(col: DG.Column): Promise<DG.Widget> {
|
|
194
|
-
|
|
196
|
+
[currentView, currentGrid, currentTable, alignedSequenceColumn] =
|
|
197
|
+
getOrDefineWIP(currentView, currentGrid, currentTable, col);
|
|
198
|
+
const widget = new PeptideSimilaritySpaceWidget(col, currentView);
|
|
195
199
|
return await widget.draw();
|
|
196
200
|
}
|
|
197
201
|
|
|
@@ -209,7 +213,9 @@ export async function peptideMolfile(peptide: string): Promise<DG.Widget> {
|
|
|
209
213
|
//input: string aar { semType: aminoAcids }
|
|
210
214
|
//output: widget result
|
|
211
215
|
export async function peptideMolfile2(aar: string): Promise<DG.Widget> {
|
|
212
|
-
|
|
216
|
+
[currentView, currentGrid, currentTable, alignedSequenceColumn] =
|
|
217
|
+
getOrDefineWIP(currentView, currentGrid, currentTable, alignedSequenceColumn);
|
|
218
|
+
const peptide = alignedSequenceColumn.get(currentTable.currentRowIdx);
|
|
213
219
|
return await peptideMolfile(peptide);
|
|
214
220
|
}
|
|
215
221
|
|
|
@@ -218,10 +224,7 @@ export async function peptideMolfile2(aar: string): Promise<DG.Widget> {
|
|
|
218
224
|
//input: column col {semType: alignedSequence}
|
|
219
225
|
//output: dataframe result
|
|
220
226
|
export async function multipleSequenceAlignment(col: DG.Column): Promise<DG.DataFrame> {
|
|
221
|
-
|
|
222
|
-
const table = col.dataFrame;
|
|
223
|
-
table.columns.add(msaCol);
|
|
224
|
-
return table;
|
|
227
|
+
return await msaWidget(col);
|
|
225
228
|
}
|
|
226
229
|
|
|
227
230
|
//name: Substitution
|
|
@@ -229,43 +232,7 @@ export async function multipleSequenceAlignment(col: DG.Column): Promise<DG.Data
|
|
|
229
232
|
//input: dataframe table {semType: Substitution}
|
|
230
233
|
//output: widget result
|
|
231
234
|
export async function peptideSubstitution(table: DG.DataFrame): Promise<DG.Widget> {
|
|
232
|
-
|
|
233
|
-
return new DG.Widget(ui.label('No difference'));
|
|
234
|
-
}
|
|
235
|
-
const peptideLength = 17;
|
|
236
|
-
let initialCol: DG.Column = table.columns.byName('Initial');
|
|
237
|
-
let substitutedCol: DG.Column = table.columns.byName('Substituted');
|
|
238
|
-
let substCounts = [];
|
|
239
|
-
let cnt = 0;
|
|
240
|
-
|
|
241
|
-
for (let i = 0; i < initialCol.length; ++i) {
|
|
242
|
-
const initialPeptide: string = initialCol.get(i);
|
|
243
|
-
const substPeptide: string = substitutedCol.get(i);
|
|
244
|
-
const concat = initialPeptide + '#' + substPeptide;
|
|
245
|
-
|
|
246
|
-
initialCol.set(i, concat);
|
|
247
|
-
|
|
248
|
-
const initialAminos = initialPeptide.split('-');
|
|
249
|
-
const substAminos = substPeptide.split('-');
|
|
250
|
-
|
|
251
|
-
for (let j = 0; j < peptideLength; ++j) {
|
|
252
|
-
if (initialAminos[j] != substAminos[j])
|
|
253
|
-
substCounts[cnt++] = j;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const countCol = DG.Column.fromInt32Array('substCounts', substCounts as unknown as Int32Array);
|
|
258
|
-
const df = DG.DataFrame.fromColumns([countCol]);
|
|
259
|
-
const barchart = df.plot.histogram({value: 'substCounts'});
|
|
260
|
-
if (barchart) {
|
|
261
|
-
barchart.root.style.width = '200px';
|
|
262
|
-
barchart.root.style.marginLeft = '30px';
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
initialCol.semType = 'alignedSequenceDifference';
|
|
266
|
-
initialCol.name = 'Substitution';
|
|
267
|
-
table.columns.remove('Substituted');
|
|
268
|
-
return new DG.Widget(ui.div([barchart?.root, table.plot.grid().root]));
|
|
235
|
+
return substTableWidget(table);
|
|
269
236
|
}
|
|
270
237
|
|
|
271
238
|
//name: alignedSequenceDifferenceCellRenderer
|
|
@@ -274,4 +241,17 @@ export async function peptideSubstitution(table: DG.DataFrame): Promise<DG.Widge
|
|
|
274
241
|
//output: grid_cell_renderer result
|
|
275
242
|
export function alignedSequenceDifferenceCellRenderer() {
|
|
276
243
|
return new AlignedSequenceDifferenceCellRenderer();
|
|
277
|
-
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function getOrDefineWIP(
|
|
247
|
+
view?: DG.TableView, grid?: DG.Grid, dataframe?: DG.DataFrame, column?: DG.Column | null,
|
|
248
|
+
): [DG.TableView, DG.Grid, DG.DataFrame, DG.Column] {
|
|
249
|
+
view ??= (grok.shell.v as DG.TableView);
|
|
250
|
+
grid ??= view.grid;
|
|
251
|
+
dataframe ??= grok.shell.t;
|
|
252
|
+
column ??= (dataframe.columns as DG.ColumnList).bySemType('alignedSequence');
|
|
253
|
+
if (column === null)
|
|
254
|
+
throw new Error('Table does not contain aligned sequence columns');
|
|
255
|
+
|
|
256
|
+
return [view, grid, dataframe, column];
|
|
257
|
+
}
|
package/src/peptides.ts
CHANGED
|
@@ -1,22 +1,165 @@
|
|
|
1
1
|
import * as ui from 'datagrok-api/ui';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
import {createPeptideSimilaritySpaceViewer} from './utils/peptide-similarity-space';
|
|
4
|
-
import {
|
|
5
|
-
import {model} from './model';
|
|
4
|
+
import {PeptidesModel} from './model';
|
|
6
5
|
import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
import {SARViewer, SARViewerVertical} from './viewers/sar-viewer';
|
|
7
|
+
import {SubstViewer} from './viewers/subst-viewer';
|
|
8
|
+
import {ChemPalette} from './utils/chem-palette';
|
|
9
|
+
import {Observable} from 'rxjs';
|
|
10
|
+
|
|
11
|
+
type viewerTypes = SARViewer | SARViewerVertical | SubstViewer;
|
|
12
|
+
export class PeptidesController {
|
|
13
|
+
private static _controllerName: string = 'peptidesController';
|
|
14
|
+
private helpUrl = '/help/domains/bio/peptides.md';
|
|
15
|
+
private _dataFrame: DG.DataFrame;
|
|
16
|
+
private _model: PeptidesModel;
|
|
17
|
+
|
|
18
|
+
private constructor(dataFrame: DG.DataFrame) {
|
|
19
|
+
this._dataFrame = dataFrame;
|
|
20
|
+
this._model = PeptidesModel.getOrInit(this._dataFrame);
|
|
21
|
+
// this.getOrInitModel(this._dataFrame);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static getInstance(dataFrame: DG.DataFrame): PeptidesController {
|
|
25
|
+
dataFrame.temp[PeptidesController.controllerName] ??= new PeptidesController(dataFrame);
|
|
26
|
+
return dataFrame.temp[PeptidesController.controllerName];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static get controllerName() {
|
|
30
|
+
return PeptidesController._controllerName;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// getOrInitModel(): PeptidesModel {
|
|
34
|
+
// this._model ??= PeptidesModel.getOrInit(this._dataFrame);
|
|
35
|
+
// return this._model;
|
|
36
|
+
// }
|
|
37
|
+
|
|
38
|
+
get onStatsDataFrameChanged(): Observable<DG.DataFrame> {
|
|
39
|
+
return this._model.onStatsDataFrameChanged;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get onSARGridChanged(): Observable<DG.Grid> {
|
|
43
|
+
return this._model.onSARGridChanged;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get onSARVGridChanged(): Observable<DG.Grid> {
|
|
47
|
+
return this._model.onSARVGridChanged;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get onGroupMappingChanged(): Observable<StringDictionary> {
|
|
51
|
+
return this._model.onGroupMappingChanged;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get onSubstFlagChanged(): Observable<boolean> {
|
|
55
|
+
return this._model.onSubstFlagChanged;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async updateDefault() {
|
|
59
|
+
await this._model.updateDefault();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
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) {
|
|
66
|
+
await this._model.updateData(
|
|
67
|
+
dataFrame, activityCol, activityScaling, sourceGrid, twoColorMode, initialBitset, grouping);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static async scaleActivity(
|
|
71
|
+
activityScaling: string, activityColumn: string, activityColumnScaled: string, df: DG.DataFrame,
|
|
72
|
+
): Promise<[DG.DataFrame, string]> {
|
|
73
|
+
// const df = sourceGrid.dataFrame!;
|
|
74
|
+
const tempDf = df.clone(null, [activityColumn]);
|
|
75
|
+
|
|
76
|
+
let formula = '${' + activityColumn + '}';
|
|
77
|
+
let newColName = activityColumn;
|
|
78
|
+
switch (activityScaling) {
|
|
79
|
+
case 'none':
|
|
80
|
+
break;
|
|
81
|
+
case 'lg':
|
|
82
|
+
formula = `Log10(${formula})`;
|
|
83
|
+
newColName = `Log10(${newColName})`;
|
|
84
|
+
break;
|
|
85
|
+
case '-lg':
|
|
86
|
+
formula = `-1*Log10(${formula})`;
|
|
87
|
+
newColName = `-Log10(${newColName})`;
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
throw new Error(`ScalingError: method \`${activityScaling}\` is not available.`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
await (tempDf.columns as DG.ColumnList).addNewCalculated(activityColumnScaled, formula);
|
|
94
|
+
|
|
95
|
+
return [tempDf, newColName];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static splitAlignedPeptides(peptideColumn: DG.Column, filter: boolean = true): [DG.DataFrame, number[]] {
|
|
99
|
+
const splitPeptidesArray: string[][] = [];
|
|
100
|
+
let currentSplitPeptide: string[];
|
|
101
|
+
let modeMonomerCount = 0;
|
|
102
|
+
let currentLength;
|
|
103
|
+
const colLength = peptideColumn.length;
|
|
104
|
+
|
|
105
|
+
// splitting data
|
|
106
|
+
const monomerLengths: {[index: string]: number} = {};
|
|
107
|
+
for (let i = 0; i < colLength; i++) {
|
|
108
|
+
currentSplitPeptide = peptideColumn.get(i).split('-').map((value: string) => value ? value : '-');
|
|
109
|
+
splitPeptidesArray.push(currentSplitPeptide);
|
|
110
|
+
currentLength = currentSplitPeptide.length;
|
|
111
|
+
monomerLengths[currentLength + ''] =
|
|
112
|
+
monomerLengths[currentLength + ''] ? monomerLengths[currentLength + ''] + 1 : 1;
|
|
113
|
+
}
|
|
114
|
+
//@ts-ignore: what I do here is converting string to number the most effective way I could find. parseInt is slow
|
|
115
|
+
modeMonomerCount = 1 * Object.keys(monomerLengths).reduce((a, b) => monomerLengths[a] > monomerLengths[b] ? a : b);
|
|
116
|
+
|
|
117
|
+
// making sure all of the sequences are of the same size
|
|
118
|
+
// and marking invalid sequences
|
|
119
|
+
let nTerminal: string;
|
|
120
|
+
const invalidIndexes: number[] = [];
|
|
121
|
+
let splitColumns: string[][] = Array.from({length: modeMonomerCount}, (_) => []);
|
|
122
|
+
modeMonomerCount--; // minus N-terminal
|
|
123
|
+
for (let i = 0; i < colLength; i++) {
|
|
124
|
+
currentSplitPeptide = splitPeptidesArray[i];
|
|
125
|
+
nTerminal = currentSplitPeptide.pop()!; // it is guaranteed that there will be at least one element
|
|
126
|
+
currentLength = currentSplitPeptide.length;
|
|
127
|
+
if (currentLength !== modeMonomerCount)
|
|
128
|
+
invalidIndexes.push(i);
|
|
129
|
+
|
|
130
|
+
for (let j = 0; j < modeMonomerCount; j++)
|
|
131
|
+
splitColumns[j].push(j < currentLength ? currentSplitPeptide[j] : '-');
|
|
132
|
+
|
|
133
|
+
splitColumns[modeMonomerCount].push(nTerminal);
|
|
134
|
+
}
|
|
135
|
+
modeMonomerCount--; // minus C-terminal
|
|
136
|
+
|
|
137
|
+
//create column names list
|
|
138
|
+
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');
|
|
141
|
+
|
|
142
|
+
// filter out the columns with the same values
|
|
143
|
+
if (filter) {
|
|
144
|
+
splitColumns = splitColumns.filter((positionArray, index) => {
|
|
145
|
+
const isRetained = new Set(positionArray).size > 1;
|
|
146
|
+
if (!isRetained)
|
|
147
|
+
columnNames.splice(index, 1);
|
|
148
|
+
|
|
149
|
+
return isRetained;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return [
|
|
154
|
+
DG.DataFrame.fromColumns(splitColumns.map((positionArray, index) => {
|
|
155
|
+
return DG.Column.fromList('string', columnNames[index], positionArray);
|
|
156
|
+
})),
|
|
157
|
+
invalidIndexes,
|
|
158
|
+
];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static getChemPalette() {
|
|
162
|
+
return ChemPalette;
|
|
20
163
|
}
|
|
21
164
|
|
|
22
165
|
/**
|
|
@@ -30,12 +173,17 @@ export class Peptides {
|
|
|
30
173
|
* @memberof Peptides
|
|
31
174
|
*/
|
|
32
175
|
async init(
|
|
33
|
-
tableGrid: DG.Grid,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
176
|
+
tableGrid: DG.Grid, view: DG.TableView, options: StringDictionary, col: DG.Column,
|
|
177
|
+
originalDfColumns: string[]) {
|
|
178
|
+
function adjustCellSize(grid: DG.Grid) {
|
|
179
|
+
const colNum = grid.columns.length;
|
|
180
|
+
for (let i = 0; i < colNum; ++i) {
|
|
181
|
+
const iCol = grid.columns.byIndex(i)!;
|
|
182
|
+
iCol.width = isNaN(parseInt(iCol.name)) ? 50 : 40;
|
|
183
|
+
}
|
|
184
|
+
grid.props.rowHeight = 20;
|
|
185
|
+
}
|
|
186
|
+
|
|
39
187
|
for (let i = 0; i < tableGrid.columns.length; i++) {
|
|
40
188
|
const aarCol = tableGrid.columns.byIndex(i);
|
|
41
189
|
if (aarCol &&
|
|
@@ -47,48 +195,31 @@ export class Peptides {
|
|
|
47
195
|
}
|
|
48
196
|
}
|
|
49
197
|
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const originalDfName = currentDf.name;
|
|
198
|
+
const originalDfName = this._dataFrame.name;
|
|
199
|
+
const dockManager = view.dockManager;
|
|
53
200
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// );
|
|
57
|
-
// const substNode = view.dockManager.dock(substViewer, DG.DOCK_TYPE.RIGHT, null, 'Substitution Analysis');
|
|
201
|
+
const sarViewer = await this._dataFrame.plot.fromType('peptide-sar-viewer', options) as SARViewer;
|
|
202
|
+
sarViewer.helpUrl = this.helpUrl;
|
|
58
203
|
|
|
59
|
-
|
|
60
|
-
|
|
204
|
+
const sarViewerVertical = await this._dataFrame.plot.fromType('peptide-sar-viewer-vertical') as SARViewerVertical;
|
|
205
|
+
sarViewerVertical.helpUrl = this.helpUrl;
|
|
61
206
|
|
|
62
|
-
const
|
|
207
|
+
const sarViewersGroup: viewerTypes[] = [sarViewer, sarViewerVertical];
|
|
63
208
|
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
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');
|
|
67
212
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
213
|
+
let nodeList = dockViewers(sarViewersGroup, DG.DOCK_TYPE.RIGHT, dockManager, DG.DOCK_TYPE.DOWN);
|
|
214
|
+
|
|
215
|
+
const substViewer = await this._dataFrame.plot.fromType(
|
|
216
|
+
'substitution-analysis-viewer', {'activityColumnName': `${options['activityColumnName']}Scaled`}) as SubstViewer;
|
|
217
|
+
const substViewersGroup = [substViewer];
|
|
71
218
|
|
|
72
|
-
const peptideSpaceViewer = await createPeptideSimilaritySpaceViewer(
|
|
73
|
-
currentDf,
|
|
74
|
-
col,
|
|
75
|
-
't-SNE',
|
|
76
|
-
'Levenshtein',
|
|
77
|
-
100,
|
|
78
|
-
view,
|
|
79
|
-
`${options['activityColumnName']}Scaled`,
|
|
80
|
-
);
|
|
81
|
-
const psNode = view.dockManager.dock(peptideSpaceViewer, DG.DOCK_TYPE.LEFT, sarNode, 'Peptide Space Viewer', 0.3);
|
|
82
|
-
|
|
83
|
-
// const layout2 = view.saveLayout();
|
|
84
|
-
|
|
85
|
-
const nodeList = [sarNode, sarVNode, psNode];
|
|
86
|
-
|
|
87
|
-
const StackedBarchartProm = currentDf.plot.fromType('StackedBarChartAA');
|
|
88
|
-
addViewerToHeader(tableGrid, StackedBarchartProm);
|
|
89
219
|
tableGrid.props.allowEdit = false;
|
|
220
|
+
adjustCellSize(tableGrid);
|
|
90
221
|
|
|
91
|
-
const hideIcon = ui.iconFA('window-close', () => {
|
|
222
|
+
const hideIcon = ui.iconFA('window-close', () => {
|
|
92
223
|
const viewers = [];
|
|
93
224
|
for (const viewer of view.viewers) {
|
|
94
225
|
if (viewer.type !== DG.VIEWER.GRID)
|
|
@@ -96,76 +227,55 @@ export class Peptides {
|
|
|
96
227
|
}
|
|
97
228
|
viewers.forEach((v) => v.close());
|
|
98
229
|
|
|
99
|
-
const cols = (
|
|
230
|
+
const cols = (this._dataFrame.columns as DG.ColumnList);
|
|
100
231
|
for (const colName of cols.names()) {
|
|
101
232
|
if (!originalDfColumns.includes(colName))
|
|
102
233
|
cols.remove(colName);
|
|
103
234
|
}
|
|
104
235
|
|
|
105
|
-
|
|
106
|
-
|
|
236
|
+
this._dataFrame.selection.setAll(false);
|
|
237
|
+
this._dataFrame.filter.setAll(true);
|
|
107
238
|
|
|
108
239
|
tableGrid.setOptions({'colHeaderHeight': 20});
|
|
109
240
|
tableGrid.columns.setVisible(originalDfColumns);
|
|
110
241
|
tableGrid.props.allowEdit = true;
|
|
111
|
-
|
|
242
|
+
this._dataFrame.name = originalDfName;
|
|
112
243
|
|
|
113
244
|
view.setRibbonPanels(ribbonPanels);
|
|
114
245
|
}, 'Close viewers and restore dataframe');
|
|
115
246
|
|
|
116
247
|
let isSA = false;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// $(switchViewers).removeClass('fa-toggle-on');
|
|
126
|
-
// $(switchViewers).addClass('fa-toggle-off');
|
|
127
|
-
// }
|
|
128
|
-
// isSA = !isSA;
|
|
129
|
-
// });
|
|
130
|
-
const switchViewers = ui.iconFA('toggle-on', async () => {
|
|
131
|
-
currentDf.filter.copyFrom(initialFiter);
|
|
132
|
-
currentDf.selection.setAll(false);
|
|
133
|
-
nodeList.forEach((node) => view.dockManager.close(node));
|
|
134
|
-
nodeList.length = 0;
|
|
135
|
-
if (isSA) {
|
|
136
|
-
const sarViewer = view.addViewer('peptide-sar-viewer', options);
|
|
137
|
-
sarViewer.helpUrl = helpUrl;
|
|
138
|
-
const sarNode = view.dockManager.dock(sarViewer, DG.DOCK_TYPE.DOWN, null, 'SAR Viewer');
|
|
139
|
-
|
|
140
|
-
const sarViewerVertical = view.addViewer('peptide-sar-viewer-vertical');
|
|
141
|
-
sarViewerVertical.helpUrl = helpUrl;
|
|
142
|
-
const sarVNode = view.dockManager.dock(sarViewerVertical, DG.DOCK_TYPE.RIGHT, sarNode, 'SAR Vertical Viewer');
|
|
143
|
-
|
|
144
|
-
const peptideSpaceViewer = await createPeptideSimilaritySpaceViewer(
|
|
145
|
-
currentDf, col, 't-SNE', 'Levenshtein', 100, view, `${options['activityColumnName']}Scaled`);
|
|
146
|
-
const psNode = view.dockManager.dock(
|
|
147
|
-
peptideSpaceViewer, DG.DOCK_TYPE.LEFT, sarNode, 'Peptide Space Viewer', 0.3);
|
|
148
|
-
|
|
149
|
-
nodeList.push(sarNode);
|
|
150
|
-
nodeList.push(sarVNode);
|
|
151
|
-
nodeList.push(psNode);
|
|
152
|
-
|
|
153
|
-
$(switchViewers).removeClass('fa-toggle-off');
|
|
154
|
-
$(switchViewers).addClass('fa-toggle-on');
|
|
155
|
-
} else {
|
|
156
|
-
const substViewer = view.addViewer(
|
|
157
|
-
'substitution-analysis-viewer', {'activityColumnName': `${options['activityColumnName']}Scaled`},
|
|
158
|
-
);
|
|
159
|
-
substViewer.helpUrl = helpUrl;
|
|
160
|
-
nodeList.push(view.dockManager.dock(substViewer, DG.DOCK_TYPE.DOWN, null, 'Substitution Analysis'));
|
|
161
|
-
$(switchViewers).removeClass('fa-toggle-on');
|
|
162
|
-
$(switchViewers).addClass('fa-toggle-off');
|
|
163
|
-
}
|
|
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());
|
|
164
256
|
isSA = !isSA;
|
|
165
|
-
|
|
257
|
+
nodeList = dockViewers(getCurrentViewerGroup(), DG.DOCK_TYPE.LEFT, dockManager, DG.DOCK_TYPE.DOWN);
|
|
258
|
+
}, 'Toggle viewer group');
|
|
166
259
|
|
|
167
260
|
const ribbonPanels = view.getRibbonPanels();
|
|
168
261
|
view.setRibbonPanels([[hideIcon, switchViewers]]);
|
|
169
|
-
// view.setRibbonPanels([[hideIcon]]);
|
|
170
262
|
}
|
|
171
263
|
}
|
|
264
|
+
|
|
265
|
+
function dockViewers(
|
|
266
|
+
viewerList: viewerTypes[], attachDirection: DG.DockType, dockManager: DG.DockManager,
|
|
267
|
+
initialAttachDirection?: DG.DockType): DG.DockNode[] | null {
|
|
268
|
+
const viewerListLength = viewerList.length;
|
|
269
|
+
if (viewerListLength === 0)
|
|
270
|
+
return null;
|
|
271
|
+
|
|
272
|
+
let currentViewer = viewerList[0];
|
|
273
|
+
const nodeList = [dockManager.dock(currentViewer, initialAttachDirection, null, currentViewer.name ?? '')];
|
|
274
|
+
const ratio = 1 / viewerListLength;
|
|
275
|
+
|
|
276
|
+
for (let i = 1; i < viewerListLength; i++) {
|
|
277
|
+
currentViewer = viewerList[i];
|
|
278
|
+
nodeList.push(dockManager.dock(currentViewer, attachDirection, nodeList[i - 1], currentViewer.name ?? '', ratio));
|
|
279
|
+
}
|
|
280
|
+
return nodeList;
|
|
281
|
+
}
|
|
@@ -11,7 +11,7 @@ import {aligned1} from './test-data';
|
|
|
11
11
|
|
|
12
12
|
import * as DG from 'datagrok-api/dg';
|
|
13
13
|
import * as grok from 'datagrok-api/grok';
|
|
14
|
-
import {
|
|
14
|
+
import {StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
15
15
|
|
|
16
16
|
export const _package = new DG.Package();
|
|
17
17
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {after, before, category, test} from '@datagrok-libraries/utils/src/test';
|
|
2
2
|
import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
|
|
3
|
-
import {splitAlignedPeptides} from '../utils/split-aligned';
|
|
3
|
+
// import {splitAlignedPeptides} from '../utils/split-aligned';
|
|
4
4
|
import * as DG from 'datagrok-api/dg';
|
|
5
5
|
import * as grok from 'datagrok-api/grok';
|
|
6
|
-
import {
|
|
6
|
+
import {PeptidesController} from '../peptides';
|
|
7
7
|
import {describe} from '../describe';
|
|
8
8
|
import {analyzePeptidesWidget} from '../widgets/analyze-peptides';
|
|
9
9
|
import {manualAlignmentWidget} from '../widgets/manual-alignment';
|
|
@@ -52,7 +52,7 @@ category('peptides', async () => {
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
test('utils.split-sequence', async () => {
|
|
55
|
-
splitAlignedPeptides(peptidesDf.getCol('AlignedSequence'));
|
|
55
|
+
PeptidesController.splitAlignedPeptides(peptidesDf.getCol('AlignedSequence'));
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
test('describe', async () => {
|
|
@@ -61,9 +61,9 @@ category('peptides', async () => {
|
|
|
61
61
|
DG.BitSet.create(peptidesDf.rowCount, (i) => i % 2 === 0), true);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
test('Peptides-
|
|
65
|
-
const peptides =
|
|
66
|
-
peptides.init(peptidesGrid, pepView,
|
|
64
|
+
test('Peptides-controller', async () => {
|
|
65
|
+
const peptides = PeptidesController.getInstance(peptidesDf);
|
|
66
|
+
peptides.init(peptidesGrid, pepView, options, asCol, peptidesDf.columns.names());
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
test('panel.peptides', async () => {
|
package/src/tests/utils.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createDimensinalityReducingWorker,
|
|
7
7
|
} from '@datagrok-libraries/ml/src/workers/dimensionality-reducing-worker-creator';
|
|
8
8
|
import {runKalign} from '../utils/multiple-sequence-alignment';
|
|
9
|
-
import {
|
|
9
|
+
import {StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Tests if a table has non zero rows and columns.
|
|
@@ -48,7 +48,8 @@ export async function _testDimensionalityReducer(columnData: Array<string>, meth
|
|
|
48
48
|
let embcols;
|
|
49
49
|
|
|
50
50
|
try {
|
|
51
|
-
embcols = await createDimensinalityReducingWorker(
|
|
51
|
+
embcols = await createDimensinalityReducingWorker(
|
|
52
|
+
{data: columnData, metric: measure as StringMetrics}, method, cyclesCount);
|
|
52
53
|
} catch (error) {
|
|
53
54
|
noException = false;
|
|
54
55
|
}
|