@datagrok/peptides 1.3.8 → 1.3.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.
@@ -0,0 +1,91 @@
1
+ import * as DG from 'datagrok-api/dg';
2
+
3
+ import * as C from './constants';
4
+ import * as type from './types';
5
+ import {getTypedArrayConstructor} from './misc';
6
+
7
+ //TODO: move out
8
+ export function findMutations(activityCol: DG.Column<number>, monomerColumns: DG.Column<string>[],
9
+ settings: type.PeptidesSettings = {}): type.SubstitutionsInfo {
10
+ const nCols = monomerColumns.length;
11
+ if (nCols == 0)
12
+ throw new Error(`PepAlgorithmError: Couldn't find any column of semType '${C.SEM_TYPES.MONOMER}'`);
13
+
14
+ const substitutionsInfo: type.SubstitutionsInfo = new Map();
15
+ const nRows = activityCol.length;
16
+ for (let seq1Idx = 0; seq1Idx < nRows - 1; seq1Idx++) {
17
+ for (let seq2Idx = seq1Idx + 1; seq2Idx < nRows; seq2Idx++) {
18
+ let substCounter = 0;
19
+ const activityValSeq1 = activityCol.get(seq1Idx)!;
20
+ const activityValSeq2 = activityCol.get(seq2Idx)!;
21
+ const delta = activityValSeq1 - activityValSeq2;
22
+ if (Math.abs(delta) < (settings.minActivityDelta ?? 0))
23
+ continue;
24
+
25
+ let substCounterFlag = false;
26
+ const tempData: { pos: string, seq1monomer: string, seq2monomer: string, seq1Idx: number, seq2Idx: number }[] =
27
+ [];
28
+ for (const currentPosCol of monomerColumns) {
29
+ const seq1monomer = currentPosCol.get(seq1Idx)!;
30
+ const seq2monomer = currentPosCol.get(seq2Idx)!;
31
+ if (seq1monomer == seq2monomer)
32
+ continue;
33
+
34
+ substCounter++;
35
+ substCounterFlag = substCounter > (settings.maxMutations ?? 1);
36
+ if (substCounterFlag)
37
+ break;
38
+
39
+ tempData.push({
40
+ pos: currentPosCol.name,
41
+ seq1monomer: seq1monomer,
42
+ seq2monomer: seq2monomer,
43
+ seq1Idx: seq1Idx,
44
+ seq2Idx: seq2Idx,
45
+ });
46
+ }
47
+
48
+ if (substCounterFlag || substCounter == 0)
49
+ continue;
50
+
51
+ for (const tempDataElement of tempData) {
52
+ const position = tempDataElement.pos;
53
+
54
+ //Working with seq1monomer
55
+ const seq1monomer = tempDataElement.seq1monomer;
56
+ if (!substitutionsInfo.has(seq1monomer))
57
+ substitutionsInfo.set(seq1monomer, new Map());
58
+
59
+ let positionsMap = substitutionsInfo.get(seq1monomer)!;
60
+ if (!positionsMap.has(position))
61
+ positionsMap.set(position, new Map());
62
+
63
+ let indexes = positionsMap.get(position)!;
64
+
65
+ !indexes.has(seq1Idx) ? indexes.set(seq1Idx, [seq2Idx]) : (indexes.get(seq1Idx)! as number[]).push(seq2Idx);
66
+
67
+ //Working with seq2monomer
68
+ const seq2monomer = tempDataElement.seq2monomer;
69
+ if (!substitutionsInfo.has(seq2monomer))
70
+ substitutionsInfo.set(seq2monomer, new Map());
71
+
72
+ positionsMap = substitutionsInfo.get(seq2monomer)!;
73
+ if (!positionsMap.has(position))
74
+ positionsMap.set(position, new Map());
75
+
76
+ indexes = positionsMap.get(position)!;
77
+ !indexes.has(seq2Idx) ? indexes.set(seq2Idx, [seq1Idx]) : (indexes.get(seq2Idx)! as number[]).push(seq1Idx);
78
+ }
79
+ }
80
+ }
81
+
82
+ const TypedArray = getTypedArrayConstructor(nRows);
83
+ for (const positionMap of substitutionsInfo.values()) {
84
+ for (const indexMap of positionMap.values()) {
85
+ for (const [index, indexArray] of indexMap.entries())
86
+ indexMap.set(index, new TypedArray(indexArray));
87
+ }
88
+ }
89
+
90
+ return substitutionsInfo;
91
+ }
@@ -1,8 +1,8 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
- import * as bio from '@datagrok-libraries/bio';
3
2
 
4
3
  import * as C from './constants';
5
4
  import * as types from './types';
5
+ import * as bio from '@datagrok-libraries/bio';
6
6
 
7
7
  function renderCellSelection(canvasContext: CanvasRenderingContext2D, bound: DG.Rect): void {
8
8
  canvasContext.strokeStyle = '#000';
@@ -100,86 +100,40 @@ export function renderLogoSummaryCell(canvasContext: CanvasRenderingContext2D, c
100
100
  renderCellSelection(canvasContext, bound);
101
101
  }
102
102
 
103
- export function renderBarchart(ctx: CanvasRenderingContext2D, col: DG.Column, monomerColStats: types.MonomerColStats,
104
- bounds: DG.Rect, max: number): types.BarCoordinates {
105
- let sum = col.length - (monomerColStats['-']?.count ?? 0);
106
- const colorPalette = bio.getPaletteByType(col.tags[C.TAGS.ALPHABET]);
107
- const name = col.name;
108
- const colNameSize = ctx.measureText(name);
109
- const margin = 0.2;
110
- const innerMargin = 0.02;
111
- const selectLineRatio = 0.1;
112
- const fontSize = 11;
113
-
114
- const xMargin = bounds.x + bounds.width * margin;
115
- const yMargin = bounds.y + bounds.height * margin / 4;
116
- const wMargin = bounds.width - bounds.width * margin * 2;
117
- const hMargin = bounds.height - bounds.height * margin;
118
- const barWidth = 10;
119
- ctx.fillStyle = 'black';
120
- ctx.textBaseline = 'top';
121
- ctx.font = `${hMargin * margin / 2}px`;
122
- ctx.fillText(name, xMargin + (wMargin - colNameSize.width) / 2, yMargin + hMargin + hMargin * margin / 4);
123
-
124
-
125
- const barCoordinates: types.BarCoordinates = {};
126
-
127
- const xStart = xMargin + (wMargin - barWidth) / 2;
128
- for (const [monomer, monomerStats] of Object.entries(monomerColStats)) {
129
- if (monomer == '-')
130
- continue;
131
-
132
- const count = monomerStats.count;
133
- const sBarHeight = hMargin * count / max;
134
- const gapSize = sBarHeight * innerMargin;
135
- const verticalShift = (max - sum) / max;
136
- const textSize = ctx.measureText(monomer);
137
- const subBarHeight = sBarHeight - gapSize;
138
- const yStart = yMargin + hMargin * verticalShift + gapSize / 2;
139
- barCoordinates[monomer] = new DG.Rect(xStart, yStart, barWidth, subBarHeight);
140
-
141
- const color = colorPalette.get(monomer);
142
- ctx.strokeStyle = color;
143
- ctx.fillStyle = color;
144
-
145
- if (textSize.width <= subBarHeight) {
146
- if (color != bio.SeqPaletteBase.undefinedColor)
147
- ctx.fillRect(xStart, yStart, barWidth, subBarHeight);
148
- else {
149
- ctx.strokeRect(xStart + 0.5, yStart, barWidth - 1, subBarHeight);
150
- barCoordinates[monomer].x -= 0.5;
151
- barCoordinates[monomer].width -= 1;
152
- }
153
-
154
- const leftMargin = (wMargin - (monomer.length > 1 ? fontSize : textSize.width - 8)) / 2;
155
- const absX = xMargin + leftMargin;
156
- const absY = yStart + subBarHeight / 2 + (monomer.length == 1 ? 4 : 0);
157
- const origTransform = ctx.getTransform();
158
-
159
- if (monomer.length > 1) {
160
- ctx.translate(absX, absY);
161
- ctx.rotate(Math.PI / 2);
162
- ctx.translate(-absX, -absY);
163
- }
164
-
165
- ctx.fillStyle = 'black';
166
- ctx.font = `${fontSize}px monospace`;
167
- ctx.textAlign = 'center';
168
- ctx.textBaseline = 'bottom';
169
- ctx.fillText(monomer, absX, absY);
170
- ctx.setTransform(origTransform);
171
- } else
172
- ctx.fillRect(xStart, yStart, barWidth, subBarHeight);
173
-
174
- const selectedCount = monomerStats.selected;
175
- if (selectedCount) {
176
- ctx.fillStyle = 'rgb(255,165,0)';
177
- ctx.fillRect(xStart - wMargin * selectLineRatio * 2, yStart,
178
- barWidth * selectLineRatio, hMargin * selectedCount / max - gapSize);
179
- }
180
103
 
181
- sum -= count;
104
+ export function drawLogoInBounds(ctx: CanvasRenderingContext2D, bounds: DG.Rect, statsInfo: types.StatsInfo,
105
+ rowCount: number, cp: bio.SeqPalette, drawOptions: types.DrawOptions = {}): void {
106
+ drawOptions.fontStyle ??= '16px Roboto, Roboto Local, sans-serif';
107
+ drawOptions.upperLetterHeight ??= 12.2;
108
+ drawOptions.upperLetterAscent ??= 0.25;
109
+ drawOptions.marginVertical ??= 5;
110
+ drawOptions.marginHorizontal ??= 5;
111
+
112
+ const totalSpaceBetweenLetters = (statsInfo.orderedIndexes.length - 1) * drawOptions.upperLetterAscent;
113
+ const barHeight = bounds.height - 2 * drawOptions.marginVertical - totalSpaceBetweenLetters;
114
+ const leftShift = drawOptions.marginHorizontal * 2;
115
+ const barWidth = bounds.width - leftShift - drawOptions.marginHorizontal;
116
+ const xStart = bounds.x + leftShift;
117
+ let currentY = bounds.y + drawOptions.marginVertical;
118
+
119
+
120
+ for (const index of statsInfo.orderedIndexes) {
121
+ const monomer = statsInfo.monomerCol.get(index)!;
122
+ const monomerHeight = barHeight * (statsInfo.countCol.get(index)! / rowCount);
123
+
124
+ ctx.resetTransform();
125
+ if (monomer !== '-') {
126
+ const monomerTxt = bio.monomerToShort(monomer, 5);
127
+ const mTm: TextMetrics = ctx.measureText(monomerTxt);
128
+
129
+ ctx.fillStyle = cp.get(monomer) ?? cp.get('other');
130
+ ctx.textAlign = 'left';
131
+ ctx.textBaseline = 'top';
132
+ ctx.font = drawOptions.fontStyle;
133
+ // Hacks to scale uppercase characters to target rectangle
134
+ ctx.setTransform(barWidth / mTm.width, 0, 0, monomerHeight / drawOptions.upperLetterHeight, xStart, currentY);
135
+ ctx.fillText(monomerTxt, 0, 0);
136
+ }
137
+ currentY += monomerHeight + drawOptions.upperLetterAscent;
182
138
  }
183
-
184
- return barCoordinates;
185
139
  }
@@ -1,5 +1,4 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
- import * as bio from '@datagrok-libraries/bio';
3
2
 
4
3
  export type DataFrameDict = {[key: string]: DG.DataFrame};
5
4
 
@@ -8,13 +7,31 @@ export type UTypedArray = Uint8Array | Uint16Array | Uint32Array;
8
7
  export type SubstitutionsInfo = Map<string, Map<string, Map<number, number[] | UTypedArray>>>;
9
8
  export type PositionToAARList = {[postiton: string]: string[]};
10
9
 
11
- export type HELMMonomer = bio.Monomer;
12
-
13
10
  export type MonomerColStats = {[monomer: string]: {count: number, selected: number}};
14
11
  export type MonomerDfStats = {[position: string]: MonomerColStats};
15
12
 
16
- export type BarCoordinates = {[monomer: string]: DG.Rect};
17
-
18
13
  export type ScalingMethods = 'none' | 'lg' | '-lg';
19
- export type PeptidesSettings =
20
- {scaling?: ScalingMethods, isBidirectional?: boolean, maxMutations?: number, minActivityDelta?: number};
14
+ export type PeptidesSettings = {
15
+ scaling?: ScalingMethods,
16
+ isBidirectional?: boolean,
17
+ maxMutations?: number,
18
+ minActivityDelta?: number,
19
+ columns?: {[col: string]: string},
20
+ };
21
+
22
+ export type DrawOptions = {
23
+ fontStyle?: string,
24
+ upperLetterHeight?: number,
25
+ upperLetterAscent?: number,
26
+ bounds?: DG.Rect,
27
+ textAlign?: CanvasTextAlign,
28
+ textBaseline?: CanvasTextBaseline,
29
+ marginVertical?: number,
30
+ marginHorizontal?: number,
31
+ };
32
+
33
+ export type StatsInfo = {
34
+ monomerCol: DG.Column<string>,
35
+ countCol: DG.Column<number>,
36
+ orderedIndexes: Int32Array,
37
+ }
@@ -1,11 +1,11 @@
1
1
  import * as ui from 'datagrok-api/ui';
2
2
  import * as grok from 'datagrok-api/grok';
3
3
  import * as DG from 'datagrok-api/dg';
4
- import * as bio from '@datagrok-libraries/bio';
5
4
 
6
5
  import $ from 'cash-dom';
7
6
  import '../styles.css';
8
7
  import {PeptidesModel} from '../model';
8
+ import {splitAlignedSequences} from '@datagrok-libraries/bio';
9
9
 
10
10
  /** Manual sequence alignment widget.
11
11
  *
@@ -19,7 +19,7 @@ export function manualAlignmentWidget(alignedSequenceCol: DG.Column<string>, cur
19
19
  const applyChangesBtn = ui.button('Apply', async () => {
20
20
  const newSequence = sequenceInput.value;
21
21
  const affectedRowIndex = currentDf.currentRowIdx;
22
- const splitSequence = bio.splitAlignedSequences(DG.Column.fromStrings('splitSequence', [newSequence]));
22
+ const splitSequence = splitAlignedSequences(DG.Column.fromStrings('splitSequence', [newSequence]));
23
23
 
24
24
  alignedSequenceCol.set(affectedRowIndex, newSequence);
25
25
  for (const part of splitSequence.columns) {
@@ -1,13 +1,13 @@
1
1
  import * as grok from 'datagrok-api/grok';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
- import * as bio from '@datagrok-libraries/bio';
5
4
 
6
5
  import '../styles.css';
7
6
  import * as C from '../utils/constants';
8
7
  import {PeptidesModel} from '../model';
9
8
  import $ from 'cash-dom';
10
9
  import {scaleActivity} from '../utils/misc';
10
+ import {WebLogoViewer} from '@datagrok-libraries/bio';
11
11
 
12
12
  /** Peptide analysis widget.
13
13
  *
@@ -97,7 +97,7 @@ Promise<{host: HTMLElement, callback: () => Promise<void>}> {
97
97
  inputElements.push(startBtn);
98
98
  }
99
99
 
100
- const viewer = await df.plot.fromType('WebLogo') as bio.WebLogoViewer;
100
+ const viewer = await df.plot.fromType('WebLogo') as WebLogoViewer;
101
101
  viewer.root.style.setProperty('height', '130px');
102
102
  const logoHost = ui.div();
103
103
  $(logoHost).empty().append(viewer.root);
@@ -149,6 +149,7 @@ export async function startAnalysis(activityColumn: DG.Column<number>, peptidesC
149
149
  }
150
150
 
151
151
  newDf.setTag('monomerType', monomerType);
152
+ newDf.setTag('newAnalysis', '1');
152
153
  model = await PeptidesModel.getInstance(newDf);
153
154
  } else
154
155
  grok.shell.error('The activity column must be of numeric type!');
@@ -5,27 +5,59 @@ import * as DG from 'datagrok-api/dg';
5
5
  import * as type from '../utils/types';
6
6
  import {PeptidesModel} from '../model';
7
7
 
8
+ import $ from 'cash-dom';
9
+ import wu from 'wu';
10
+
8
11
  //TODO: show sliderInput values
9
12
  export function getSettingsDialog(model: PeptidesModel): DG.Dialog {
13
+ const accordion = ui.accordion();
10
14
  const settings = model.settings;
11
- const result: type.PeptidesSettings = {};
15
+ const result: type.PeptidesSettings = {columns: {}};
12
16
  const activityScaling = ui.choiceInput('Activity scaling', settings.scaling ?? 'none', ['none', 'lg', '-lg'],
13
17
  () => result.scaling = activityScaling.value! as type.ScalingMethods);
14
18
  const bidirectionalAnalysis = ui.boolInput('Bidirectional analysis', settings.isBidirectional ?? false,
15
19
  () => result.isBidirectional = bidirectionalAnalysis.value!);
20
+ accordion.addPane('General', () => ui.inputs([activityScaling, bidirectionalAnalysis]), true);
21
+
16
22
  const maxMutations = ui.sliderInput('Max mutations', settings.maxMutations ?? 1, 0, 50, () => {
17
23
  const val = Math.round(maxMutations.value!);
24
+ $(maxMutations.root).find('label.ui-input-description').remove();
18
25
  result.maxMutations = val;
26
+ maxMutations.addPostfix(val.toString());
19
27
  });
28
+ maxMutations.addPostfix((settings.maxMutations ?? 1).toString());
20
29
  const minActivityDelta = ui.sliderInput('Min activity delta', settings.minActivityDelta ?? 0, 0, 100, () => {
21
30
  const val = Math.round(minActivityDelta.value!);
22
31
  result.minActivityDelta = val;
32
+ $(minActivityDelta.root).find('label.ui-input-description').remove();
33
+ minActivityDelta.addPostfix(val.toString());
23
34
  });
24
-
25
- const accordion = ui.accordion();
26
- accordion.addPane('General', () => ui.inputs([activityScaling, bidirectionalAnalysis]), true);
35
+ minActivityDelta.addPostfix((settings.minActivityDelta ?? 0).toString());
27
36
  accordion.addPane('Mutation Cliffs', () => ui.inputs([maxMutations, minActivityDelta]), true);
28
37
 
38
+ const inputsRows: HTMLElement[] = [];
39
+ for (const col of model.df.columns.numerical) {
40
+ const isIncluded = ui.boolInput('', typeof (settings.columns ?? {})[col.name] !== 'undefined',
41
+ () => {
42
+ if (isIncluded)
43
+ result.columns![col.name] = aggregation.stringValue;
44
+ else
45
+ delete result.columns![col.name];
46
+ }) as DG.InputBase<boolean>;
47
+ const aggregation = ui.choiceInput('Aggregation', (settings.columns ?? {})[col.name] ?? 'avg', Object.values(DG.STATS),
48
+ () => {
49
+ if (isIncluded)
50
+ result.columns![col.name] = aggregation.stringValue;
51
+ else
52
+ delete result.columns![col.name];
53
+ }) as DG.InputBase<string>;
54
+ $(aggregation.root).find('label').css('width', 'auto');
55
+ const inputsRow = ui.inputsRow(col.name, [isIncluded, aggregation]);
56
+ $(inputsRow).find('div.ui-div').css('display', 'inline-flex');
57
+ inputsRows.push(inputsRow);
58
+ }
59
+ accordion.addPane('Columns to include', () => ui.divV(inputsRows), false);
60
+
29
61
  const dialog = ui.dialog('Peptides settings').add(accordion);
30
62
  dialog.root.style.width = '400px';
31
63
  dialog.onOK(() => model.settings = result);
@@ -33,5 +65,3 @@ export function getSettingsDialog(model: PeptidesModel): DG.Dialog {
33
65
 
34
66
  return dialog.show();
35
67
  }
36
-
37
-
@@ -0,0 +1,276 @@
1
+ <html><head><meta charset="utf-8"/><title>Peptides Test Report. Datagrok version datagrok/datagrok:latest SHA=62cc009524f3. Commit 0949dc07.</title><style type="text/css">html,
2
+ body {
3
+ font-family: Arial, Helvetica, sans-serif;
4
+ font-size: 1rem;
5
+ margin: 0;
6
+ padding: 0;
7
+ color: #333;
8
+ }
9
+ body {
10
+ padding: 2rem 1rem;
11
+ font-size: 0.85rem;
12
+ }
13
+ #jesthtml-content {
14
+ margin: 0 auto;
15
+ max-width: 70rem;
16
+ }
17
+ header {
18
+ display: flex;
19
+ align-items: center;
20
+ }
21
+ #title {
22
+ margin: 0;
23
+ flex-grow: 1;
24
+ }
25
+ #logo {
26
+ height: 4rem;
27
+ }
28
+ #timestamp {
29
+ color: #777;
30
+ margin-top: 0.5rem;
31
+ }
32
+
33
+ /** SUMMARY */
34
+ #summary {
35
+ color: #333;
36
+ margin: 2rem 0;
37
+ display: flex;
38
+ font-family: monospace;
39
+ font-size: 1rem;
40
+ }
41
+ #summary > div {
42
+ margin-right: 2rem;
43
+ background: #eee;
44
+ padding: 1rem;
45
+ min-width: 15rem;
46
+ }
47
+ #summary > div:last-child {
48
+ margin-right: 0;
49
+ }
50
+ @media only screen and (max-width: 720px) {
51
+ #summary {
52
+ flex-direction: column;
53
+ }
54
+ #summary > div {
55
+ margin-right: 0;
56
+ margin-top: 2rem;
57
+ }
58
+ #summary > div:first-child {
59
+ margin-top: 0;
60
+ }
61
+ }
62
+
63
+ .summary-total {
64
+ font-weight: bold;
65
+ margin-bottom: 0.5rem;
66
+ }
67
+ .summary-passed {
68
+ color: #4f8a10;
69
+ border-left: 0.4rem solid #4f8a10;
70
+ padding-left: 0.5rem;
71
+ }
72
+ .summary-failed,
73
+ .summary-obsolete-snapshots {
74
+ color: #d8000c;
75
+ border-left: 0.4rem solid #d8000c;
76
+ padding-left: 0.5rem;
77
+ }
78
+ .summary-pending {
79
+ color: #9f6000;
80
+ border-left: 0.4rem solid #9f6000;
81
+ padding-left: 0.5rem;
82
+ }
83
+ .summary-empty {
84
+ color: #999;
85
+ border-left: 0.4rem solid #999;
86
+ }
87
+
88
+ .test-result {
89
+ padding: 1rem;
90
+ margin-bottom: 0.25rem;
91
+ }
92
+ .test-result:last-child {
93
+ border: 0;
94
+ }
95
+ .test-result.passed {
96
+ background-color: #dff2bf;
97
+ color: #4f8a10;
98
+ }
99
+ .test-result.failed {
100
+ background-color: #ffbaba;
101
+ color: #d8000c;
102
+ }
103
+ .test-result.pending {
104
+ background-color: #ffdf61;
105
+ color: #9f6000;
106
+ }
107
+
108
+ .test-info {
109
+ display: flex;
110
+ justify-content: space-between;
111
+ }
112
+ .test-suitename {
113
+ width: 20%;
114
+ text-align: left;
115
+ font-weight: bold;
116
+ word-break: break-word;
117
+ }
118
+ .test-title {
119
+ width: 40%;
120
+ text-align: left;
121
+ font-style: italic;
122
+ }
123
+ .test-status {
124
+ width: 20%;
125
+ text-align: right;
126
+ }
127
+ .test-duration {
128
+ width: 10%;
129
+ text-align: right;
130
+ font-size: 0.75rem;
131
+ }
132
+
133
+ .failureMessages {
134
+ padding: 0 1rem;
135
+ margin-top: 1rem;
136
+ border-top: 1px dashed #d8000c;
137
+ }
138
+ .failureMessages.suiteFailure {
139
+ border-top: none;
140
+ }
141
+ .failureMsg {
142
+ white-space: pre-wrap;
143
+ white-space: -moz-pre-wrap;
144
+ white-space: -pre-wrap;
145
+ white-space: -o-pre-wrap;
146
+ word-wrap: break-word;
147
+ }
148
+
149
+ .suite-container {
150
+ margin-bottom: 2rem;
151
+ }
152
+ .suite-info {
153
+ padding: 1rem;
154
+ background-color: #eee;
155
+ color: #777;
156
+ display: flex;
157
+ align-items: center;
158
+ margin-bottom: 0.25rem;
159
+ }
160
+ .suite-info .suite-path {
161
+ word-break: break-all;
162
+ flex-grow: 1;
163
+ font-family: monospace;
164
+ font-size: 1rem;
165
+ }
166
+ .suite-info .suite-time {
167
+ margin-left: 0.5rem;
168
+ padding: 0.2rem 0.3rem;
169
+ font-size: 0.75rem;
170
+ }
171
+ .suite-info .suite-time.warn {
172
+ background-color: #d8000c;
173
+ color: #fff;
174
+ }
175
+
176
+ /* CONSOLE LOGS */
177
+ .suite-consolelog {
178
+ margin-bottom: 0.25rem;
179
+ padding: 1rem;
180
+ background-color: #efefef;
181
+ }
182
+ .suite-consolelog-header {
183
+ font-weight: bold;
184
+ }
185
+ .suite-consolelog-item {
186
+ padding: 0.5rem;
187
+ }
188
+ .suite-consolelog-item pre {
189
+ margin: 0.5rem 0;
190
+ white-space: pre-wrap;
191
+ white-space: -moz-pre-wrap;
192
+ white-space: -pre-wrap;
193
+ white-space: -o-pre-wrap;
194
+ word-wrap: break-word;
195
+ }
196
+ .suite-consolelog-item-origin {
197
+ color: #777;
198
+ font-weight: bold;
199
+ }
200
+ .suite-consolelog-item-message {
201
+ color: #000;
202
+ font-size: 1rem;
203
+ padding: 0 0.5rem;
204
+ }
205
+
206
+ /* OBSOLETE SNAPSHOTS */
207
+ .suite-obsolete-snapshots {
208
+ margin-bottom: 0.25rem;
209
+ padding: 1rem;
210
+ background-color: #ffbaba;
211
+ color: #d8000c;
212
+ }
213
+ .suite-obsolete-snapshots-header {
214
+ font-weight: bold;
215
+ }
216
+ .suite-obsolete-snapshots-item {
217
+ padding: 0.5rem;
218
+ }
219
+ .suite-obsolete-snapshots-item pre {
220
+ margin: 0.5rem 0;
221
+ white-space: pre-wrap;
222
+ white-space: -moz-pre-wrap;
223
+ white-space: -pre-wrap;
224
+ white-space: -o-pre-wrap;
225
+ word-wrap: break-word;
226
+ }
227
+ .suite-obsolete-snapshots-item-message {
228
+ color: #000;
229
+ font-size: 1rem;
230
+ padding: 0 0.5rem;
231
+ }
232
+ </style></head><body><div id="jesthtml-content"><header><h1 id="title">Peptides Test Report. Datagrok version datagrok/datagrok:latest SHA=62cc009524f3. Commit 0949dc07.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-11-11 14:09:20</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><div class="suite-info"><div class="suite-path">/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts</div><div class="suite-time warn">96.038s</div></div><div class="suite-tests"><div class="test-result failed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">failed</div><div class="test-duration">82.695s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: Test result : Failed : 329 : Peptides.Core.Start analysis: сomplex : Error: For column 'macromolecule' of alphabet 'UN' tag '.alphabetSize' is mandatory.
233
+
234
+ at /home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:68:20
235
+ at Generator.next (&lt;anonymous&gt;)
236
+ at fulfilled (/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:31:58)
237
+ at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre></div></div></div><div class="suite-consolelog"><div class="suite-consolelog-header">Console Log</div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at Object.&lt;anonymous&gt; (/home/runner/work/public/public/packages/Peptides/src/__jest__/test-node.ts:62:11)
238
+ at Generator.next (&lt;anonymous&gt;)
239
+ at fulfilled (/home/runner/work/public/public/packages/Peptides/src/__jest__/test-node.ts:28:58)
240
+ at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre><pre class="suite-consolelog-item-message">Using web root: http://localhost:8080</pre></div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at /home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:40:11
241
+ at Generator.next (&lt;anonymous&gt;)
242
+ at /home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:34:71
243
+ at new Promise (&lt;anonymous&gt;)
244
+ at Object.&lt;anonymous&gt;.__awaiter (/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:30:12)
245
+ at Object.&lt;anonymous&gt; (/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:38:23)
246
+ at Promise.then.completed (/home/runner/work/public/public/packages/Peptides/node_modules/jest-circus/build/utils.js:391:28)
247
+ at new Promise (&lt;anonymous&gt;)</pre><pre class="suite-consolelog-item-message">Testing Peptides package</pre></div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at /home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:66:11
248
+ at Generator.next (&lt;anonymous&gt;)
249
+ at fulfilled (/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:31:58)
250
+ at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre><pre class="suite-consolelog-item-message">Test result : Success : 4295 : Peptides.Core.Start analysis: simple : OK
251
+ Test result : Success : 7421 : Peptides.Core.Save and load project : OK
252
+ Test result : Success : 0 : Peptides.Peptide space.test_table.is_not_empty : OK
253
+ Test result : Success : 2686 : Peptides.Peptide space.PeptideSimilaritySpaceWidget.is_drawing : OK
254
+ Test result : Success : 2 : Peptides.Peptide space.test_deminsionality_reducer : OK
255
+ Test result : Success : 0 : Peptides.Peptide space.test_peptide_similarity_space_viewer : OK
256
+ Test result : Success : 2238 : Peptides.Peptide space.peptide_space.DimensinalityReducer.UMAP.Levenshtein.is_numeric : OK
257
+ Test result : Success : 2625 : Peptides.Peptide space.peptide_space.DimensinalityReducer.UMAP.Jaro-Winkler.is_numeric : OK
258
+ Test result : Success : 3350 : Peptides.Peptide space.peptide_space.DimensinalityReducer.t-SNE.Levenshtein.is_numeric : OK
259
+ Test result : Success : 3819 : Peptides.Peptide space.peptide_space.DimensinalityReducer.t-SNE.Jaro-Winkler.is_numeric : OK
260
+ Test result : Success : 208 : Peptides.Peptide space.peptide_space.DimensinalityReducer.SPE.Levenshtein.is_numeric : OK
261
+ Test result : Success : 594 : Peptides.Peptide space.peptide_space.DimensinalityReducer.SPE.Jaro-Winkler.is_numeric : OK
262
+ Test result : Success : 171 : Peptides.Peptide space.peptide_space.DimensinalityReducer.pSPE.Levenshtein.is_numeric : OK
263
+ Test result : Success : 556 : Peptides.Peptide space.peptide_space.DimensinalityReducer.pSPE.Jaro-Winkler.is_numeric : OK
264
+ Test result : Success : 8614 : Peptides.Peptide space.peptide_space.DimensinalityReducer.OriginalSPE.Levenshtein.is_numeric : OK
265
+ Test result : Success : 9838 : Peptides.Peptide space.peptide_space.DimensinalityReducer.OriginalSPE.Jaro-Winkler.is_numeric : OK
266
+ Test result : Success : 2113 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.UMAP.Levenshtein.is_proper : OK
267
+ Test result : Success : 2618 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.UMAP.Jaro-Winkler.is_proper : OK
268
+ Test result : Success : 3392 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.t-SNE.Levenshtein.is_proper : OK
269
+ Test result : Success : 3850 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.t-SNE.Jaro-Winkler.is_proper : OK
270
+ Test result : Success : 232 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.SPE.Levenshtein.is_proper : OK
271
+ Test result : Success : 818 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.SPE.Jaro-Winkler.is_proper : OK
272
+ Test result : Success : 193 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.pSPE.Levenshtein.is_proper : OK
273
+ Test result : Success : 587 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.pSPE.Jaro-Winkler.is_proper : OK
274
+ Test result : Success : 8223 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.OriginalSPE.Levenshtein.is_proper : OK
275
+ Test result : Success : 9416 : Peptides.Peptide space.peptide_space.PeptideSimilaritySpaceViewer.OriginalSPE.Jaro-Winkler.is_proper : OK
276
+ </pre></div></div></div></div></body></html>