@datagrok/peptides 1.2.0 → 1.3.1

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.
@@ -14,7 +14,11 @@ const otherConst = 'Other';
14
14
  export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel): DG.Widget {
15
15
  const activityScaledCol = table.columns.bySemType(C.SEM_TYPES.ACTIVITY_SCALED)!;
16
16
  const rowCount = activityScaledCol.length;
17
- const selectionObject = model.currentSelection;
17
+ const selectionObject = model.mutationCliffsSelection;
18
+ let isMutationCliffsSelectionEmpty = true;
19
+ for (const aarList of Object.values(selectionObject))
20
+ isMutationCliffsSelectionEmpty &&= aarList.length === 0;
21
+ const clustersObject = model.logoSummarySelection;
18
22
  const positions = Object.keys(selectionObject);
19
23
  const positionsLen = positions.length;
20
24
  let aarStr = allConst;
@@ -29,12 +33,16 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
29
33
  otherStr = otherConst;
30
34
  for (const position of positions) {
31
35
  const posCol = table.getCol(position);
32
- for (const aar of selectionObject[position]) {
36
+ const aarList = selectionObject[position];
37
+ if (aarList.length === 0)
38
+ continue;
39
+
40
+ for (const aar of aarList) {
33
41
  aarStr = `${position} : ${aar}`;
34
42
  const splitCol = DG.Column.bool(C.COLUMNS_NAMES.SPLIT_COL, rowCount).init((i) => posCol.get(i) == aar);
35
43
 
36
44
  const distributionTable = DG.DataFrame.fromColumns([activityScaledCol, splitCol]);
37
- const currentStatsDf = model.statsDf.rows.match({Pos: position, AAR: aar}).toDataFrame();
45
+ const currentStatsDf = model.monomerPositionStatsDf.rows.match({Pos: position, AAR: aar}).toDataFrame();
38
46
  const stats: Stats = {
39
47
  count: currentStatsDf.get(C.COLUMNS_NAMES.COUNT, 0),
40
48
  ratio: currentStatsDf.get(C.COLUMNS_NAMES.RATIO, 0),
@@ -49,10 +57,13 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
49
57
  }
50
58
  } else if (splitByPosition.value) {
51
59
  otherStr = otherConst;
52
- const activityScaledData = activityScaledCol.getRawData();
60
+ const activityScaledData = activityScaledCol.toList();
53
61
  for (const position of positions) {
54
62
  const posCol = table.getCol(position);
55
63
  const aarList = selectionObject[position];
64
+ if (aarList.length === 0)
65
+ continue;
66
+
56
67
  aarStr = `${position}: {${aarList.join(', ')}}`;
57
68
 
58
69
  const mask = DG.BitSet.create(rowCount, (i) => aarList.includes(posCol.get(i)));
@@ -80,7 +91,7 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
80
91
  }
81
92
 
82
93
  otherStr = otherConst;
83
- const activityScaledData = activityScaledCol.getRawData();
94
+ const activityScaledData = activityScaledCol.toList();
84
95
  for (const aar of aars) {
85
96
  const posList = reversedSelectionObject[aar];
86
97
  aarStr = `${aar}: {${posList.join(', ')}}`;
@@ -112,14 +123,18 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
112
123
  otherStr = otherConst;
113
124
  } else if (positionsLen) {
114
125
  aarStr = '';
115
- for (const position of positions)
116
- aarStr += `${position}: {${selectionObject[position].join(', ')}}; `;
117
- aarStr = aarStr.slice(0, aarStr.length - 2);
126
+ for (const position of positions) {
127
+ const aarList = selectionObject[position];
128
+ if (aarList.length !== 0)
129
+ aarStr += `${position}: {${aarList.join(', ')}}; `;
130
+ }
131
+ if (clustersObject.length !== 0)
132
+ aarStr += `Clusters: ${clustersObject.join(', ')}`;
118
133
  otherStr = otherConst;
119
134
  }
120
135
 
121
136
  const distributionTable = DG.DataFrame.fromColumns([activityScaledCol, splitCol]);
122
- const stats = getStats(activityScaledCol.getRawData(), table.selection);
137
+ const stats = getStats(activityScaledCol.toList(), table.selection);
123
138
  const distributionRoot = getDistributionAndStats(distributionTable, stats, aarStr, otherStr);
124
139
  $(distributionRoot).addClass('d4-flex-col');
125
140
 
@@ -130,9 +145,9 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
130
145
  };
131
146
 
132
147
  const setDefaultProperties = (input: DG.InputBase): void => {
133
- input.enabled = positionsLen != 0;
148
+ input.enabled = !isMutationCliffsSelectionEmpty;
134
149
  $(input.root).find('.ui-input-editor').css('margin', '0px');
135
- $(input.root).find('.ui-input-description').css('padding', '0px');
150
+ $(input.root).find('.ui-input-description').css('padding', '0px').css('padding-left', '5px');
136
151
  };
137
152
 
138
153
  const splitByPosition = ui.boolInput('', model.splitByPos, updateDistributionHost);
@@ -7,7 +7,7 @@ import {getSeparator} from '../utils/misc';
7
7
 
8
8
  export function mutationCliffsWidget(table: DG.DataFrame, model: PeptidesModel): DG.Widget {
9
9
  const substInfo = model.substitutionsInfo;
10
- const currentCell = model.currentSelection;
10
+ const currentCell = model.mutationCliffsSelection;
11
11
  const positions = Object.keys(currentCell);
12
12
 
13
13
  if (!positions.length)
@@ -16,7 +16,8 @@ export function mutationCliffsWidget(table: DG.DataFrame, model: PeptidesModel):
16
16
  const substitutionsArray: string[] = [];
17
17
  const deltaArray: number[] = [];
18
18
  const substitutedToArray: string[] = [];
19
- const alignedSeqCol = table.columns.bySemType(C.SEM_TYPES.MACROMOLECULE)!;
19
+ // const alignedSeqCol = table.columns.bySemType(C.SEM_TYPES.MACROMOLECULE)!;
20
+ const alignedSeqCol = table.getCol(C.COLUMNS_NAMES.MACROMOLECULE);
20
21
  const activityScaledCol = table.columns.bySemType(C.SEM_TYPES.ACTIVITY_SCALED)!;
21
22
  const seenIndexes = new Map<number, number[]>();
22
23
 
@@ -12,10 +12,10 @@ import {scaleActivity} from '../utils/misc';
12
12
 
13
13
  /** Peptide analysis widget.
14
14
  *
15
- * @param {DG.DataFrame} currentDf Working table
15
+ * @param {DG.DataFrame} df Working table
16
16
  * @param {DG.Column} col Aligned sequence column
17
17
  * @return {Promise<DG.Widget>} Widget containing peptide analysis */
18
- export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Column): Promise<DG.Widget> {
18
+ export async function analyzePeptidesWidget(df: DG.DataFrame, col: DG.Column): Promise<DG.Widget> {
19
19
  if (!col.tags['aligned']?.includes('MSA') && col.tags[DG.TAGS.UNITS].toLowerCase() != 'helm')
20
20
  return new DG.Widget(ui.divText('Peptides analysis only works with aligned sequences'));
21
21
 
@@ -30,19 +30,27 @@ export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Col
30
30
  let tempCol = null;
31
31
  let scaledDf: DG.DataFrame;
32
32
  let newScaledColName: string;
33
+ let scalingFormula: (x: number) => number;
33
34
 
34
- for (const column of currentDf.columns.numerical)
35
+ for (const column of df.columns.numerical)
35
36
  tempCol = column.type === DG.TYPE.FLOAT ? column : null;
36
37
 
37
- const defaultColumn: DG.Column<number> | null = currentDf.col('activity') || currentDf.col('IC50') || tempCol;
38
+ const defaultActivityColumn: DG.Column<number> | null = df.col('activity') || df.col('IC50') || tempCol;
38
39
  const histogramHost = ui.div([], {id: 'pep-hist-host'});
39
40
 
41
+ const indexes: number[] = [];
42
+ const f = df.filter;
43
+ df.onFilterChanged.subscribe(() => {
44
+ for (let i = 0; i < f.length; ++i) {
45
+ if (f.get(i))
46
+ indexes.push(i);
47
+ }
48
+ });
40
49
  const activityScalingMethod = ui.choiceInput(
41
50
  'Scaling', 'none', ['none', 'lg', '-lg'],
42
51
  async (currentMethod: string): Promise<void> => {
43
- const currentActivityCol = activityColumnChoice.value?.name;
44
-
45
- [scaledDf, newScaledColName] = scaleActivity(currentMethod, currentDf, currentActivityCol, true);
52
+ [scaledDf, scalingFormula, newScaledColName] =
53
+ scaleActivity(currentMethod, activityColumnChoice.value!, indexes.length !== 0 ? indexes : undefined);
46
54
 
47
55
  const hist = scaledDf.plot.histogram({
48
56
  filteringEnabled: false,
@@ -60,21 +68,23 @@ export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Col
60
68
 
61
69
  const activityScalingMethodState = (_: any): void => {
62
70
  activityScalingMethod.enabled = (activityColumnChoice.value ?? false) &&
63
- DG.Stats.fromColumn(activityColumnChoice.value!, currentDf.filter).min > 0;
71
+ DG.Stats.fromColumn(activityColumnChoice.value!, df.filter).min > 0;
64
72
  activityScalingMethod.fireChanged();
65
73
  };
66
- const activityColumnChoice = ui.columnInput('Activity', currentDf, defaultColumn, activityScalingMethodState);
74
+ const activityColumnChoice = ui.columnInput('Activity', df, defaultActivityColumn, activityScalingMethodState);
75
+ const clustersColumnChoice = ui.columnInput('Clusters', df, null);
67
76
  activityColumnChoice.fireChanged();
68
77
  activityScalingMethod.fireChanged();
69
78
 
70
- const inputsList = [activityColumnChoice, activityScalingMethod];
79
+ const inputsList = [activityColumnChoice, activityScalingMethod, clustersColumnChoice];
71
80
 
72
81
  const startBtn = ui.button('Launch SAR', async () => {
73
- await startAnalysis(activityColumnChoice.value, col, currentDf, scaledDf, newScaledColName);
82
+ await startAnalysis(activityColumnChoice.value, col, clustersColumnChoice.value, df, scalingFormula,
83
+ newScaledColName, activityScalingMethod.value ?? 'none', indexes);
74
84
  });
75
85
  startBtn.style.alignSelf = 'center';
76
86
 
77
- const viewer = await currentDf.plot.fromType('WebLogo') as WebLogo;
87
+ const viewer = await df.plot.fromType('WebLogo') as WebLogo;
78
88
  viewer.root.style.setProperty('height', '130px');
79
89
  const logoHost = ui.div();
80
90
  $(logoHost).empty().append(viewer.root);
@@ -85,38 +95,56 @@ export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Col
85
95
  ui.splitH([
86
96
  ui.splitV([ui.inputs(inputsList), startBtn]),
87
97
  histogramHost,
88
- ], {style: {height: 'unset'}}),
98
+ ], {style: {height: '215px'}}),
89
99
  ]),
90
100
  );
91
101
  }
92
102
 
93
- export async function startAnalysis(
94
- activityColumn: DG.Column<number> | null, alignedSeqCol: DG.Column<string>, currentDf: DG.DataFrame,
95
- scaledDf: DG.DataFrame, newScaledColName: string): Promise<PeptidesModel | null> {
103
+ export async function startAnalysis(activityColumn: DG.Column<number> | null, peptidesCol: DG.Column<string>,
104
+ clustersColumn: DG.Column | null, currentDf: DG.DataFrame, scaleNum: (x: number) => number, newScaledColName: string,
105
+ scaling: string, indexes: number[]): Promise<PeptidesModel | null> {
96
106
  const progress = DG.TaskBarProgressIndicator.create('Loading SAR...');
97
107
  let model = null;
98
108
  if (activityColumn?.type === DG.TYPE.FLOAT) {
99
- const activityColumnName: string = activityColumn.name;
100
-
109
+ const f = currentDf.filter;
101
110
  //prepare new DF
102
- const newDf = currentDf.clone(currentDf.filter, [alignedSeqCol.name, activityColumnName]);
103
- const activityCol = newDf.getCol(activityColumnName);
104
- activityCol.name = C.COLUMNS_NAMES.ACTIVITY;
105
- activityCol.semType = C.SEM_TYPES.ACTIVITY;
106
- newDf.getCol(alignedSeqCol.name).name = C.COLUMNS_NAMES.ALIGNED_SEQUENCE;
107
- const activityScaledCol = scaledDf.getCol(C.COLUMNS_NAMES.ACTIVITY_SCALED);
111
+ const newDf = DG.DataFrame.create(f.trueCount);
112
+ const getIndex = indexes.length !== 0 ? (i: number) : number => indexes[i] : (i: number): number => i;
113
+ let activityCol: DG.Column<number> | null = null;
114
+ for (const col of currentDf.columns.toList()) {
115
+ let virtualCol: DG.Column<any>;
116
+ if (col === activityColumn) {
117
+ virtualCol = newDf.columns.addNewVirtual(
118
+ C.COLUMNS_NAMES.ACTIVITY, (i) => activityColumn.get(getIndex(i)!), DG.TYPE.FLOAT);
119
+ activityCol = virtualCol;
120
+ } else if (col === peptidesCol) {
121
+ virtualCol = newDf.columns.addNewVirtual(
122
+ C.COLUMNS_NAMES.MACROMOLECULE, (i) => peptidesCol.get(getIndex(i)!), DG.TYPE.STRING);
123
+ } else
124
+ virtualCol = newDf.columns.addNewVirtual(col.name, (i) => col.get(getIndex(i)!), col.type as DG.TYPE);
125
+ virtualCol.setTag(C.TAGS.VISIBLE, '0');
126
+ }
127
+ activityCol!.semType = C.SEM_TYPES.ACTIVITY;
128
+ const activityScaledCol = newDf.columns.addNewVirtual(C.COLUMNS_NAMES.ACTIVITY_SCALED, (i) => {
129
+ const val = activityCol!.get(getIndex(i)!);
130
+ return val ? scaleNum(val) : val;
131
+ }, DG.TYPE.FLOAT);
108
132
  activityScaledCol.semType = C.SEM_TYPES.ACTIVITY_SCALED;
109
- newDf.columns.add(activityScaledCol);
110
133
  newDf.name = 'Peptides analysis';
111
134
  newDf.tags[C.COLUMNS_NAMES.ACTIVITY_SCALED] = newScaledColName;
135
+ if (clustersColumn) {
136
+ newDf.getCol(clustersColumn.name).name = C.COLUMNS_NAMES.CLUSTERS;
137
+ newDf.tags[C.TAGS.CLUSTERS] = C.COLUMNS_NAMES.CLUSTERS;
138
+ }
112
139
  // newDf.tags[C.PEPTIDES_ANALYSIS] = 'true';
140
+ newDf.tags['scaling'] = scaling;
113
141
 
114
142
  let monomerType = 'HELM_AA';
115
- if (alignedSeqCol.getTag(DG.TAGS.UNITS).toLowerCase() == 'helm') {
116
- const sampleSeq = alignedSeqCol.get(0)!;
143
+ if (peptidesCol.getTag(DG.TAGS.UNITS).toLowerCase() == 'helm') {
144
+ const sampleSeq = peptidesCol.get(0)!;
117
145
  monomerType = sampleSeq.startsWith('PEPTIDE') ? 'HELM_AA' : 'HELM_BASE';
118
146
  } else {
119
- const alphabet = alignedSeqCol.tags[C.TAGS.ALPHABET];
147
+ const alphabet = peptidesCol.tags[C.TAGS.ALPHABET];
120
148
  monomerType = alphabet == 'DNA' || alphabet == 'RNA' ? 'HELM_BASE' : 'HELM_AA';
121
149
  }
122
150
 
@@ -0,0 +1,246 @@
1
+ <html><head><meta charset="utf-8"/><title>Peptides Test Report. Datagrok version datagrok/datagrok:latest SHA=8408d9b6ee67. Commit ca232121.</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=8408d9b6ee67. Commit ca232121.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-10-11 15:08:32</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">127.821s</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">112.749s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: Evaluation failed: TypeError: Cannot read properties of null (reading 'get')
233
+ at __puppeteer_evaluation_script__:17:71
234
+ at ExecutionContext._evaluateInternal (/home/runner/work/public/public/packages/Peptides/node_modules/puppeteer/src/common/ExecutionContext.ts:273:13)
235
+ at processTicksAndRejections (internal/process/task_queues.js:97:5)
236
+ at ExecutionContext.evaluate (/home/runner/work/public/public/packages/Peptides/node_modules/puppeteer/src/common/ExecutionContext.ts:140:12)</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)
237
+ at Generator.next (&lt;anonymous&gt;)
238
+ at fulfilled (/home/runner/work/public/public/packages/Peptides/src/__jest__/test-node.ts:28:58)
239
+ 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
240
+ at Generator.next (&lt;anonymous&gt;)
241
+ at /home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:34:71
242
+ at new Promise (&lt;anonymous&gt;)
243
+ at Object.&lt;anonymous&gt;.__awaiter (/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:30:12)
244
+ at Object.&lt;anonymous&gt; (/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:38:23)
245
+ at Promise.then.completed (/home/runner/work/public/public/packages/Peptides/node_modules/jest-circus/build/utils.js:391:28)
246
+ at new Promise (&lt;anonymous&gt;)</pre><pre class="suite-consolelog-item-message">Testing Peptides package</pre></div></div></div></div></body></html>
@@ -1,163 +0,0 @@
1
- import * as ui from 'datagrok-api/ui';
2
- import * as DG from 'datagrok-api/dg';
3
-
4
- import * as C from './constants';
5
- import {PeptidesModel} from '../model';
6
- import {isGridCellInvalid} from './misc';
7
-
8
- const CELL_SIZE = 20; // 20px cell height and width
9
-
10
- export class InvariantMap extends DG.Filter {
11
- model: PeptidesModel | null = null;
12
- chosenCells: {[position: string]: string[]} = {};
13
-
14
- constructor() {
15
- super();
16
- }
17
-
18
- get caption(): string {return 'Invariant Map';}
19
-
20
- get filterSummary(): string {
21
- let summary = '';
22
- for (const [pos, aarList] of Object.entries(this.chosenCells))
23
- if (aarList.length > 0)
24
- summary += `${pos}: ${aarList}\n`;
25
-
26
- return summary;
27
- }
28
-
29
- get isFiltering(): boolean {return true && super.isFiltering;}
30
-
31
- get isReadyToApplyFilter(): boolean {return this.model != null;}
32
-
33
- async attach(df: DG.DataFrame): Promise<void> {
34
- super.attach(df);
35
- this.model = await PeptidesModel.getInstance(df);
36
- this.render(true);
37
- }
38
-
39
- saveState(): any {
40
- const state = super.saveState();
41
- state.chosenCells = JSON.stringify(this.chosenCells);
42
- return state;
43
- }
44
-
45
- applyState(state: any): void {
46
- super.applyState(state);
47
- if (state.chosenCells) {
48
- this.chosenCells = JSON.parse(state.chosenCells);
49
- this.render();
50
- }
51
- }
52
-
53
- applyFilter(): void {
54
- this.dataFrame?.filter.init((bitsetIndex) => {
55
- for (const [position, aarList] of Object.entries(this.chosenCells)) {
56
- if (aarList.length != 0 && !aarList.includes(this.dataFrame!.get(position, bitsetIndex)))
57
- return false;
58
- }
59
- return true;
60
- });
61
- }
62
-
63
- render(initChosenCells: boolean = false): void {
64
- if (this.model == null)
65
- return;
66
-
67
- const invariantDf = this.model.statsDf.groupBy([C.COLUMNS_NAMES.MONOMER])
68
- .pivot(C.COLUMNS_NAMES.POSITION)
69
- .add('first', C.COLUMNS_NAMES.COUNT, '')
70
- .aggregate();
71
- invariantDf.getCol(C.COLUMNS_NAMES.MONOMER).semType = C.SEM_TYPES.MONOMER;
72
- const orderedColNames = invariantDf.columns.names().sort((a, b) => {
73
- const aInt = parseInt(a);
74
- const bInt = parseInt(b);
75
- if (isNaN(aInt))
76
- return -1;
77
- else if (isNaN(bInt))
78
- return 1;
79
- return aInt - bInt;
80
- });
81
-
82
- // Create grid and set properties
83
- const invariantGrid = invariantDf.plot.grid();
84
- const gridCols = invariantGrid.columns;
85
- gridCols.rowHeader!.visible = false;
86
- gridCols.setOrder(orderedColNames);
87
-
88
- for (let gridColIndex = 0; gridColIndex < gridCols.length; ++gridColIndex) {
89
- const gridCol = gridCols.byIndex(gridColIndex)!
90
- if (gridCol.name != C.COLUMNS_NAMES.MONOMER)
91
- gridCol.width = CELL_SIZE;
92
- }
93
-
94
- if (initChosenCells) {
95
- this.chosenCells = {};
96
- for (const col of invariantDf.columns)
97
- if (col.name != C.COLUMNS_NAMES.MONOMER)
98
- this.chosenCells[col.name] = [];
99
- }
100
-
101
- invariantGrid.root.addEventListener('click', (ev) => {
102
- invariantDf.currentRowIdx = -1;
103
- const gridCell = invariantGrid.hitTest(ev.offsetX, ev.offsetY);
104
- if (isGridCellInvalid(gridCell) || gridCell!.tableColumn!.name == C.COLUMNS_NAMES.MONOMER)
105
- return;
106
-
107
- const position = gridCell!.tableColumn!.name;
108
- const aar = invariantDf.get(C.COLUMNS_NAMES.MONOMER, gridCell!.tableRowIndex!);
109
- const aarList = this.chosenCells[position];
110
- const aarIndex = aarList.indexOf(aar);
111
-
112
- if (aarIndex != -1)
113
- aarList.splice(aarIndex, 1);
114
- else
115
- aarList.push(aar);
116
-
117
- invariantGrid.invalidate();
118
- this.applyFilter();
119
- });
120
-
121
- invariantGrid.onCellRender.subscribe((args) => {
122
- //FIXME: for some reason it doesn't work when I set right away
123
- const gridProps = invariantGrid.props;
124
- gridProps.allowBlockSelection = false;
125
- gridProps.allowColSelection = false;
126
- gridProps.allowRowSelection = false;
127
- gridProps.allowEdit = false;
128
- gridProps.rowHeight = CELL_SIZE;
129
-
130
- const gc = args.cell;
131
- const tableColName = gc.tableColumn?.name;
132
- const tableRowIndex = gc.tableRowIndex;
133
-
134
- if (isGridCellInvalid(gc) || tableColName == C.COLUMNS_NAMES.MONOMER ||
135
- tableRowIndex == null || tableRowIndex == -1)
136
- return;
137
-
138
- const currentPosition: string = tableColName !== C.COLUMNS_NAMES.MEAN_DIFFERENCE ?
139
- tableColName : invariantDf.get(C.COLUMNS_NAMES.POSITION, tableRowIndex);
140
- const currentAAR: string = invariantDf.get(C.COLUMNS_NAMES.MONOMER, tableRowIndex);
141
- const canvasContext = args.g;
142
- const bound = args.bounds;
143
-
144
- canvasContext.font = '10px Roboto';
145
- canvasContext.textAlign = 'center';
146
- canvasContext.textBaseline = 'middle';
147
- canvasContext.fillStyle = '#000';
148
- canvasContext.fillText(gc.cell.value, bound.x + (bound.width / 2), bound.y + (bound.height / 2), bound.width);
149
-
150
- const aarSelection = this.chosenCells[currentPosition];
151
- if (aarSelection.includes(currentAAR)) {
152
- canvasContext.strokeStyle = '#000';
153
- canvasContext.lineWidth = 1;
154
- canvasContext.strokeRect(bound.x + 1, bound.y + 1, bound.width - 1, bound.height - 1);
155
- }
156
- args.preventDefault();
157
- });
158
-
159
- const gridHost = ui.box(invariantGrid.root);
160
- gridHost.style.width = '100%';
161
- this.root.appendChild(gridHost);
162
- }
163
- }