@vitessce/config 3.0.1 → 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.
@@ -4,6 +4,7 @@ import {
4
4
  VitessceConfig,
5
5
  hconcat,
6
6
  vconcat,
7
+ CL,
7
8
  } from './VitessceConfig.js';
8
9
 
9
10
  describe('src/api/VitessceConfig.js', () => {
@@ -263,6 +264,343 @@ describe('src/api/VitessceConfig.js', () => {
263
264
  });
264
265
  });
265
266
 
267
+ it('can add complex coordination', () => {
268
+ const config = new VitessceConfig({
269
+ schemaVersion: '1.0.16',
270
+ name: 'My config',
271
+ });
272
+ config.addComplexCoordination({
273
+ spatialImageLayer: CL([
274
+ {
275
+ image: 'S-1905-017737_bf',
276
+ spatialLayerVisible: true,
277
+ spatialLayerOpacity: 1,
278
+ spatialImageChannel: CL([
279
+ {
280
+ spatialTargetC: 0,
281
+ spatialChannelColor: [255, 0, 0],
282
+ },
283
+ {
284
+ spatialTargetC: 1,
285
+ spatialChannelColor: [0, 255, 0],
286
+ },
287
+ ]),
288
+ },
289
+ ]),
290
+ spatialSegmentationLayer: CL([
291
+ {
292
+ image: 'S-1905-017737',
293
+ spatialLayerVisible: true,
294
+ spatialLayerOpacity: 1,
295
+ spatialSegmentationChannel: CL([
296
+ {
297
+ obsType: 'Cortical Interstitia',
298
+ spatialTargetC: 0,
299
+ spatialChannelColor: [255, 0, 0],
300
+ },
301
+ {
302
+ obsType: 'Non-Globally Sclerotic Glomeruli',
303
+ spatialTargetC: 1,
304
+ spatialChannelColor: [255, 0, 0],
305
+ },
306
+ {
307
+ obsType: 'Globally Sclerotic Glomeruli',
308
+ spatialTargetC: 2,
309
+ spatialChannelColor: [255, 0, 0],
310
+ },
311
+ ]),
312
+ },
313
+ ]),
314
+ });
315
+ const configJSON = config.toJSON();
316
+ expect(configJSON.coordinationSpace).toEqual({
317
+ spatialImageLayer: { A: '__dummy__' },
318
+ image: { A: 'S-1905-017737_bf', B: 'S-1905-017737' },
319
+ spatialLayerVisible: { A: true, B: true },
320
+ spatialLayerOpacity: { A: 1, B: 1 },
321
+ spatialImageChannel: { A: '__dummy__', B: '__dummy__' },
322
+ spatialTargetC: {
323
+ A: 0, B: 1, C: 0, D: 1, E: 2,
324
+ },
325
+ spatialChannelColor: {
326
+ A: [255, 0, 0], B: [0, 255, 0], C: [255, 0, 0], D: [255, 0, 0], E: [255, 0, 0],
327
+ },
328
+ spatialSegmentationLayer: { A: '__dummy__' },
329
+ spatialSegmentationChannel: { A: '__dummy__', B: '__dummy__', C: '__dummy__' },
330
+ obsType: {
331
+ A: 'Cortical Interstitia',
332
+ B: 'Non-Globally Sclerotic Glomeruli',
333
+ C: 'Globally Sclerotic Glomeruli',
334
+ },
335
+ });
336
+ });
337
+
338
+ it('can add _and use_ complex coordination', () => {
339
+ const config = new VitessceConfig({
340
+ schemaVersion: '1.0.16',
341
+ name: 'My config',
342
+ });
343
+ const dataset = config.addDataset('My dataset');
344
+
345
+ const scopes = config.addComplexCoordination({
346
+ spatialImageLayer: CL([
347
+ {
348
+ image: 'S-1905-017737_bf',
349
+ spatialLayerVisible: true,
350
+ spatialLayerOpacity: 1,
351
+ spatialImageChannel: CL([
352
+ {
353
+ spatialTargetC: 0,
354
+ spatialChannelColor: [255, 0, 0],
355
+ },
356
+ {
357
+ spatialTargetC: 1,
358
+ spatialChannelColor: [0, 255, 0],
359
+ },
360
+ ]),
361
+ },
362
+ ]),
363
+ spatialSegmentationLayer: CL([
364
+ {
365
+ image: 'S-1905-017737',
366
+ spatialLayerVisible: true,
367
+ spatialLayerOpacity: 1,
368
+ spatialSegmentationChannel: CL([
369
+ {
370
+ obsType: 'Cortical Interstitia',
371
+ spatialTargetC: 0,
372
+ spatialChannelColor: [255, 0, 0],
373
+ },
374
+ {
375
+ obsType: 'Non-Globally Sclerotic Glomeruli',
376
+ spatialTargetC: 1,
377
+ spatialChannelColor: [255, 0, 0],
378
+ },
379
+ {
380
+ obsType: 'Globally Sclerotic Glomeruli',
381
+ spatialTargetC: 2,
382
+ spatialChannelColor: [255, 0, 0],
383
+ },
384
+ ]),
385
+ },
386
+ ]),
387
+ });
388
+
389
+ const spatialView = config.addView(dataset, 'spatial');
390
+ spatialView.useComplexCoordination(scopes);
391
+
392
+ const configJSON = config.toJSON();
393
+ expect(configJSON).toEqual({
394
+ version: '1.0.16',
395
+ name: 'My config',
396
+ datasets: [{ uid: 'A', name: 'My dataset', files: [] }],
397
+ coordinationSpace: {
398
+ dataset: { A: 'A' },
399
+ spatialImageLayer: { A: '__dummy__' },
400
+ image: { A: 'S-1905-017737_bf', B: 'S-1905-017737' },
401
+ spatialLayerVisible: { A: true, B: true },
402
+ spatialLayerOpacity: { A: 1, B: 1 },
403
+ spatialImageChannel: { A: '__dummy__', B: '__dummy__' },
404
+ spatialTargetC: {
405
+ A: 0, B: 1, C: 0, D: 1, E: 2,
406
+ },
407
+ spatialChannelColor: {
408
+ A: [255, 0, 0],
409
+ B: [0, 255, 0],
410
+ C: [255, 0, 0],
411
+ D: [255, 0, 0],
412
+ E: [255, 0, 0],
413
+ },
414
+ spatialSegmentationLayer: { A: '__dummy__' },
415
+ spatialSegmentationChannel: { A: '__dummy__', B: '__dummy__', C: '__dummy__' },
416
+ obsType: {
417
+ A: 'Cortical Interstitia',
418
+ B: 'Non-Globally Sclerotic Glomeruli',
419
+ C: 'Globally Sclerotic Glomeruli',
420
+ },
421
+ },
422
+ layout: [{
423
+ component: 'spatial',
424
+ coordinationScopes: {
425
+ dataset: 'A',
426
+ spatialImageLayer: ['A'],
427
+ spatialSegmentationLayer: ['A'],
428
+ },
429
+ coordinationScopesBy: {
430
+ spatialImageLayer: {
431
+ image: { A: 'A' },
432
+ spatialLayerVisible: { A: 'A' },
433
+ spatialLayerOpacity: { A: 'A' },
434
+ spatialImageChannel: { A: ['A', 'B'] },
435
+ },
436
+ spatialImageChannel: {
437
+ spatialTargetC: { A: 'A', B: 'B' },
438
+ spatialChannelColor: { A: 'A', B: 'B' },
439
+ },
440
+ spatialSegmentationLayer: {
441
+ image: { A: 'B' },
442
+ spatialLayerVisible: { A: 'B' },
443
+ spatialLayerOpacity: { A: 'B' },
444
+ spatialSegmentationChannel: { A: ['A', 'B', 'C'] },
445
+ },
446
+ spatialSegmentationChannel: {
447
+ obsType: { A: 'A', B: 'B', C: 'C' },
448
+ spatialTargetC: { A: 'C', B: 'D', C: 'E' },
449
+ spatialChannelColor: { A: 'C', B: 'D', C: 'E' },
450
+ },
451
+ },
452
+ x: 0,
453
+ y: 0,
454
+ w: 1,
455
+ h: 1,
456
+ }],
457
+ initStrategy: 'auto',
458
+ });
459
+ });
460
+
461
+ it('can use _meta_ complex coordination', () => {
462
+ const config = new VitessceConfig({
463
+ schemaVersion: '1.0.16',
464
+ name: 'My config',
465
+ });
466
+ const dataset = config.addDataset('My dataset');
467
+
468
+ const scopes = config.addComplexCoordination({
469
+ spatialImageLayer: CL([
470
+ {
471
+ image: 'S-1905-017737_bf',
472
+ spatialLayerVisible: true,
473
+ spatialLayerOpacity: 1,
474
+ spatialImageChannel: CL([
475
+ {
476
+ spatialTargetC: 0,
477
+ spatialChannelColor: [255, 0, 0],
478
+ },
479
+ {
480
+ spatialTargetC: 1,
481
+ spatialChannelColor: [0, 255, 0],
482
+ },
483
+ ]),
484
+ },
485
+ ]),
486
+ spatialSegmentationLayer: CL([
487
+ {
488
+ image: 'S-1905-017737',
489
+ spatialLayerVisible: true,
490
+ spatialLayerOpacity: 1,
491
+ spatialSegmentationChannel: CL([
492
+ {
493
+ obsType: 'Cortical Interstitia',
494
+ spatialTargetC: 0,
495
+ spatialChannelColor: [255, 0, 0],
496
+ },
497
+ {
498
+ obsType: 'Non-Globally Sclerotic Glomeruli',
499
+ spatialTargetC: 1,
500
+ spatialChannelColor: [255, 0, 0],
501
+ },
502
+ {
503
+ obsType: 'Globally Sclerotic Glomeruli',
504
+ spatialTargetC: 2,
505
+ spatialChannelColor: [255, 0, 0],
506
+ },
507
+ ]),
508
+ },
509
+ ]),
510
+ });
511
+
512
+ const metaCoordinationScope = config.addMetaCoordination();
513
+ metaCoordinationScope.useComplexCoordination(scopes);
514
+
515
+ const spatialView = config.addView(dataset, 'spatial');
516
+ const lcView = config.addView(dataset, 'layerController');
517
+ spatialView.useMetaCoordination(metaCoordinationScope);
518
+ lcView.useMetaCoordination(metaCoordinationScope);
519
+
520
+ const configJSON = config.toJSON();
521
+ expect(configJSON).toEqual({
522
+ version: '1.0.16',
523
+ name: 'My config',
524
+ datasets: [{ uid: 'A', name: 'My dataset', files: [] }],
525
+ coordinationSpace: {
526
+ dataset: { A: 'A' },
527
+ spatialImageLayer: { A: '__dummy__' },
528
+ image: { A: 'S-1905-017737_bf', B: 'S-1905-017737' },
529
+ spatialLayerVisible: { A: true, B: true },
530
+ spatialLayerOpacity: { A: 1, B: 1 },
531
+ spatialImageChannel: { A: '__dummy__', B: '__dummy__' },
532
+ spatialTargetC: {
533
+ A: 0, B: 1, C: 0, D: 1, E: 2,
534
+ },
535
+ spatialChannelColor: {
536
+ A: [255, 0, 0],
537
+ B: [0, 255, 0],
538
+ C: [255, 0, 0],
539
+ D: [255, 0, 0],
540
+ E: [255, 0, 0],
541
+ },
542
+ spatialSegmentationLayer: { A: '__dummy__' },
543
+ spatialSegmentationChannel: { A: '__dummy__', B: '__dummy__', C: '__dummy__' },
544
+ obsType: {
545
+ A: 'Cortical Interstitia',
546
+ B: 'Non-Globally Sclerotic Glomeruli',
547
+ C: 'Globally Sclerotic Glomeruli',
548
+ },
549
+ metaCoordinationScopes: {
550
+ A: {
551
+ spatialImageLayer: ['A'],
552
+ spatialSegmentationLayer: ['A'],
553
+ },
554
+ },
555
+ metaCoordinationScopesBy: {
556
+ A: {
557
+ spatialImageLayer: {
558
+ image: { A: 'A' },
559
+ spatialLayerVisible: { A: 'A' },
560
+ spatialLayerOpacity: { A: 'A' },
561
+ spatialImageChannel: { A: ['A', 'B'] },
562
+ },
563
+ spatialImageChannel: {
564
+ spatialTargetC: { A: 'A', B: 'B' },
565
+ spatialChannelColor: { A: 'A', B: 'B' },
566
+ },
567
+ spatialSegmentationLayer: {
568
+ image: { A: 'B' },
569
+ spatialLayerVisible: { A: 'B' },
570
+ spatialLayerOpacity: { A: 'B' },
571
+ spatialSegmentationChannel: { A: ['A', 'B', 'C'] },
572
+ },
573
+ spatialSegmentationChannel: {
574
+ obsType: { A: 'A', B: 'B', C: 'C' },
575
+ spatialTargetC: { A: 'C', B: 'D', C: 'E' },
576
+ spatialChannelColor: { A: 'C', B: 'D', C: 'E' },
577
+ },
578
+ },
579
+ },
580
+ },
581
+ layout: [{
582
+ component: 'spatial',
583
+ coordinationScopes: {
584
+ dataset: 'A',
585
+ metaCoordinationScopes: ['A'],
586
+ metaCoordinationScopesBy: ['A'],
587
+ },
588
+ // eslint-disable-next-line object-property-newline
589
+ x: 0, y: 0, w: 1, h: 1,
590
+ }, {
591
+ component: 'layerController',
592
+ coordinationScopes: {
593
+ dataset: 'A',
594
+ metaCoordinationScopes: ['A'],
595
+ metaCoordinationScopesBy: ['A'],
596
+ },
597
+ // eslint-disable-next-line object-property-newline
598
+ x: 0, y: 0, w: 1, h: 1,
599
+ }],
600
+ initStrategy: 'auto',
601
+ });
602
+ });
603
+
266
604
  it('can add a coordination scope using the link views convenience function', () => {
267
605
  const config = new VitessceConfig({
268
606
  schemaVersion: '1.0.4',
@@ -0,0 +1,94 @@
1
+ const SINGLE_CELL_WITH_HEATMAP_VIEWS = {
2
+ obsSets: { x: 4, y: 0, w: 4, h: 4 },
3
+ obsSetSizes: { x: 8, y: 0, w: 4, h: 4 },
4
+ scatterplot: { x: 0, y: 0, w: 4, h: 4 },
5
+ heatmap: { x: 0, y: 4, w: 8, h: 4 },
6
+ featureList: { x: 8, y: 4, w: 4, h: 4 },
7
+ };
8
+
9
+ const SINGLE_CELL_WITHOUT_HEATMAP_VIEWS = {
10
+ obsSets: { x: 10, y: 6, w: 2, h: 6 },
11
+ obsSetSizes: { x: 8, y: 1, w: 4, h: 6 },
12
+ scatterplot: { x: 0, y: 0, w: 8, h: 12 },
13
+ featureList: { x: 8, y: 6, w: 2, h: 6 },
14
+ };
15
+
16
+ const SPATIAL_TRANSCRIPTOMICS_VIEWS = {
17
+ scatterplot: { x: 0, y: 0, w: 3, h: 4 },
18
+ spatial: { x: 3, y: 0, w: 5, h: 4 },
19
+ obsSets: { x: 8, y: 0, w: 4, h: 2 },
20
+ featureList: { x: 8, y: 0, w: 4, h: 2 },
21
+ heatmap: { x: 0, y: 4, w: 6, h: 4 },
22
+ obsSetFeatureValueDistribution: { x: 6, y: 4, w: 6, h: 4 },
23
+ };
24
+
25
+ const SPATIAL_TRANSCRIPTOMICS_WITH_HSITOLOGY_VIEWS = {
26
+ spatial: { x: 0, y: 0, w: 6, h: 6 },
27
+ heatmap: { x: 0, y: 6, w: 8, h: 6 },
28
+ layerController: { x: 8, y: 6, w: 4, h: 6 },
29
+ obsSets: { x: 9, y: 0, w: 3, h: 6 },
30
+ featureList: { x: 6, y: 0, w: 3, h: 6 },
31
+ };
32
+
33
+ const IMAGE_VIEWS = {
34
+ spatial: { x: 0, y: 0, w: 8, h: 12 },
35
+ layerController: { x: 8, y: 0, w: 4, h: 7 },
36
+ description: { x: 8, y: 9, w: 4, h: 5 },
37
+ };
38
+
39
+ export const NO_HINTS_CONFIG = {
40
+ views: {},
41
+ coordinationValues: {},
42
+ };
43
+
44
+ export const HINTS_CONFIG = {
45
+ 'No hints are available. Generate config with no hints.': NO_HINTS_CONFIG,
46
+ Basic: NO_HINTS_CONFIG,
47
+ 'Transcriptomics / scRNA-seq (with heatmap)': {
48
+ views: SINGLE_CELL_WITH_HEATMAP_VIEWS,
49
+ },
50
+ 'Transcriptomics / scRNA-seq (without heatmap)': {
51
+ views: SINGLE_CELL_WITHOUT_HEATMAP_VIEWS,
52
+ },
53
+ 'Spatial transcriptomics (with polygon cell segmentations)': {
54
+ views: SPATIAL_TRANSCRIPTOMICS_VIEWS,
55
+ },
56
+ 'Chromatin accessibility / scATAC-seq (with heatmap)': {
57
+ views: SINGLE_CELL_WITH_HEATMAP_VIEWS,
58
+ coordinationValues: {
59
+ featureType: 'peak',
60
+ },
61
+ },
62
+ 'Chromatin accessibility / scATAC-seq (without heatmap)': {
63
+ views: SINGLE_CELL_WITHOUT_HEATMAP_VIEWS,
64
+ coordinationValues: {
65
+ featureType: 'peak',
66
+ },
67
+ },
68
+ 'Spatial transcriptomics (with histology image and polygon cell segmentations)': {
69
+ views: SPATIAL_TRANSCRIPTOMICS_WITH_HSITOLOGY_VIEWS,
70
+ coordinationSpaceRequired: true,
71
+ },
72
+ Image: {
73
+ views: IMAGE_VIEWS,
74
+ },
75
+ };
76
+
77
+ export const HINT_TYPE_TO_FILE_TYPE_MAP = {
78
+ 'AnnData-Zarr': [
79
+ 'Basic',
80
+ 'Transcriptomics / scRNA-seq (with heatmap)',
81
+ 'Transcriptomics / scRNA-seq (without heatmap)',
82
+ 'Spatial transcriptomics (with polygon cell segmentations)',
83
+ 'Chromatin accessibility / scATAC-seq (with heatmap)',
84
+ 'Chromatin accessibility / scATAC-seq (without heatmap)',
85
+ ],
86
+ 'OME-TIFF': [
87
+ 'Basic',
88
+ 'Image',
89
+ ],
90
+ 'AnnData-Zarr,OME-TIFF': [
91
+ 'Basic',
92
+ 'Spatial transcriptomics (with histology image and polygon cell segmentations)',
93
+ ],
94
+ };
package/src/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { VitessceConfig, vconcat, hconcat } from './VitessceConfig.js';
2
- export { generateConfigs } from './VitessceAutoConfig.js';
2
+ export { generateConfig, getHintOptions } from './VitessceAutoConfig.js';
3
+ export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from './constants.js';