@datagrok/peptides 0.0.1 → 0.2.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/detectors.js CHANGED
@@ -3,7 +3,7 @@ class PeptidesPackageDetectors extends DG.Package {
3
3
  //input: column col
4
4
  //output: string semType
5
5
  detectAligned(col) {
6
- const regexp = new RegExp('^((.+)?-){5,49}(\\w|\\(|\\))+$');
7
- return DG.Detector.sampleCategories(col, (s) => s.length < 1000 && regexp.test(s)) ? 'alignedSequence' : null;
6
+ const regexp = new RegExp(/^([^-^\n]*-){2,49}(\w|\(|\))+$/);
7
+ return DG.Detector.sampleCategories(col, (s) => regexp.test(s.trim())) ? 'alignedSequence' : null;
8
8
  }
9
9
  }
package/package.json CHANGED
@@ -1,27 +1,30 @@
1
1
  {
2
2
  "name": "@datagrok/peptides",
3
- "friendlyName": "Peptides",
4
- "version": "0.0.1",
3
+ "version": "0.2.0",
5
4
  "description": "",
6
5
  "dependencies": {
6
+ "@keckelt/tsne": "^1.0.2",
7
7
  "cash-dom": "latest",
8
8
  "d3": "latest",
9
- "datagrok-api": "../../js-api",
9
+ "datagrok-api": ">0.95.4",
10
10
  "dayjs": "latest",
11
+ "jaro-winkler-typescript": "^1.0.1",
11
12
  "jstat": "^1.9.5",
12
13
  "logojs-react": "^2.1.1",
13
- "rxjs": "^7.3.1",
14
- "ts-loader": "^9.2.5"
14
+ "rxjs": "^6.5.5",
15
+ "umap-js": "^1.3.3",
16
+ "@datagrok-libraries/utils": ">=0.0.9",
17
+ "@datagrok-libraries/statistics": ">=0.1.4",
18
+ "@types/d3": "^7.0.0",
19
+ "@types/jquery": "^3.5.6"
15
20
  },
16
21
  "devDependencies": {
17
- "@types/d3": "^7.0.0",
18
- "@types/jquery": "^3.5.6",
22
+ "typescript": "^4.4.4",
23
+ "ts-loader": "^9.2.5",
19
24
  "@typescript-eslint/eslint-plugin": "^4.29.1",
20
25
  "@typescript-eslint/parser": "^4.29.1",
21
26
  "eslint": "^7.32.0",
22
27
  "eslint-config-google": "^0.14.0",
23
- "ts-loader": "^9.2.5",
24
- "typescript": "^4.4.3",
25
28
  "webpack": "latest",
26
29
  "webpack-cli": "latest"
27
30
  },
@@ -31,6 +34,10 @@
31
34
  "common/ngl_viewer/ngl.js"
32
35
  ],
33
36
  "scripts": {
37
+ "link-utils": "npm link @datagrok-libraries/utils",
38
+ "link-statistics": "npm link @datagrok-libraries/statistics",
39
+ "link-api": "npm link datagrok-api",
40
+ "link-all": "npm link datagrok-api @datagrok-libraries/utils @datagrok-libraries/statistics",
34
41
  "install-dependencies": "npm install",
35
42
  "debug-peptides": "grok publish --rebuild",
36
43
  "release-peptides": "grok publish --rebuild --release",
@@ -42,7 +49,7 @@
42
49
  "release-peptides-public": "grok publish public --rebuild --release",
43
50
  "debug-peptides-local": "grok publish local --rebuild",
44
51
  "release-peptides-local": "grok publish local --rebuild --release",
45
- "lint": "eslint './src/**/*.ts'",
46
- "lint-fix": "eslint ./src/*.ts --fix"
52
+ "lint": "eslint \"./src/**/*.ts\"",
53
+ "lint-fix": "eslint \"./src/**/*.ts\" --fix"
47
54
  }
48
55
  }
@@ -0,0 +1,13 @@
1
+ #name: smiTo3D
2
+ #language: python
3
+ #input: string smiles
4
+ #output: string sdf
5
+
6
+ from rdkit.Chem import AllChem
7
+ from rdkit import Chem
8
+
9
+ mol = AllChem.MolFromSmiles(smiles)
10
+ AllChem.EmbedMolecule(mol, AllChem.ETKDG())
11
+ #AllChem.UFFOptimizeMolecule(mol)
12
+ #mol = Chem.RemoveHs(mol)
13
+ sdf = Chem.MolToMolBlock(mol)
@@ -1,10 +1,12 @@
1
+ // eslint-disable-next-line no-unused-vars
1
2
  import * as grok from 'datagrok-api/grok';
2
3
  import * as ui from 'datagrok-api/ui';
3
4
  import * as DG from 'datagrok-api/dg';
4
- import {splitAlignedPeptides} from '../split-aligned';
5
- import {tTest} from '../utils/misc';
6
- import {ChemPalette} from '../utils/chem-palette';
7
- import {setAARRenderer} from '../utils/cell-renderer';
5
+ import {splitAlignedPeptides} from './utils/split-aligned';
6
+ import {tTest} from '@datagrok-libraries/statistics/src/tests';
7
+ import {fdrcorrection} from '@datagrok-libraries/statistics/src/multiple-tests.js';
8
+ import {ChemPalette} from './utils/chem-palette';
9
+ import {setAARRenderer} from './utils/cell-renderer';
8
10
 
9
11
  const cp = new ChemPalette('grok');
10
12
 
@@ -15,19 +17,13 @@ export async function describe(
15
17
  sourceGrid: DG.Grid,
16
18
  twoColorMode: boolean,
17
19
  initialBitset: DG.BitSet | null,
18
- ): Promise<[DG.Grid, DG.Grid, DG.DataFrame] | [null, null, null]> {
20
+ ): Promise<[DG.Grid, DG.Grid, DG.DataFrame]> {
19
21
  //Split the aligned sequence into separate AARs
20
22
  let splitSeqDf: DG.DataFrame | undefined;
23
+ let invalidIndexes: number[];
21
24
  const col: DG.Column = df.columns.bySemType('alignedSequence');
22
- if (col) {
23
- splitSeqDf = splitAlignedPeptides(col);
24
- splitSeqDf.name = 'Split sequence';
25
- }
26
-
27
- if (typeof splitSeqDf === 'undefined') {
28
- return [null, null, null];
29
- }
30
-
25
+ [splitSeqDf, invalidIndexes] = splitAlignedPeptides(col);
26
+ splitSeqDf.name = 'Split sequence';
31
27
  const positionColumns = splitSeqDf.columns.names();
32
28
  const activityColumnScaled = `${activityColumn}Scaled`;
33
29
  const renderColNames: string[] = splitSeqDf.columns.names();
@@ -129,6 +125,8 @@ export async function describe(
129
125
  let otherActivity: number[];
130
126
  let testResult;
131
127
  let currentMeanDiff: number;
128
+ let pvalues: Float32Array = new Float32Array(matrixDf.rowCount).fill(1);
129
+ let pvalue = 1.;
132
130
 
133
131
  const mdCol: DG.Column = matrixDf.columns.addNewFloat('Mean difference');
134
132
  const pValCol: DG.Column = matrixDf.columns.addNewFloat('pValue');
@@ -153,9 +151,18 @@ export async function describe(
153
151
  testResult = tTest(currentActivity, otherActivity);
154
152
  // testResult = uTest(currentActivity, otherActivity);
155
153
  currentMeanDiff = testResult['Mean difference']!;
154
+ pvalue = testResult[currentMeanDiff >= 0 ? 'p-value more' : 'p-value less'];
156
155
 
157
156
  mdCol.set(i, currentMeanDiff);
158
- pValCol.set(i, testResult[currentMeanDiff >= 0 ? 'p-value more' : 'p-value less']);
157
+ pvalues[i] = pvalue;
158
+ }
159
+
160
+ if (true) {
161
+ pvalues = fdrcorrection(pvalues)[1];
162
+ }
163
+
164
+ for (let i = 0; i < pvalues.length; ++i) {
165
+ pValCol.set(i, pvalues[i]);
159
166
  }
160
167
 
161
168
  const statsDf = matrixDf.clone();
@@ -336,7 +343,6 @@ export async function describe(
336
343
  const textNum = statsDf.groupBy([col]).where(query).aggregate().get(col, 0);
337
344
  let text = `${col === 'Count' ? textNum : textNum.toFixed(5)}`;
338
345
 
339
- //@ts-ignore: I'm sure it's gonna be fine, text contains a number
340
346
  if (col === 'Count') {
341
347
  text += ` / ${peptidesCount}`;
342
348
  } else if (col === 'pValue') {
@@ -363,54 +369,16 @@ export async function describe(
363
369
  SARgrid.onCellTooltip(onCellTooltipFunc);
364
370
  SARVgrid.onCellTooltip(onCellTooltipFunc);
365
371
 
366
- for (const col of matrixDf.columns.names()) {
367
- SARgrid.col(col)!.width = SARgrid.props.rowHeight;
368
- }
372
+ sourceGrid.onCellPrepare((cell) => {
373
+ const currentRowIndex = cell.tableRowIndex;
374
+ if (currentRowIndex && invalidIndexes.includes(currentRowIndex) && !cell.isRowHeader) {
375
+ cell.style.backColor = DG.Color.lightLightGray;
376
+ }
377
+ });
369
378
 
370
- return [SARgrid, SARVgrid, statsDf];
371
- }
379
+ // for (const col of matrixDf.columns.names()) {
380
+ // SARgrid.col(col)!.width = SARgrid.props.rowHeight;
381
+ // }
372
382
 
373
- //Selects best (by mean difference) amino acids in all positions in all categories(p-value)
374
- function segregateBestAtAllCateg(originalDf: DG.DataFrame, twoColorMode:boolean):DG.DataFrame {
375
- //todo: make with group by + refactor
376
- const filteredDf = originalDf.clone(DG.BitSet.create(originalDf.rowCount, (i) => {
377
- return originalDf.get('Count', i) > 3;
378
- }));
379
- const pValueFilteredDF = filteredDf.clone(DG.BitSet.create(filteredDf.rowCount, (i) => {
380
- return filteredDf.get('pValue', i) >= 0.1 && filteredDf.get('Mean difference', i) > 0;
381
- }));
382
- let statsDfAgr = grok.data.joinTables(pValueFilteredDF, pValueFilteredDF.groupBy(['Position'])
383
- .max('Mean difference')
384
- .aggregate(), ['Mean difference', 'Position'],
385
- ['max(Mean difference)', 'Position'], pValueFilteredDF.columns.names(), [], 'inner', false);
386
- //and 'pValue' > 0.1 'pValue' < ${coef}`
387
- let lastCoef = 0.0;
388
- [0.01, 0.05, 0.1].forEach((coef)=>{
389
- const pValueFilteredDF = filteredDf.clone(DG.BitSet.create(filteredDf.rowCount, (i) => {
390
- return filteredDf.get('pValue', i) >= lastCoef &&
391
- filteredDf.get('pValue', i)< coef &&
392
- (filteredDf.get('Mean difference', i) > 0 || !twoColorMode);
393
- }));
394
- statsDfAgr = statsDfAgr.append(grok.data.joinTables(pValueFilteredDF, pValueFilteredDF.groupBy(['Position'])
395
- .max('Mean difference')
396
- .aggregate(), ['Mean difference', 'Position'],
397
- ['max(Mean difference)', 'Position'], pValueFilteredDF.columns.names(), [], 'inner', false));
398
- lastCoef = coef;
399
- });
400
- if (twoColorMode) {
401
- lastCoef = 0.0;
402
- [0.01, 0.05, 0.1, 1.01].forEach((coef) => {
403
- const pValueFilteredDF = filteredDf.clone(DG.BitSet.create(filteredDf.rowCount, (i) => {
404
- return filteredDf.get('pValue', i) >= lastCoef &&
405
- filteredDf.get('pValue', i) < coef &&
406
- filteredDf.get('Mean difference', i) <= 0;
407
- }));
408
- statsDfAgr = statsDfAgr.append(grok.data.joinTables(pValueFilteredDF, pValueFilteredDF.groupBy(['Position'])
409
- .min('Mean difference')
410
- .aggregate(), ['Mean difference', 'position'],
411
- ['min(Mean difference)', 'position'], pValueFilteredDF.columns.names(), [], 'inner', false));
412
- lastCoef = coef;
413
- });
414
- }
415
- return statsDfAgr;
383
+ return [SARgrid, SARVgrid, statsDf];
416
384
  }
package/src/package.ts CHANGED
@@ -3,20 +3,24 @@ 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 {SARViewerBase} from './peptide-sar-viewer/sar-viewer';
7
6
  import {
8
7
  AlignedSequenceCellRenderer,
9
8
  AminoAcidsCellRenderer,
10
- expandColumn,
11
- processSequence,
12
9
  } from './utils/cell-renderer';
13
- import {Logo} from './peptide-logo-viewer/logo-viewer';
14
- import {StackedBarChart, addViewerToHeader} from './stacked-barchart/stacked-barchart-viewer';
15
- import {ChemPalette} from './utils/chem-palette';
16
- // import { tTest, uTest } from './utils/misc';
10
+ import {Logo} from './viewers/logo-viewer';
11
+ import {StackedBarChart} from './viewers/stacked-barchart-viewer';
12
+
13
+ import {analyzePeptidesWidget} from './widgets/analyze-peptides';
14
+ import {PeptideSimilaritySpaceWidget} from './utils/peptide-similarity-space';
15
+ import {manualAlignmentWidget} from './widgets/manual-alignment';
16
+ import {SARViewer, SARViewerVertical} from './viewers/sar-viewer';
17
+ import { peptideMoleculeWidget } from './widgets/peptide-molecule';
17
18
 
18
19
  export const _package = new DG.Package();
19
20
  let tableGrid: DG.Grid;
21
+ let currentDf: DG.DataFrame;
22
+ let alignedSequenceCol: DG.Column;
23
+ let view: DG.TableView;
20
24
 
21
25
  async function main(chosenFile: string) {
22
26
  const pi = DG.TaskBarProgressIndicator.create('Loading Peptides');
@@ -28,25 +32,24 @@ async function main(chosenFile: string) {
28
32
  peptides.setTag('dataType', 'peptides');
29
33
  const view = grok.shell.addTableView(peptides);
30
34
  tableGrid = view.grid;
31
- peptides.onSemanticTypeDetecting.subscribe((_) => {
32
- const regexp = new RegExp('^((.+)?-){5,49}(\\w|\\(|\\))+$');
33
- for (const col of peptides.columns) {
34
- col.semType = DG.Detector.sampleCategories(col, (s) => regexp.test(s)) ? 'alignedSequence' : null;
35
- if (col.semType == 'alignedSequence') {
36
- expandColumn(col, tableGrid, (ent)=>{
37
- const subParts:string[] = ent.split('-');
38
- // eslint-disable-next-line no-unused-vars
39
- const [text, _] = processSequence(subParts);
40
- let textSize = 0;
41
- text.forEach((aar)=>{
42
- textSize += aar.length;
43
- });
44
- return textSize;
45
- });
46
- }
47
- }
48
- },
49
- );
35
+ // peptides.onSemanticTypeDetecting.subscribe((_: any) => {
36
+ // const regexp = new RegExp(/^([^-^\n]*-){2,49}(\w|\(|\))+$/);
37
+ // for (const col of peptides.columns) {
38
+ // col.semType = DG.Detector.sampleCategories(col, (s: any) => regexp.test(s.trim())) ? 'alignedSequence' : null;
39
+ // if (col.semType == 'alignedSequence') {
40
+ // expandColumn(col, tableGrid, (ent)=>{
41
+ // const subParts:string[] = ent.split('-');
42
+ // // eslint-disable-next-line no-unused-vars
43
+ // const [text, _] = processSequence(subParts);
44
+ // let textSize = 0;
45
+ // text.forEach((aar)=>{
46
+ // textSize += aar.length;
47
+ // });
48
+ // return textSize;
49
+ // });
50
+ // }
51
+ // }
52
+ // });
50
53
 
51
54
  view.name = 'PeptidesView';
52
55
 
@@ -55,7 +58,7 @@ async function main(chosenFile: string) {
55
58
  pi.close();
56
59
  }
57
60
 
58
- //name: Peptides
61
+ //name: Peptides App
59
62
  //tags: app
60
63
  export function Peptides() {
61
64
  const wikiLink = ui.link('wiki', 'https://github.com/datagrok-ai/public/blob/master/help/domains/bio/peptides.md');
@@ -82,7 +85,6 @@ export function Peptides() {
82
85
  'Use and analyse peptide sequence data to support your research:',
83
86
  );
84
87
 
85
-
86
88
  const annotationViewerDiv = ui.div();
87
89
 
88
90
  const windows = grok.shell.windows;
@@ -94,7 +96,6 @@ export function Peptides() {
94
96
  grok.shell.newView('Peptides', [
95
97
  appDescription,
96
98
  ui.info([textLink]),
97
- //ui.h2('Choose .csv file'),
98
99
  ui.div([
99
100
  ui.block25([
100
101
  ui.button('Open peptide sequences demonstration set', () => main('aligned.csv'), ''),
@@ -110,106 +111,34 @@ export function Peptides() {
110
111
  //tags: panel, widgets
111
112
  //input: column col {semType: alignedSequence}
112
113
  //output: widget result
113
- export async function analyzePeptides(col: DG.Column): Promise<DG.Widget> {
114
- // let defaultColumn: DG.Column | null = col;
115
- let tempCol = null;
116
- for (const column of col.dataFrame.columns.numerical) {
117
- column.type === DG.TYPE.FLOAT ? tempCol = column : null;
118
- }
119
- const defaultColumn: DG.Column = col.dataFrame.col('activity') || col.dataFrame.col('IC50') || tempCol;
120
-
121
- const activityScalingMethod = ui.choiceInput('Activity scaling', 'none', ['none', 'lg', '-lg']);
122
- activityScalingMethod.setTooltip('Function to apply for each value in activity column');
123
-
124
- const activityScalingMethodState = function(_: any) {
125
- activityScalingMethod.enabled =
126
- activityColumnChoice.value && DG.Stats.fromColumn(activityColumnChoice.value, col.dataFrame.filter).min > 0;
127
- };
128
- const activityColumnChoice = ui.columnInput(
129
- 'Activity column',
130
- col.dataFrame,
131
- defaultColumn,
132
- activityScalingMethodState,
133
- );
134
- activityColumnChoice.fireChanged();
135
-
136
- const startBtn = ui.button('Launch SAR', async () => {
137
- if (activityColumnChoice.value.type === DG.TYPE.FLOAT) {
138
- const options = {
139
- 'activityColumnColumnName': activityColumnChoice.value.name,
140
- 'activityScalingMethod': activityScalingMethod.value,
141
- };
142
- // @ts-ignore
143
- for (let i = 0; i < tableGrid.columns.length; i++) {
144
- const col = tableGrid.columns.byIndex(i);
145
- if (col &&
146
- col.name &&
147
- col.name != 'IC50'&&
148
- col.column?.semType != 'aminoAcids') {
149
- // @ts-ignore
150
- tableGrid.columns.byIndex(i)?.visible = false;
151
- }
152
- }
153
-
154
- //await describe(col.dataFrame, activityColumnChoice.value.name, activityScalingMethod.value, false, tableGrid);
155
-
156
- // @ts-ignore
157
-
158
-
159
- // const viewer = DG.Viewer.fromType('peptide-sar-viewer', tableGrid.table, options);
160
- // (grok.shell.v as DG.TableView).addViewer(viewer);
161
- // const refNode = (grok.shell.v as DG.TableView).dockManager.dock(viewer, 'right');
162
-
163
- // const hist = DG.Viewer.fromType('peptide-sar-viewer-vertical', tableGrid.table, options);
164
- // (grok.shell.v as DG.TableView).addViewer(hist);
165
- // (grok.shell.v as DG.TableView).dockManager.dock(hist, DG.DOCK_TYPE.DOWN, refNode);
166
-
167
- (grok.shell.v as DG.TableView).addViewer('peptide-sar-viewer', options);
168
- // (grok.shell.v as DG.TableView).addViewer('peptide-sar-viewer-vertical', options);
169
- // @ts-ignore
170
- //view.dockManager.dock(ui.divText('bottom'), 'down');
171
-
172
- // @ts-ignore
173
- //console.error(sarViewer.view.dockNode);
174
-
175
- const StackedBarchartProm = col.dataFrame.plot.fromType('StackedBarChartAA');
176
- addViewerToHeader(tableGrid, StackedBarchartProm);
177
-
178
- // tableGrid.dataFrame!.columns.names().forEach((name:string)=>{
179
- // col = tableGrid.dataFrame!.columns.byName(name);
180
- // if (col.semType == 'aminoAcids') {
181
- // let maxLen = 0;
182
- // col.categories.forEach( (ent:string)=>{
183
- // if ( ent.length> maxLen) {
184
- // maxLen = ent.length;
185
- // }
186
- // });
187
- // tableGrid.columns.byName(name)!.width = maxLen*10;
188
- // }
189
- // });
190
- } else {
191
- grok.shell.error('The activity column must be of floating point number type!');
192
- }
193
- });
194
-
195
- const viewer = await col.dataFrame.plot.fromType('peptide-logo-viewer');
196
-
197
- return new DG.Widget(ui.divV([viewer.root, ui.inputs([activityColumnChoice, activityScalingMethod]), startBtn]));
114
+ export async function peptidesPanel(col: DG.Column): Promise<DG.Widget> {
115
+ view = (grok.shell.v as DG.TableView);
116
+ tableGrid = view.grid;
117
+ currentDf = col.dataFrame;
118
+ alignedSequenceCol = col;
119
+ return await analyzePeptidesWidget(col, view, tableGrid, currentDf);
198
120
  }
199
121
 
200
122
  //name: peptide-sar-viewer
201
123
  //description: Peptides SAR Viewer
202
124
  //tags: viewer
203
125
  //output: viewer result
204
- export function sar(): SARViewerBase {
205
- return new SARViewerBase();
126
+ export function sar(): SARViewer {
127
+ return new SARViewer();
128
+ }
129
+
130
+ //name: peptide-sar-viewer-vertical
131
+ //description: Peptides Vertical SAR Viewer
132
+ //tags: viewer
133
+ //output: viewer result
134
+ export function sarVertical(): SARViewerVertical {
135
+ return new SARViewerVertical();
206
136
  }
207
137
 
208
138
  //name: StackedBarchart Widget
209
139
  //tags: panel, widgets
210
140
  //input: column col {semType: aminoAcids}
211
141
  //output: widget result
212
-
213
142
  export async function stackedBarchartWidget(col: DG.Column): Promise<DG.Widget> {
214
143
  const viewer = await col.dataFrame.plot.fromType('StackedBarChartAA');
215
144
  const panel = ui.divH([viewer.root]);
@@ -218,30 +147,13 @@ export async function stackedBarchartWidget(col: DG.Column): Promise<DG.Widget>
218
147
 
219
148
  //name: Peptide Molecule
220
149
  //tags: panel, widgets
221
- //input: string pep {semType: alignedSequence}
150
+ //input: string peptide {semType: alignedSequence}
222
151
  //output: widget result
223
- export async function pepMolGraph(pep: string): Promise<DG.Widget> {
224
- const split = pep.split('-');
225
- const mols = [];
226
- for (let i = 1; i < split.length - 1; i++) {
227
- if (split[i] in ChemPalette.AASmiles) {
228
- const aar = ChemPalette.AASmiles[split[i]];
229
- mols[i] = aar.substr(0, aar.length - 1);
230
- } else if (!split[i] || split[i] == '-') {
231
- mols[i] = '';
232
- } else {
233
- return new DG.Widget(ui.divH([]));
234
- }
235
- }
236
- console.error(mols);
237
- console.error(mols.join('') + 'COOH');
238
- const sketch = grok.chem.svgMol(mols.join('') + 'O');
239
- const panel = ui.divH([sketch]);
240
- return new DG.Widget(panel);
152
+ export async function peptideMolecule(peptide: string): Promise<DG.Widget> {
153
+ return await peptideMoleculeWidget(peptide);
241
154
  }
242
155
 
243
156
  //name: StackedBarChartAA
244
- //description: Creates an awesome viewer
245
157
  //tags: viewer
246
158
  //output: viewer result
247
159
  export function stackedBarChart(): DG.JsViewer {
@@ -270,3 +182,20 @@ export function aminoAcidsCellRenderer() {
270
182
  export function logov() {
271
183
  return new Logo();
272
184
  }
185
+
186
+ //name: Manual Alignment
187
+ //tags: panel, widgets
188
+ //input: string monomer {semType: aminoAcids}
189
+ //output: widget result
190
+ export function manualAlignment(monomer: string) {
191
+ return manualAlignmentWidget(alignedSequenceCol, currentDf);
192
+ }
193
+
194
+ //name: Peptide Space
195
+ //tags: panel, widgets
196
+ //input: column col {semType: alignedSequence}
197
+ //output: widget result
198
+ export async function peptideSpacePanel(col: DG.Column): Promise<DG.Widget> {
199
+ const widget = new PeptideSimilaritySpaceWidget(col);
200
+ return await widget.draw();
201
+ }