@vitessce/config 3.0.0 → 3.1.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/dist/index.js +589 -83
- package/dist-tsc/VitessceAutoConfig.d.ts +13 -1
- package/dist-tsc/VitessceAutoConfig.d.ts.map +1 -1
- package/dist-tsc/VitessceAutoConfig.js +318 -87
- package/dist-tsc/VitessceAutoConfig.test.js +599 -71
- package/dist-tsc/VitessceConfig.d.ts +46 -0
- package/dist-tsc/VitessceConfig.d.ts.map +1 -1
- package/dist-tsc/VitessceConfig.js +353 -0
- package/dist-tsc/VitessceConfig.test.js +329 -1
- package/dist-tsc/constants.d.ts +247 -0
- package/dist-tsc/constants.d.ts.map +1 -0
- package/dist-tsc/constants.js +87 -0
- package/dist-tsc/index.d.ts +2 -1
- package/dist-tsc/index.js +2 -1
- package/package.json +4 -4
- package/src/VitessceAutoConfig.js +368 -99
- package/src/VitessceAutoConfig.test.js +626 -76
- package/src/VitessceConfig.js +393 -0
- package/src/VitessceConfig.test.js +339 -0
- package/src/constants.js +94 -0
- package/src/index.js +2 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { generateConfig, getHintOptions } from './VitessceAutoConfig.js';
|
|
3
|
+
import { HINT_TYPE_TO_FILE_TYPE_MAP } from './constants.js';
|
|
2
4
|
|
|
3
|
-
describe('
|
|
5
|
+
describe('generateConfig', () => {
|
|
4
6
|
it('generates config for OME-TIFF file correctly', async () => {
|
|
5
7
|
const urls = ['somefile.ome.tif'];
|
|
6
|
-
const expectedName = urls[0].split('/').at(-1);
|
|
7
8
|
const expectedConfig = {
|
|
8
9
|
version: '1.0.15',
|
|
9
10
|
name: 'An automatically generated config. Adjust values and add layout components if needed.',
|
|
@@ -11,7 +12,7 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
11
12
|
datasets: [
|
|
12
13
|
{
|
|
13
14
|
uid: 'A',
|
|
14
|
-
name:
|
|
15
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
15
16
|
files: [
|
|
16
17
|
{
|
|
17
18
|
fileType: 'raster.json',
|
|
@@ -21,7 +22,7 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
21
22
|
metadata: {
|
|
22
23
|
isBitmask: false,
|
|
23
24
|
},
|
|
24
|
-
name:
|
|
25
|
+
name: 'somefile.ome.tif',
|
|
25
26
|
type: 'ome-tiff',
|
|
26
27
|
url: urls[0],
|
|
27
28
|
},
|
|
@@ -77,13 +78,12 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
77
78
|
initStrategy: 'auto',
|
|
78
79
|
};
|
|
79
80
|
|
|
80
|
-
const config = await
|
|
81
|
+
const config = await generateConfig(urls);
|
|
81
82
|
expect(config).toEqual(expectedConfig);
|
|
82
83
|
});
|
|
83
84
|
|
|
84
85
|
it('generates config for OME-ZARR file correctly', async () => {
|
|
85
86
|
const urls = ['anotherfile.ome.zarr'];
|
|
86
|
-
const expectedName = urls[0].split('/').at(-1);
|
|
87
87
|
const expectedConfig = {
|
|
88
88
|
version: '1.0.15',
|
|
89
89
|
name: 'An automatically generated config. Adjust values and add layout components if needed.',
|
|
@@ -91,7 +91,7 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
91
91
|
datasets: [
|
|
92
92
|
{
|
|
93
93
|
uid: 'A',
|
|
94
|
-
name:
|
|
94
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
95
95
|
files: [
|
|
96
96
|
{
|
|
97
97
|
url: urls[0],
|
|
@@ -135,28 +135,21 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
135
135
|
y: 6,
|
|
136
136
|
w: 6,
|
|
137
137
|
h: 6,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
coordinationScopes: {
|
|
142
|
-
dataset: 'A',
|
|
138
|
+
props: {
|
|
139
|
+
disable3d: [],
|
|
140
|
+
disableChannelsIfRgbDetected: true,
|
|
143
141
|
},
|
|
144
|
-
x: 6,
|
|
145
|
-
y: 6,
|
|
146
|
-
w: 6,
|
|
147
|
-
h: 6,
|
|
148
142
|
},
|
|
149
143
|
],
|
|
150
144
|
initStrategy: 'auto',
|
|
151
145
|
};
|
|
152
146
|
|
|
153
|
-
const config = await
|
|
147
|
+
const config = await generateConfig(urls);
|
|
154
148
|
expect(config).toEqual(expectedConfig);
|
|
155
149
|
});
|
|
156
150
|
|
|
157
151
|
it('generates config for Anndata-ZARR file correctly', async () => {
|
|
158
|
-
const urls = ['http://localhost:
|
|
159
|
-
const expectedName = urls[0].split('/').at(-1);
|
|
152
|
+
const urls = ['http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
|
|
160
153
|
const expectedConfig = {
|
|
161
154
|
version: '1.0.15',
|
|
162
155
|
name: 'An automatically generated config. Adjust values and add layout components if needed.',
|
|
@@ -164,7 +157,7 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
164
157
|
datasets: [
|
|
165
158
|
{
|
|
166
159
|
uid: 'A',
|
|
167
|
-
name:
|
|
160
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
168
161
|
files: [
|
|
169
162
|
{
|
|
170
163
|
url: urls[0],
|
|
@@ -219,7 +212,7 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
219
212
|
x: 0,
|
|
220
213
|
y: 0,
|
|
221
214
|
w: 6,
|
|
222
|
-
h:
|
|
215
|
+
h: 4,
|
|
223
216
|
},
|
|
224
217
|
{
|
|
225
218
|
component: 'scatterplot',
|
|
@@ -230,7 +223,27 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
230
223
|
x: 6,
|
|
231
224
|
y: 0,
|
|
232
225
|
w: 6,
|
|
233
|
-
h:
|
|
226
|
+
h: 4,
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
component: 'obsSetSizes',
|
|
230
|
+
coordinationScopes: {
|
|
231
|
+
dataset: 'A',
|
|
232
|
+
},
|
|
233
|
+
h: 4,
|
|
234
|
+
w: 6,
|
|
235
|
+
x: 0,
|
|
236
|
+
y: 4,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
component: 'obsSetFeatureValueDistribution',
|
|
240
|
+
coordinationScopes: {
|
|
241
|
+
dataset: 'A',
|
|
242
|
+
},
|
|
243
|
+
h: 4,
|
|
244
|
+
w: 6,
|
|
245
|
+
x: 6,
|
|
246
|
+
y: 4,
|
|
234
247
|
},
|
|
235
248
|
{
|
|
236
249
|
component: 'heatmap',
|
|
@@ -238,9 +251,9 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
238
251
|
dataset: 'A',
|
|
239
252
|
},
|
|
240
253
|
x: 0,
|
|
241
|
-
y:
|
|
254
|
+
y: 8,
|
|
242
255
|
w: 6,
|
|
243
|
-
h:
|
|
256
|
+
h: 4,
|
|
244
257
|
props: {
|
|
245
258
|
transpose: true,
|
|
246
259
|
},
|
|
@@ -251,21 +264,20 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
251
264
|
dataset: 'A',
|
|
252
265
|
},
|
|
253
266
|
x: 6,
|
|
254
|
-
y:
|
|
267
|
+
y: 8,
|
|
255
268
|
w: 6,
|
|
256
|
-
h:
|
|
269
|
+
h: 4,
|
|
257
270
|
},
|
|
258
271
|
],
|
|
259
272
|
initStrategy: 'auto',
|
|
260
273
|
};
|
|
261
274
|
|
|
262
|
-
const config = await
|
|
275
|
+
const config = await generateConfig(urls);
|
|
263
276
|
expect(config).toEqual(expectedConfig);
|
|
264
277
|
});
|
|
265
278
|
|
|
266
|
-
it('generates
|
|
267
|
-
const urls = ['http://localhost:
|
|
268
|
-
const expectedName = urls[0].split('/').at(-1);
|
|
279
|
+
it('generates correct config for Anndata-ZARR file with empty .zmetadata', async () => {
|
|
280
|
+
const urls = ['http://localhost:4204/@fixtures/zarr/partials/emptymeta.h5ad.zarr'];
|
|
269
281
|
const expectedConfig = {
|
|
270
282
|
version: '1.0.15',
|
|
271
283
|
name: 'An automatically generated config. Adjust values and add layout components if needed.',
|
|
@@ -273,7 +285,7 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
273
285
|
datasets: [
|
|
274
286
|
{
|
|
275
287
|
uid: 'A',
|
|
276
|
-
name:
|
|
288
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
277
289
|
files: [
|
|
278
290
|
{
|
|
279
291
|
url: urls[0],
|
|
@@ -298,20 +310,43 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
298
310
|
A: 'A',
|
|
299
311
|
},
|
|
300
312
|
},
|
|
301
|
-
layout: [
|
|
313
|
+
layout: [
|
|
314
|
+
{
|
|
315
|
+
component: 'obsSetSizes',
|
|
316
|
+
coordinationScopes: {
|
|
317
|
+
dataset: 'A',
|
|
318
|
+
},
|
|
319
|
+
h: 6,
|
|
320
|
+
w: 12,
|
|
321
|
+
x: 0,
|
|
322
|
+
y: 0,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
component: 'obsSetFeatureValueDistribution',
|
|
326
|
+
coordinationScopes: {
|
|
327
|
+
dataset: 'A',
|
|
328
|
+
},
|
|
329
|
+
h: 6,
|
|
330
|
+
w: 12,
|
|
331
|
+
x: 0,
|
|
332
|
+
y: 6,
|
|
333
|
+
},
|
|
334
|
+
],
|
|
302
335
|
initStrategy: 'auto',
|
|
303
336
|
};
|
|
304
337
|
|
|
305
|
-
const config = await
|
|
338
|
+
const config = await generateConfig(urls);
|
|
306
339
|
expect(config).toEqual(expectedConfig);
|
|
307
340
|
});
|
|
308
341
|
|
|
309
342
|
it('raises an error for Anndata-ZARR file with misconfigured .zmetadata', async () => {
|
|
310
|
-
const urls = ['http://localhost:
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
)
|
|
343
|
+
const urls = ['http://localhost:4204/@fixtures/zarr/partials/invalidmeta.adata.zarr'];
|
|
344
|
+
// References:
|
|
345
|
+
// - https://vitest.dev/api/expect.html#tothrowerror
|
|
346
|
+
// - https://vitest.dev/api/expect.html#rejects
|
|
347
|
+
await expect(() => generateConfig(urls))
|
|
348
|
+
.rejects
|
|
349
|
+
.toThrowError('Could not generate config: .zmetadata file is not valid.');
|
|
315
350
|
});
|
|
316
351
|
|
|
317
352
|
it('generates config for multiple files correctly', async () => {
|
|
@@ -325,7 +360,7 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
325
360
|
datasets: [
|
|
326
361
|
{
|
|
327
362
|
uid: 'A',
|
|
328
|
-
name:
|
|
363
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
329
364
|
files: [
|
|
330
365
|
{
|
|
331
366
|
fileType: 'raster.json',
|
|
@@ -344,12 +379,6 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
344
379
|
usePhysicalSizeScaling: false,
|
|
345
380
|
},
|
|
346
381
|
},
|
|
347
|
-
],
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
uid: 'B',
|
|
351
|
-
name: expectedNames[1],
|
|
352
|
-
files: [
|
|
353
382
|
{
|
|
354
383
|
url: urls[1],
|
|
355
384
|
fileType: 'raster.ome-zarr',
|
|
@@ -360,7 +389,6 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
360
389
|
coordinationSpace: {
|
|
361
390
|
dataset: {
|
|
362
391
|
A: 'A',
|
|
363
|
-
B: 'B',
|
|
364
392
|
},
|
|
365
393
|
},
|
|
366
394
|
layout: [
|
|
@@ -371,7 +399,7 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
371
399
|
},
|
|
372
400
|
x: 0,
|
|
373
401
|
y: 0,
|
|
374
|
-
w:
|
|
402
|
+
w: 6,
|
|
375
403
|
h: 4,
|
|
376
404
|
},
|
|
377
405
|
{
|
|
@@ -379,9 +407,9 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
379
407
|
coordinationScopes: {
|
|
380
408
|
dataset: 'A',
|
|
381
409
|
},
|
|
382
|
-
x:
|
|
410
|
+
x: 6,
|
|
383
411
|
y: 0,
|
|
384
|
-
w:
|
|
412
|
+
w: 6,
|
|
385
413
|
h: 4,
|
|
386
414
|
},
|
|
387
415
|
{
|
|
@@ -389,9 +417,9 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
389
417
|
coordinationScopes: {
|
|
390
418
|
dataset: 'A',
|
|
391
419
|
},
|
|
392
|
-
x:
|
|
393
|
-
y:
|
|
394
|
-
w:
|
|
420
|
+
x: 0,
|
|
421
|
+
y: 4,
|
|
422
|
+
w: 6,
|
|
395
423
|
h: 4,
|
|
396
424
|
props: {
|
|
397
425
|
disable3d: [],
|
|
@@ -401,65 +429,587 @@ describe('src/VitessceAutoConfig.js', () => {
|
|
|
401
429
|
{
|
|
402
430
|
component: 'description',
|
|
403
431
|
coordinationScopes: {
|
|
404
|
-
dataset: '
|
|
432
|
+
dataset: 'A',
|
|
405
433
|
},
|
|
406
|
-
x:
|
|
434
|
+
x: 6,
|
|
407
435
|
y: 4,
|
|
408
|
-
w:
|
|
436
|
+
w: 6,
|
|
409
437
|
h: 4,
|
|
410
438
|
},
|
|
411
439
|
{
|
|
412
440
|
component: 'spatial',
|
|
413
441
|
coordinationScopes: {
|
|
414
|
-
dataset: '
|
|
442
|
+
dataset: 'A',
|
|
415
443
|
},
|
|
416
|
-
x:
|
|
417
|
-
y:
|
|
418
|
-
w:
|
|
444
|
+
x: 0,
|
|
445
|
+
y: 8,
|
|
446
|
+
w: 6,
|
|
419
447
|
h: 4,
|
|
420
448
|
},
|
|
421
449
|
{
|
|
422
450
|
component: 'layerController',
|
|
423
451
|
coordinationScopes: {
|
|
424
|
-
dataset: '
|
|
452
|
+
dataset: 'A',
|
|
425
453
|
},
|
|
426
|
-
|
|
454
|
+
props: {
|
|
455
|
+
disable3d: [],
|
|
456
|
+
disableChannelsIfRgbDetected: true,
|
|
457
|
+
},
|
|
458
|
+
x: 6,
|
|
459
|
+
y: 8,
|
|
460
|
+
w: 6,
|
|
461
|
+
h: 4,
|
|
462
|
+
},
|
|
463
|
+
],
|
|
464
|
+
initStrategy: 'auto',
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
const config = await generateConfig(urls);
|
|
468
|
+
expect(config).toEqual(expectedConfig);
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
it('Does the parsing when .zmetadata file not present in folder', async () => {
|
|
473
|
+
const urls = ['http://localhost:4204/@fixtures/zarr/anndata-0.8/anndata-csr.adata.zarr'];
|
|
474
|
+
const expectedConfig = {
|
|
475
|
+
version: '1.0.15',
|
|
476
|
+
name: 'An automatically generated config. Adjust values and add layout components if needed.',
|
|
477
|
+
description: 'Populate with text relevant to this visualisation.',
|
|
478
|
+
datasets: [
|
|
479
|
+
{
|
|
480
|
+
uid: 'A',
|
|
481
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
482
|
+
files: [
|
|
483
|
+
{
|
|
484
|
+
url: urls[0],
|
|
485
|
+
fileType: 'anndata.zarr',
|
|
486
|
+
coordinationValues: {
|
|
487
|
+
obsType: 'cell',
|
|
488
|
+
featureType: 'gene',
|
|
489
|
+
featureValueType: 'expression',
|
|
490
|
+
},
|
|
491
|
+
options: {
|
|
492
|
+
obsEmbedding: [
|
|
493
|
+
{
|
|
494
|
+
path: 'obsm/X_umap',
|
|
495
|
+
embeddingType: 'UMAP',
|
|
496
|
+
},
|
|
497
|
+
],
|
|
498
|
+
obsFeatureMatrix: {
|
|
499
|
+
path: 'X',
|
|
500
|
+
},
|
|
501
|
+
obsSets: [
|
|
502
|
+
{
|
|
503
|
+
name: 'Cell Type',
|
|
504
|
+
path: 'obs/leiden',
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
],
|
|
510
|
+
},
|
|
511
|
+
],
|
|
512
|
+
coordinationSpace: {
|
|
513
|
+
dataset: {
|
|
514
|
+
A: 'A',
|
|
515
|
+
},
|
|
516
|
+
embeddingType: {
|
|
517
|
+
A: 'UMAP',
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
layout: [
|
|
521
|
+
{
|
|
522
|
+
component: 'scatterplot',
|
|
523
|
+
coordinationScopes: {
|
|
524
|
+
dataset: 'A',
|
|
525
|
+
embeddingType: 'A',
|
|
526
|
+
},
|
|
527
|
+
x: 0,
|
|
528
|
+
y: 0,
|
|
529
|
+
w: 6,
|
|
530
|
+
h: 4,
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
component: 'obsSetSizes',
|
|
534
|
+
coordinationScopes: {
|
|
535
|
+
dataset: 'A',
|
|
536
|
+
},
|
|
537
|
+
h: 4,
|
|
538
|
+
w: 6,
|
|
539
|
+
x: 6,
|
|
540
|
+
y: 0,
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
component: 'obsSetFeatureValueDistribution',
|
|
544
|
+
coordinationScopes: {
|
|
545
|
+
dataset: 'A',
|
|
546
|
+
},
|
|
547
|
+
h: 4,
|
|
548
|
+
w: 6,
|
|
549
|
+
x: 0,
|
|
427
550
|
y: 4,
|
|
428
|
-
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
component: 'heatmap',
|
|
554
|
+
coordinationScopes: {
|
|
555
|
+
dataset: 'A',
|
|
556
|
+
},
|
|
429
557
|
h: 4,
|
|
558
|
+
props: {
|
|
559
|
+
transpose: true,
|
|
560
|
+
},
|
|
561
|
+
w: 6,
|
|
562
|
+
x: 6,
|
|
563
|
+
y: 4,
|
|
430
564
|
},
|
|
431
565
|
{
|
|
432
|
-
component: '
|
|
566
|
+
component: 'featureList',
|
|
433
567
|
coordinationScopes: {
|
|
434
|
-
dataset: '
|
|
568
|
+
dataset: 'A',
|
|
435
569
|
},
|
|
570
|
+
h: 4,
|
|
571
|
+
w: 6,
|
|
436
572
|
x: 0,
|
|
437
573
|
y: 8,
|
|
438
|
-
w: 4,
|
|
439
|
-
h: 4,
|
|
440
574
|
},
|
|
441
575
|
],
|
|
442
576
|
initStrategy: 'auto',
|
|
443
577
|
};
|
|
444
578
|
|
|
445
|
-
const config = await
|
|
579
|
+
const config = await generateConfig(urls);
|
|
446
580
|
expect(config).toEqual(expectedConfig);
|
|
447
581
|
});
|
|
448
582
|
|
|
583
|
+
it('raises an error when URL with unsupported file format is passed', async () => {
|
|
584
|
+
const urls = ['http://localhost:4204/@fixtures/zarr/anndata-0.7/somefile.zarr'];
|
|
585
|
+
|
|
586
|
+
await generateConfig(urls, 'Transcriptomics / scRNA-seq (with heatmap)').catch(
|
|
587
|
+
e => expect(e.message).toContain('One or more of the URLs provided point to unsupported file types.'),
|
|
588
|
+
);
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
// ********** TESTS WITH HINTS **********
|
|
592
|
+
|
|
593
|
+
it('generates config with hints for OME-TIFF dataset types correctly', async () => {
|
|
594
|
+
const urls = ['somefile.ome.tif'];
|
|
595
|
+
const expectedConfig = {
|
|
596
|
+
version: '1.0.15',
|
|
597
|
+
name: 'An automatically generated config. Adjust values and add layout components if needed.',
|
|
598
|
+
description: 'Populate with text relevant to this visualisation.',
|
|
599
|
+
datasets: [
|
|
600
|
+
{
|
|
601
|
+
uid: 'A',
|
|
602
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
603
|
+
files: [
|
|
604
|
+
{
|
|
605
|
+
fileType: 'raster.json',
|
|
606
|
+
options: {
|
|
607
|
+
images: [
|
|
608
|
+
{
|
|
609
|
+
metadata: {
|
|
610
|
+
isBitmask: false,
|
|
611
|
+
},
|
|
612
|
+
name: 'somefile.ome.tif',
|
|
613
|
+
type: 'ome-tiff',
|
|
614
|
+
url: urls[0],
|
|
615
|
+
},
|
|
616
|
+
],
|
|
617
|
+
schemaVersion: '0.0.2',
|
|
618
|
+
usePhysicalSizeScaling: false,
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
],
|
|
622
|
+
},
|
|
623
|
+
],
|
|
624
|
+
coordinationSpace: {
|
|
625
|
+
dataset: {
|
|
626
|
+
A: 'A',
|
|
627
|
+
},
|
|
628
|
+
},
|
|
629
|
+
layout: [
|
|
630
|
+
{
|
|
631
|
+
component: 'spatial',
|
|
632
|
+
coordinationScopes: {
|
|
633
|
+
dataset: 'A',
|
|
634
|
+
},
|
|
635
|
+
x: 0,
|
|
636
|
+
y: 0,
|
|
637
|
+
w: 8,
|
|
638
|
+
h: 12,
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
component: 'layerController',
|
|
642
|
+
coordinationScopes: {
|
|
643
|
+
dataset: 'A',
|
|
644
|
+
},
|
|
645
|
+
x: 8,
|
|
646
|
+
y: 0,
|
|
647
|
+
w: 4,
|
|
648
|
+
h: 7,
|
|
649
|
+
props: {
|
|
650
|
+
disable3d: [],
|
|
651
|
+
disableChannelsIfRgbDetected: true,
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
component: 'description',
|
|
656
|
+
coordinationScopes: {
|
|
657
|
+
dataset: 'A',
|
|
658
|
+
},
|
|
659
|
+
h: 5,
|
|
660
|
+
w: 4,
|
|
661
|
+
x: 8,
|
|
662
|
+
y: 9,
|
|
663
|
+
},
|
|
664
|
+
],
|
|
665
|
+
initStrategy: 'auto',
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
const viewConfig = await generateConfig(urls, 'Image');
|
|
669
|
+
expect(viewConfig).toEqual(expectedConfig);
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
it('generates config with hints for OME-ZARR dataset types correctly', async () => {
|
|
673
|
+
const urls = ['somefile.ome.zarr'];
|
|
449
674
|
|
|
450
|
-
|
|
451
|
-
|
|
675
|
+
const expectedConfig = {
|
|
676
|
+
version: '1.0.15',
|
|
677
|
+
name: 'An automatically generated config. Adjust values and add layout components if needed.',
|
|
678
|
+
description: 'Populate with text relevant to this visualisation.',
|
|
679
|
+
datasets: [
|
|
680
|
+
{
|
|
681
|
+
uid: 'A',
|
|
682
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
683
|
+
files: [
|
|
684
|
+
{
|
|
685
|
+
fileType: 'raster.ome-zarr',
|
|
686
|
+
url: 'somefile.ome.zarr',
|
|
687
|
+
},
|
|
688
|
+
],
|
|
689
|
+
},
|
|
690
|
+
],
|
|
691
|
+
coordinationSpace: {
|
|
692
|
+
dataset: {
|
|
693
|
+
A: 'A',
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
layout: [
|
|
697
|
+
{
|
|
698
|
+
component: 'spatial',
|
|
699
|
+
coordinationScopes: {
|
|
700
|
+
dataset: 'A',
|
|
701
|
+
},
|
|
702
|
+
x: 0,
|
|
703
|
+
y: 0,
|
|
704
|
+
w: 8,
|
|
705
|
+
h: 12,
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
component: 'layerController',
|
|
709
|
+
coordinationScopes: {
|
|
710
|
+
dataset: 'A',
|
|
711
|
+
},
|
|
712
|
+
x: 8,
|
|
713
|
+
y: 0,
|
|
714
|
+
w: 4,
|
|
715
|
+
h: 7,
|
|
716
|
+
props: {
|
|
717
|
+
disable3d: [],
|
|
718
|
+
disableChannelsIfRgbDetected: true,
|
|
719
|
+
},
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
component: 'description',
|
|
723
|
+
coordinationScopes: {
|
|
724
|
+
dataset: 'A',
|
|
725
|
+
},
|
|
726
|
+
h: 5,
|
|
727
|
+
w: 4,
|
|
728
|
+
x: 8,
|
|
729
|
+
y: 9,
|
|
730
|
+
},
|
|
731
|
+
],
|
|
732
|
+
initStrategy: 'auto',
|
|
733
|
+
};
|
|
452
734
|
|
|
453
|
-
await
|
|
454
|
-
|
|
735
|
+
const viewConfig = await generateConfig(urls, 'Image');
|
|
736
|
+
expect(viewConfig).toEqual(expectedConfig);
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
it('generates config hints for Anndata-Zarr, OME-TIFF dataset types correctly', async () => {
|
|
740
|
+
const urls = ['somefile.ome.tif', 'http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
|
|
741
|
+
const expectedNames = [urls[0].split('/').at(-1), urls[1].split('/').at(-1)];
|
|
742
|
+
|
|
743
|
+
const expectedConfig = {
|
|
744
|
+
version: '1.0.15',
|
|
745
|
+
name: 'An automatically generated config. Adjust values and add layout components if needed.',
|
|
746
|
+
description: 'Populate with text relevant to this visualisation.',
|
|
747
|
+
datasets: [
|
|
748
|
+
{
|
|
749
|
+
uid: 'A',
|
|
750
|
+
name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
|
|
751
|
+
files: [
|
|
752
|
+
{
|
|
753
|
+
fileType: 'raster.json',
|
|
754
|
+
options: {
|
|
755
|
+
images: [
|
|
756
|
+
{
|
|
757
|
+
metadata: {
|
|
758
|
+
isBitmask: false,
|
|
759
|
+
},
|
|
760
|
+
name: expectedNames[0],
|
|
761
|
+
type: 'ome-tiff',
|
|
762
|
+
url: urls[0],
|
|
763
|
+
},
|
|
764
|
+
],
|
|
765
|
+
schemaVersion: '0.0.2',
|
|
766
|
+
usePhysicalSizeScaling: false,
|
|
767
|
+
},
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
url: urls[1],
|
|
771
|
+
coordinationValues: {
|
|
772
|
+
featureType: 'gene',
|
|
773
|
+
featureValueType: 'expression',
|
|
774
|
+
obsType: 'cell',
|
|
775
|
+
},
|
|
776
|
+
fileType: 'anndata.zarr',
|
|
777
|
+
options: {
|
|
778
|
+
obsFeatureMatrix: {
|
|
779
|
+
path: 'X',
|
|
780
|
+
},
|
|
781
|
+
obsEmbedding: [
|
|
782
|
+
{
|
|
783
|
+
embeddingType: 'UMAP',
|
|
784
|
+
path: 'obsm/X_umap',
|
|
785
|
+
},
|
|
786
|
+
],
|
|
787
|
+
obsSets: [
|
|
788
|
+
{
|
|
789
|
+
name: 'Cell Type',
|
|
790
|
+
path: [
|
|
791
|
+
'obs/cell_type',
|
|
792
|
+
'obs/disease',
|
|
793
|
+
'obs/leiden',
|
|
794
|
+
'obs/organism',
|
|
795
|
+
'obs/self_reported_ethnicity',
|
|
796
|
+
'obs/sex',
|
|
797
|
+
'obs/tissue',
|
|
798
|
+
],
|
|
799
|
+
},
|
|
800
|
+
],
|
|
801
|
+
},
|
|
802
|
+
},
|
|
803
|
+
],
|
|
804
|
+
},
|
|
805
|
+
],
|
|
806
|
+
coordinationSpace: {
|
|
807
|
+
dataset: {
|
|
808
|
+
A: 'A',
|
|
809
|
+
},
|
|
810
|
+
spatialSegmentationLayer: {
|
|
811
|
+
A: {
|
|
812
|
+
radius: 65,
|
|
813
|
+
stroked: true,
|
|
814
|
+
visible: true,
|
|
815
|
+
opacity: 1,
|
|
816
|
+
},
|
|
817
|
+
},
|
|
818
|
+
spatialImageLayer: {
|
|
819
|
+
A: [
|
|
820
|
+
{
|
|
821
|
+
type: 'raster',
|
|
822
|
+
index: 0,
|
|
823
|
+
colormap: null,
|
|
824
|
+
transparentColor: null,
|
|
825
|
+
opacity: 1,
|
|
826
|
+
domainType: 'Min/Max',
|
|
827
|
+
channels: [
|
|
828
|
+
{
|
|
829
|
+
selection: {
|
|
830
|
+
c: 0,
|
|
831
|
+
},
|
|
832
|
+
color: [
|
|
833
|
+
255,
|
|
834
|
+
0,
|
|
835
|
+
0,
|
|
836
|
+
],
|
|
837
|
+
visible: true,
|
|
838
|
+
slider: [
|
|
839
|
+
0,
|
|
840
|
+
255,
|
|
841
|
+
],
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
selection: {
|
|
845
|
+
c: 1,
|
|
846
|
+
},
|
|
847
|
+
color: [
|
|
848
|
+
0,
|
|
849
|
+
255,
|
|
850
|
+
0,
|
|
851
|
+
],
|
|
852
|
+
visible: true,
|
|
853
|
+
slider: [
|
|
854
|
+
0,
|
|
855
|
+
255,
|
|
856
|
+
],
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
selection: {
|
|
860
|
+
c: 2,
|
|
861
|
+
},
|
|
862
|
+
color: [
|
|
863
|
+
0,
|
|
864
|
+
0,
|
|
865
|
+
255,
|
|
866
|
+
],
|
|
867
|
+
visible: true,
|
|
868
|
+
slider: [
|
|
869
|
+
0,
|
|
870
|
+
255,
|
|
871
|
+
],
|
|
872
|
+
},
|
|
873
|
+
],
|
|
874
|
+
},
|
|
875
|
+
],
|
|
876
|
+
},
|
|
877
|
+
spatialZoom: {
|
|
878
|
+
A: null,
|
|
879
|
+
},
|
|
880
|
+
spatialTargetX: {
|
|
881
|
+
A: null,
|
|
882
|
+
},
|
|
883
|
+
spatialTargetY: {
|
|
884
|
+
A: null,
|
|
885
|
+
},
|
|
886
|
+
},
|
|
887
|
+
layout: [
|
|
888
|
+
{
|
|
889
|
+
component: 'spatial',
|
|
890
|
+
coordinationScopes: {
|
|
891
|
+
dataset: 'A',
|
|
892
|
+
spatialImageLayer: 'A',
|
|
893
|
+
spatialSegmentationLayer: 'A',
|
|
894
|
+
spatialTargetX: 'A',
|
|
895
|
+
spatialTargetY: 'A',
|
|
896
|
+
spatialZoom: 'A',
|
|
897
|
+
},
|
|
898
|
+
h: 6,
|
|
899
|
+
w: 6,
|
|
900
|
+
x: 0,
|
|
901
|
+
y: 0,
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
component: 'layerController',
|
|
905
|
+
coordinationScopes: {
|
|
906
|
+
dataset: 'A',
|
|
907
|
+
spatialImageLayer: 'A',
|
|
908
|
+
spatialSegmentationLayer: 'A',
|
|
909
|
+
spatialTargetX: 'A',
|
|
910
|
+
spatialTargetY: 'A',
|
|
911
|
+
spatialZoom: 'A',
|
|
912
|
+
},
|
|
913
|
+
h: 6,
|
|
914
|
+
props: {
|
|
915
|
+
disable3d: [],
|
|
916
|
+
disableChannelsIfRgbDetected: true,
|
|
917
|
+
},
|
|
918
|
+
w: 4,
|
|
919
|
+
x: 8,
|
|
920
|
+
y: 6,
|
|
921
|
+
},
|
|
922
|
+
{
|
|
923
|
+
component: 'heatmap',
|
|
924
|
+
coordinationScopes: {
|
|
925
|
+
dataset: 'A',
|
|
926
|
+
},
|
|
927
|
+
x: 0,
|
|
928
|
+
y: 6,
|
|
929
|
+
w: 8,
|
|
930
|
+
h: 6,
|
|
931
|
+
props: {
|
|
932
|
+
transpose: true,
|
|
933
|
+
},
|
|
934
|
+
},
|
|
935
|
+
{
|
|
936
|
+
component: 'obsSets',
|
|
937
|
+
coordinationScopes: {
|
|
938
|
+
dataset: 'A',
|
|
939
|
+
},
|
|
940
|
+
x: 9,
|
|
941
|
+
y: 0,
|
|
942
|
+
w: 3,
|
|
943
|
+
h: 6,
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
component: 'featureList',
|
|
947
|
+
coordinationScopes: {
|
|
948
|
+
dataset: 'A',
|
|
949
|
+
},
|
|
950
|
+
h: 6,
|
|
951
|
+
w: 3,
|
|
952
|
+
x: 6,
|
|
953
|
+
y: 0,
|
|
954
|
+
},
|
|
955
|
+
],
|
|
956
|
+
initStrategy: 'auto',
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
const viewConfig = await generateConfig(
|
|
960
|
+
urls,
|
|
961
|
+
'Spatial transcriptomics (with histology image and polygon cell segmentations)',
|
|
962
|
+
);
|
|
963
|
+
|
|
964
|
+
expect(viewConfig).toEqual(expectedConfig);
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
it('raises an error if the supplied dataset URLs and hint do not have any compatible views', async () => {
|
|
968
|
+
const urls = ['http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
|
|
969
|
+
const hint = 'Image';
|
|
970
|
+
|
|
971
|
+
await generateConfig(urls, hint).catch(
|
|
972
|
+
e => expect(e.message).toContain('No views found that are compatible with the supplied dataset URLs and hint.'),
|
|
455
973
|
);
|
|
456
974
|
});
|
|
457
975
|
|
|
458
|
-
it('raises an error
|
|
459
|
-
const urls = ['http://localhost:
|
|
976
|
+
it('raises an error if no views are found for the supplied hint string', async () => {
|
|
977
|
+
const urls = ['http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
|
|
978
|
+
const hint = 'I do not exist';
|
|
460
979
|
|
|
461
|
-
await
|
|
462
|
-
e => expect(e.message).toContain('
|
|
980
|
+
await generateConfig(urls, hint).catch(
|
|
981
|
+
e => expect(e.message).toContain('Hints config not found for the supplied hint: I do not exist'),
|
|
463
982
|
);
|
|
464
983
|
});
|
|
984
|
+
|
|
985
|
+
// ********** TESTS OF GET HINTS OPTIONS **********
|
|
986
|
+
|
|
987
|
+
it('returns a list of hints options for the supplied dataset URLs', async () => {
|
|
988
|
+
const urls = ['http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
|
|
989
|
+
const actualHintOptions = getHintOptions(urls);
|
|
990
|
+
|
|
991
|
+
expect(actualHintOptions).toEqual(HINT_TYPE_TO_FILE_TYPE_MAP['AnnData-Zarr']);
|
|
992
|
+
});
|
|
993
|
+
|
|
994
|
+
it('returns a list of hints options for the supplied dataset URLs', async () => {
|
|
995
|
+
const urls = [
|
|
996
|
+
'http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr',
|
|
997
|
+
'somefile.ome.zarr',
|
|
998
|
+
'http://localhost:4204/@fixtures/zarr/partials/.adata.zarr',
|
|
999
|
+
'somefile.ome.tiff',
|
|
1000
|
+
];
|
|
1001
|
+
const actualHintOptions = getHintOptions(urls);
|
|
1002
|
+
|
|
1003
|
+
expect(actualHintOptions).toEqual(HINT_TYPE_TO_FILE_TYPE_MAP['AnnData-Zarr,OME-TIFF']);
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
it('raises an error if no hints options are found for the supplied dataset URLs', async () => {
|
|
1007
|
+
const urls = ['unsupportedfiletype.txt', 'unsupportedfiletype2.ome.tiff'];
|
|
1008
|
+
|
|
1009
|
+
try {
|
|
1010
|
+
getHintOptions(urls);
|
|
1011
|
+
} catch (e) {
|
|
1012
|
+
expect(e.message).toContain('One or more of the URLs provided point to unsupported file types.');
|
|
1013
|
+
}
|
|
1014
|
+
});
|
|
465
1015
|
});
|