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