@vitessce/config 3.8.4 → 3.8.6
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/blosc-DvQQ1ST0.js +887 -0
- package/dist/chunk-INHXZS53-DHVJiuU3.js +19 -0
- package/dist/index.js +2487 -22
- package/dist/lz4-BIbM36RN.js +801 -0
- package/dist/zstd-CO575QiM.js +769 -0
- package/dist-tsc/generate-config-anndata.js +1 -1
- package/dist-tsc/generate-config-helpers.d.ts +1 -1
- package/dist-tsc/generate-config-helpers.d.ts.map +1 -1
- package/dist-tsc/generate-config-helpers.js +1 -1
- package/dist-tsc/generate-config-ome.d.ts.map +1 -1
- package/dist-tsc/generate-config-ome.js +7 -2
- package/dist-tsc/generate-config-spatialdata.d.ts.map +1 -1
- package/dist-tsc/generate-config-spatialdata.js +23 -2
- package/dist-tsc/generate-config.d.ts +10 -1
- package/dist-tsc/generate-config.d.ts.map +1 -1
- package/dist-tsc/generate-config.js +25 -11
- package/dist-tsc/generate-config.test.js +6 -6
- package/dist-tsc/index.d.ts +1 -0
- package/dist-tsc/index.js +1 -0
- package/package.json +6 -5
- package/src/generate-config-anndata.js +1 -1
- package/src/generate-config-helpers.js +1 -1
- package/src/generate-config-ome.js +8 -2
- package/src/generate-config-spatialdata.js +27 -2
- package/src/generate-config.js +29 -11
- package/src/generate-config.test.js +6 -6
- package/src/index.js +2 -0
|
@@ -4,6 +4,6 @@ export class AbstractAutoConfig {
|
|
|
4
4
|
fileType: any;
|
|
5
5
|
zmetadata: any;
|
|
6
6
|
addFiles(vc: any, dataset: any): void;
|
|
7
|
-
addViews(vc: any, layoutOption: any): void;
|
|
7
|
+
addViews(vc: any, dataset: any, layoutOption: any): void;
|
|
8
8
|
}
|
|
9
9
|
//# sourceMappingURL=generate-config-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-config-helpers.d.ts","sourceRoot":"","sources":["../src/generate-config-helpers.js"],"names":[],"mappings":"AACA;IACE,8BAKC;IAHC,SAAc;IACd,cAAwB;IACxB,eAA0B;IAI5B,sCAEC;IAGD,
|
|
1
|
+
{"version":3,"file":"generate-config-helpers.d.ts","sourceRoot":"","sources":["../src/generate-config-helpers.js"],"names":[],"mappings":"AACA;IACE,8BAKC;IAHC,SAAc;IACd,cAAwB;IACxB,eAA0B;IAI5B,sCAEC;IAGD,yDAEC;CACF"}
|
|
@@ -11,7 +11,7 @@ export class AbstractAutoConfig {
|
|
|
11
11
|
throw new Error('The addFiles() method has not been implemented.');
|
|
12
12
|
}
|
|
13
13
|
// eslint-disable-next-line class-methods-use-this
|
|
14
|
-
addViews(vc, layoutOption) {
|
|
14
|
+
addViews(vc, dataset, layoutOption) {
|
|
15
15
|
throw new Error('The addViews() method has not been implemented.');
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-config-ome.d.ts","sourceRoot":"","sources":["../src/generate-config-ome.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate-config-ome.d.ts","sourceRoot":"","sources":["../src/generate-config-ome.js"],"names":[],"mappings":"AAMA;CAoBC;mCAxBkC,8BAA8B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
+
import { hconcat, vconcat } from './VitessceConfig.js';
|
|
2
3
|
import { AbstractAutoConfig } from './generate-config-helpers.js';
|
|
3
4
|
// TODO: split into separate classes for OME-TIFF and OME-Zarr?
|
|
4
5
|
// TODO: split into separate classes for image and obsSegmentations?
|
|
@@ -13,7 +14,11 @@ export class OmeAutoConfig extends AbstractAutoConfig {
|
|
|
13
14
|
});
|
|
14
15
|
}
|
|
15
16
|
// eslint-disable-next-line class-methods-use-this
|
|
16
|
-
addViews(vc, layoutOption) {
|
|
17
|
-
//
|
|
17
|
+
addViews(vc, dataset, layoutOption) {
|
|
18
|
+
// Add spatialBeta/layerControllerBeta views.
|
|
19
|
+
const spatialView = vc.addView(dataset, 'spatialBeta');
|
|
20
|
+
const lcView = vc.addView(dataset, 'layerControllerBeta');
|
|
21
|
+
// Layout.
|
|
22
|
+
vc.layout(hconcat(spatialView, lcView));
|
|
18
23
|
}
|
|
19
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-config-spatialdata.d.ts","sourceRoot":"","sources":["../src/generate-config-spatialdata.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate-config-spatialdata.d.ts","sourceRoot":"","sources":["../src/generate-config-spatialdata.js"],"names":[],"mappings":"AAIA;IACE,iBA6FC;CAqCF;mCArIkC,8BAA8B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
+
import { hconcat, vconcat } from './VitessceConfig.js';
|
|
2
3
|
import { AbstractAutoConfig } from './generate-config-helpers.js';
|
|
3
4
|
export class SpatialDataAutoConfig extends AbstractAutoConfig {
|
|
4
5
|
getOptions() {
|
|
@@ -70,6 +71,9 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
|
|
|
70
71
|
// region: null,
|
|
71
72
|
tablePath: relPath,
|
|
72
73
|
obsSets: columnOrder.map(c => ({
|
|
74
|
+
// TODO: determine whether this column is string/categorical.
|
|
75
|
+
// TODO: determine whether this column contains too many
|
|
76
|
+
// categories to make sense to consider a cell set.
|
|
73
77
|
path: `${hasObs.path.substring(1)}/${c}`,
|
|
74
78
|
name: c,
|
|
75
79
|
})),
|
|
@@ -89,7 +93,24 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
|
|
|
89
93
|
});
|
|
90
94
|
}
|
|
91
95
|
// eslint-disable-next-line class-methods-use-this
|
|
92
|
-
addViews(vc, layoutOption) {
|
|
93
|
-
|
|
96
|
+
addViews(vc, dataset, layoutOption) {
|
|
97
|
+
const options = this.getOptions();
|
|
98
|
+
// Add spatialBeta/layerControllerBeta views.
|
|
99
|
+
const spatialView = vc.addView(dataset, 'spatialBeta');
|
|
100
|
+
const lcView = vc.addView(dataset, 'layerControllerBeta');
|
|
101
|
+
const controlViews = [lcView];
|
|
102
|
+
// If obsSets are present, add obsSets view.
|
|
103
|
+
if (options.obsSets) {
|
|
104
|
+
const obsSets = vc.addView(dataset, 'obsSets');
|
|
105
|
+
controlViews.push(obsSets);
|
|
106
|
+
}
|
|
107
|
+
// If obsFeatureMatrix is present, add featureList view.
|
|
108
|
+
if (options.obsFeatureMatrix) {
|
|
109
|
+
const featureList = vc.addView(dataset, 'featureList');
|
|
110
|
+
controlViews.push(featureList);
|
|
111
|
+
}
|
|
112
|
+
// TODO: set up coordination stuff here?
|
|
113
|
+
// Layout.
|
|
114
|
+
vc.layout(hconcat(spatialView, vconcat(...controlViews)));
|
|
94
115
|
}
|
|
95
116
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {string[]} arr
|
|
4
|
+
* @returns {{ url: string, fileType: string }[]} The URLs with file types.
|
|
5
|
+
*/
|
|
6
|
+
export function parseUrls(arr: string[]): {
|
|
7
|
+
url: string;
|
|
8
|
+
fileType: string;
|
|
9
|
+
}[];
|
|
1
10
|
/**
|
|
2
11
|
*
|
|
3
12
|
* @param {string} s A single string, like this
|
|
@@ -5,7 +14,7 @@
|
|
|
5
14
|
* http://example.com/my_tiff.ome.tif`
|
|
6
15
|
* @returns {{ url: string, fileType: string}[]} The URLs with file types.
|
|
7
16
|
*/
|
|
8
|
-
export function
|
|
17
|
+
export function parseUrlsFromString(s: string): {
|
|
9
18
|
url: string;
|
|
10
19
|
fileType: string;
|
|
11
20
|
}[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-config.d.ts","sourceRoot":"","sources":["../src/generate-config.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate-config.d.ts","sourceRoot":"","sources":["../src/generate-config.js"],"names":[],"mappings":"AA4GA;;;;GAIG;AACH,+BAHW,MAAM,EAAE,GACN;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAAE,CAoB/C;AAED;;;;;;GAMG;AACH,uCALW,MAAM,GAGJ;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,EAAE,CAK9C;AAGD;;;;YAsEC;AAED;;;;GAIG;AACH,sDAHW;IAAE,GAAG,MAAC;IAAC,QAAQ,MAAC;IAAC,KAAK,MAAA;CAAE,EAAE,GACzB,MAAM,EAAE,CAOnB;AAED;;;;GAIG;AACH,2CAHW;IAAE,GAAG,MAAC;IAAC,QAAQ,MAAC;IAAC,KAAK,MAAA;CAAE,EAAE,iBAC1B,MAAM,GAAC,IAAI;;;GAoDrB;+BAtR8B,qBAAqB"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
// TODO: ts-check
|
|
2
2
|
import { FileType } from '@vitessce/constants-internal';
|
|
3
|
-
import { withConsolidated, FetchStore,
|
|
3
|
+
import { withConsolidated, FetchStore, open as zarrOpen, root as zarrRoot } from 'zarrita';
|
|
4
|
+
// eslint-disable-next-line import/no-unresolved
|
|
5
|
+
import ZipFileStore from '@zarrita/storage/zip';
|
|
4
6
|
import { transformEntriesForZipFileStore } from '@vitessce/zarr-utils';
|
|
5
7
|
import { VitessceConfig } from './VitessceConfig.js';
|
|
6
8
|
// Classes for different types of objects
|
|
7
9
|
import { AnnDataAutoConfig } from './generate-config-anndata.js';
|
|
8
10
|
import { SpatialDataAutoConfig } from './generate-config-spatialdata.js';
|
|
9
11
|
import { OmeAutoConfig } from './generate-config-ome.js';
|
|
12
|
+
// TODO: make this a function parameter?
|
|
13
|
+
const FILE_TYPE_DELIM = '$';
|
|
10
14
|
const fileTypeToExtensions = {
|
|
11
15
|
[FileType.IMAGE_OME_TIFF]: ['.ome.tif', '.ome.tiff', '.ome.tf2', '.ome.tf8'],
|
|
12
16
|
[FileType.IMAGE_OME_ZARR]: ['.ome.zarr'],
|
|
@@ -47,6 +51,8 @@ const ZARR_FILETYPES = [
|
|
|
47
51
|
FileType.OBS_SEGMENTATIONS_OME_ZARR_ZIP,
|
|
48
52
|
];
|
|
49
53
|
function urlToFileType(url) {
|
|
54
|
+
// TODO: for plain .zarr, we could open the root .attrs and try to guess a fileType
|
|
55
|
+
// (we can probably infer at least whether OME-Zarr vs. AnnData vs. SpatialData).
|
|
50
56
|
const match = Object.entries(fileTypeToExtensions).find(
|
|
51
57
|
// eslint-disable-next-line no-unused-vars
|
|
52
58
|
([fileType, extensions]) => extensions.some(ext => url.endsWith(ext)));
|
|
@@ -91,15 +97,12 @@ function ensureStores(parsedUrls) {
|
|
|
91
97
|
}
|
|
92
98
|
/**
|
|
93
99
|
*
|
|
94
|
-
* @param {string}
|
|
95
|
-
*
|
|
96
|
-
* http://example.com/my_tiff.ome.tif`
|
|
97
|
-
* @returns {{ url: string, fileType: string}[]} The URLs with file types.
|
|
100
|
+
* @param {string[]} arr
|
|
101
|
+
* @returns {{ url: string, fileType: string }[]} The URLs with file types.
|
|
98
102
|
*/
|
|
99
|
-
export function parseUrls(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const parts = urlWithHash.split('#');
|
|
103
|
+
export function parseUrls(arr) {
|
|
104
|
+
return arr.map((urlWithHash) => {
|
|
105
|
+
const parts = urlWithHash.split(FILE_TYPE_DELIM);
|
|
103
106
|
if (parts.length === 1) {
|
|
104
107
|
const [url] = parts;
|
|
105
108
|
return {
|
|
@@ -114,9 +117,20 @@ export function parseUrls(s) {
|
|
|
114
117
|
fileType,
|
|
115
118
|
};
|
|
116
119
|
}
|
|
117
|
-
throw new Error(
|
|
120
|
+
throw new Error(`Only expected zero or one ${FILE_TYPE_DELIM} character per URL, but received more.`);
|
|
118
121
|
});
|
|
119
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
*
|
|
125
|
+
* @param {string} s A single string, like this
|
|
126
|
+
* `http://example.com/my_zarr.zarr#anndata.zarr;
|
|
127
|
+
* http://example.com/my_tiff.ome.tif`
|
|
128
|
+
* @returns {{ url: string, fileType: string}[]} The URLs with file types.
|
|
129
|
+
*/
|
|
130
|
+
export function parseUrlsFromString(s) {
|
|
131
|
+
const urlsWithHashes = s.split(';');
|
|
132
|
+
return parseUrls(urlsWithHashes);
|
|
133
|
+
}
|
|
120
134
|
export async function parsedUrlToZmetadata(parsedUrl) {
|
|
121
135
|
const { store: initialStore } = parsedUrl;
|
|
122
136
|
if (!initialStore) {
|
|
@@ -226,7 +240,7 @@ export async function generateConfig(parsedUrls, layoutOption = null) {
|
|
|
226
240
|
const autoConfig = new AutoConfigClass(parsedStore);
|
|
227
241
|
autoConfig.addFiles(vc, dataset);
|
|
228
242
|
// TODO: add all files, then add all views (in two separate loops)?
|
|
229
|
-
autoConfig.addViews(vc, layoutOption);
|
|
243
|
+
autoConfig.addViews(vc, dataset, layoutOption);
|
|
230
244
|
});
|
|
231
245
|
const stores = Object.fromEntries(
|
|
232
246
|
// Here, we use `parsedUrls` rather than `parsedStores`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { createStoreFromMapContents } from '@vitessce/zarr-utils';
|
|
3
3
|
import { withConsolidated } from 'zarrita';
|
|
4
|
-
import {
|
|
4
|
+
import { parseUrlsFromString, parsedUrlToZmetadata, generateConfig } from './generate-config.js';
|
|
5
5
|
import spatialdataMouseLiverFixture from './json-fixtures/mouse_liver.spatialdata.json';
|
|
6
6
|
import anndataMouseLiverFixture from './json-fixtures/mouse_liver.anndata.json';
|
|
7
7
|
import imageOmeZarrMouseLiverFixture from './json-fixtures/mouse_liver.ome.json';
|
|
@@ -9,21 +9,21 @@ import obsSegmentationsOmeZarrMouseLiverFixture from './json-fixtures/mouse_live
|
|
|
9
9
|
describe('generateConfig', () => {
|
|
10
10
|
it('parses URLs', () => {
|
|
11
11
|
const s1 = 'https://example.com/my_image.ome.tif';
|
|
12
|
-
expect(
|
|
12
|
+
expect(parseUrlsFromString(s1)).toEqual([
|
|
13
13
|
{
|
|
14
14
|
url: 'https://example.com/my_image.ome.tif',
|
|
15
15
|
fileType: 'image.ome-tiff',
|
|
16
16
|
},
|
|
17
17
|
]);
|
|
18
|
-
const s2 = 'https://example.com/my_image.ome.tif
|
|
19
|
-
expect(
|
|
18
|
+
const s2 = 'https://example.com/my_image.ome.tif$obsSegmentations.ome-tiff';
|
|
19
|
+
expect(parseUrlsFromString(s2)).toEqual([
|
|
20
20
|
{
|
|
21
21
|
url: 'https://example.com/my_image.ome.tif',
|
|
22
22
|
fileType: 'obsSegmentations.ome-tiff',
|
|
23
23
|
},
|
|
24
24
|
]);
|
|
25
|
-
const s3 = 'https://example.com/my_image.ome.tif
|
|
26
|
-
expect(
|
|
25
|
+
const s3 = 'https://example.com/my_image.ome.tif$obsSegmentations.ome-tiff;http://another.com/obj.zarr$anndata.zarr';
|
|
26
|
+
expect(parseUrlsFromString(s3)).toEqual([
|
|
27
27
|
{
|
|
28
28
|
url: 'https://example.com/my_image.ome.tif',
|
|
29
29
|
fileType: 'obsSegmentations.ome-tiff',
|
package/dist-tsc/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel, getCoordinationSpaceAndScopes } from "./VitessceConfig.js";
|
|
2
2
|
export { generateConfig, getHintOptions } from "./VitessceAutoConfig.js";
|
|
3
3
|
export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from "./constants.js";
|
|
4
|
+
export { generateConfig as generateConfigAlt, parseUrls, parseUrlsFromString } from "./generate-config.js";
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist-tsc/index.js
CHANGED
|
@@ -2,3 +2,4 @@ export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel, getCoordinat
|
|
|
2
2
|
export { generateConfig, getHintOptions } from './VitessceAutoConfig.js';
|
|
3
3
|
export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from './constants.js';
|
|
4
4
|
export { getInitialCoordinationScopePrefix, getInitialCoordinationScopeName, } from '@vitessce/utils';
|
|
5
|
+
export { generateConfig as generateConfigAlt, parseUrls, parseUrlsFromString } from './generate-config.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitessce/config",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.6",
|
|
4
4
|
"author": "HIDIVE Lab at HMS",
|
|
5
5
|
"homepage": "http://vitessce.io",
|
|
6
6
|
"repository": {
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"zarrita": "0.5.4",
|
|
20
|
-
"@
|
|
21
|
-
"@vitessce/
|
|
22
|
-
"@vitessce/
|
|
23
|
-
"@vitessce/
|
|
20
|
+
"@zarrita/storage": "0.1.3",
|
|
21
|
+
"@vitessce/constants-internal": "3.8.6",
|
|
22
|
+
"@vitessce/utils": "3.8.6",
|
|
23
|
+
"@vitessce/globals": "3.8.6",
|
|
24
|
+
"@vitessce/zarr-utils": "3.8.6"
|
|
24
25
|
},
|
|
25
26
|
"scripts": {
|
|
26
27
|
"bundle": "pnpm exec vite build -c ../../scripts/vite.config.mjs",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
+
import { hconcat, vconcat } from './VitessceConfig.js';
|
|
2
3
|
import { AbstractAutoConfig } from './generate-config-helpers.js';
|
|
3
4
|
|
|
4
5
|
// TODO: split into separate classes for OME-TIFF and OME-Zarr?
|
|
@@ -15,7 +16,12 @@ export class OmeAutoConfig extends AbstractAutoConfig {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
// eslint-disable-next-line class-methods-use-this
|
|
18
|
-
addViews(vc, layoutOption) {
|
|
19
|
-
//
|
|
19
|
+
addViews(vc, dataset, layoutOption) {
|
|
20
|
+
// Add spatialBeta/layerControllerBeta views.
|
|
21
|
+
const spatialView = vc.addView(dataset, 'spatialBeta');
|
|
22
|
+
const lcView = vc.addView(dataset, 'layerControllerBeta');
|
|
23
|
+
|
|
24
|
+
// Layout.
|
|
25
|
+
vc.layout(hconcat(spatialView, lcView));
|
|
20
26
|
}
|
|
21
27
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
+
import { hconcat, vconcat } from './VitessceConfig.js';
|
|
2
3
|
import { AbstractAutoConfig } from './generate-config-helpers.js';
|
|
3
4
|
|
|
4
5
|
export class SpatialDataAutoConfig extends AbstractAutoConfig {
|
|
@@ -83,6 +84,9 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
|
|
|
83
84
|
// region: null,
|
|
84
85
|
tablePath: relPath,
|
|
85
86
|
obsSets: columnOrder.map(c => ({
|
|
87
|
+
// TODO: determine whether this column is string/categorical.
|
|
88
|
+
// TODO: determine whether this column contains too many
|
|
89
|
+
// categories to make sense to consider a cell set.
|
|
86
90
|
path: `${hasObs.path.substring(1)}/${c}`,
|
|
87
91
|
name: c,
|
|
88
92
|
})),
|
|
@@ -105,7 +109,28 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
|
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
// eslint-disable-next-line class-methods-use-this
|
|
108
|
-
addViews(vc, layoutOption) {
|
|
109
|
-
|
|
112
|
+
addViews(vc, dataset, layoutOption) {
|
|
113
|
+
const options = this.getOptions();
|
|
114
|
+
|
|
115
|
+
// Add spatialBeta/layerControllerBeta views.
|
|
116
|
+
const spatialView = vc.addView(dataset, 'spatialBeta');
|
|
117
|
+
const lcView = vc.addView(dataset, 'layerControllerBeta');
|
|
118
|
+
|
|
119
|
+
const controlViews = [lcView];
|
|
120
|
+
// If obsSets are present, add obsSets view.
|
|
121
|
+
if (options.obsSets) {
|
|
122
|
+
const obsSets = vc.addView(dataset, 'obsSets');
|
|
123
|
+
controlViews.push(obsSets);
|
|
124
|
+
}
|
|
125
|
+
// If obsFeatureMatrix is present, add featureList view.
|
|
126
|
+
if (options.obsFeatureMatrix) {
|
|
127
|
+
const featureList = vc.addView(dataset, 'featureList');
|
|
128
|
+
controlViews.push(featureList);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// TODO: set up coordination stuff here?
|
|
132
|
+
|
|
133
|
+
// Layout.
|
|
134
|
+
vc.layout(hconcat(spatialView, vconcat(...controlViews)));
|
|
110
135
|
}
|
|
111
136
|
}
|
package/src/generate-config.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// TODO: ts-check
|
|
2
|
+
|
|
2
3
|
import { FileType } from '@vitessce/constants-internal';
|
|
3
|
-
import { withConsolidated, FetchStore,
|
|
4
|
+
import { withConsolidated, FetchStore, open as zarrOpen, root as zarrRoot } from 'zarrita';
|
|
5
|
+
// eslint-disable-next-line import/no-unresolved
|
|
6
|
+
import ZipFileStore from '@zarrita/storage/zip';
|
|
4
7
|
import { transformEntriesForZipFileStore } from '@vitessce/zarr-utils';
|
|
5
8
|
import { VitessceConfig } from './VitessceConfig.js';
|
|
6
9
|
// Classes for different types of objects
|
|
@@ -8,6 +11,9 @@ import { AnnDataAutoConfig } from './generate-config-anndata.js';
|
|
|
8
11
|
import { SpatialDataAutoConfig } from './generate-config-spatialdata.js';
|
|
9
12
|
import { OmeAutoConfig } from './generate-config-ome.js';
|
|
10
13
|
|
|
14
|
+
// TODO: make this a function parameter?
|
|
15
|
+
const FILE_TYPE_DELIM = '$';
|
|
16
|
+
|
|
11
17
|
const fileTypeToExtensions = {
|
|
12
18
|
[FileType.IMAGE_OME_TIFF]: ['.ome.tif', '.ome.tiff', '.ome.tf2', '.ome.tf8'],
|
|
13
19
|
[FileType.IMAGE_OME_ZARR]: ['.ome.zarr'],
|
|
@@ -51,6 +57,9 @@ const ZARR_FILETYPES = [
|
|
|
51
57
|
];
|
|
52
58
|
|
|
53
59
|
function urlToFileType(url) {
|
|
60
|
+
// TODO: for plain .zarr, we could open the root .attrs and try to guess a fileType
|
|
61
|
+
// (we can probably infer at least whether OME-Zarr vs. AnnData vs. SpatialData).
|
|
62
|
+
|
|
54
63
|
const match = Object.entries(fileTypeToExtensions).find(
|
|
55
64
|
// eslint-disable-next-line no-unused-vars
|
|
56
65
|
([fileType, extensions]) => extensions.some(ext => url.endsWith(ext)),
|
|
@@ -99,15 +108,12 @@ function ensureStores(parsedUrls) {
|
|
|
99
108
|
|
|
100
109
|
/**
|
|
101
110
|
*
|
|
102
|
-
* @param {string}
|
|
103
|
-
*
|
|
104
|
-
* http://example.com/my_tiff.ome.tif`
|
|
105
|
-
* @returns {{ url: string, fileType: string}[]} The URLs with file types.
|
|
111
|
+
* @param {string[]} arr
|
|
112
|
+
* @returns {{ url: string, fileType: string }[]} The URLs with file types.
|
|
106
113
|
*/
|
|
107
|
-
export function parseUrls(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const parts = urlWithHash.split('#');
|
|
114
|
+
export function parseUrls(arr) {
|
|
115
|
+
return arr.map((urlWithHash) => {
|
|
116
|
+
const parts = urlWithHash.split(FILE_TYPE_DELIM);
|
|
111
117
|
if (parts.length === 1) {
|
|
112
118
|
const [url] = parts;
|
|
113
119
|
return {
|
|
@@ -121,10 +127,22 @@ export function parseUrls(s) {
|
|
|
121
127
|
fileType,
|
|
122
128
|
};
|
|
123
129
|
}
|
|
124
|
-
throw new Error(
|
|
130
|
+
throw new Error(`Only expected zero or one ${FILE_TYPE_DELIM} character per URL, but received more.`);
|
|
125
131
|
});
|
|
126
132
|
}
|
|
127
133
|
|
|
134
|
+
/**
|
|
135
|
+
*
|
|
136
|
+
* @param {string} s A single string, like this
|
|
137
|
+
* `http://example.com/my_zarr.zarr#anndata.zarr;
|
|
138
|
+
* http://example.com/my_tiff.ome.tif`
|
|
139
|
+
* @returns {{ url: string, fileType: string}[]} The URLs with file types.
|
|
140
|
+
*/
|
|
141
|
+
export function parseUrlsFromString(s) {
|
|
142
|
+
const urlsWithHashes = s.split(';');
|
|
143
|
+
return parseUrls(urlsWithHashes);
|
|
144
|
+
}
|
|
145
|
+
|
|
128
146
|
|
|
129
147
|
export async function parsedUrlToZmetadata(parsedUrl) {
|
|
130
148
|
const { store: initialStore } = parsedUrl;
|
|
@@ -247,7 +265,7 @@ export async function generateConfig(parsedUrls, layoutOption = null) {
|
|
|
247
265
|
|
|
248
266
|
autoConfig.addFiles(vc, dataset);
|
|
249
267
|
// TODO: add all files, then add all views (in two separate loops)?
|
|
250
|
-
autoConfig.addViews(vc, layoutOption);
|
|
268
|
+
autoConfig.addViews(vc, dataset, layoutOption);
|
|
251
269
|
});
|
|
252
270
|
|
|
253
271
|
const stores = Object.fromEntries(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { createStoreFromMapContents } from '@vitessce/zarr-utils';
|
|
3
3
|
import { withConsolidated } from 'zarrita';
|
|
4
|
-
import {
|
|
4
|
+
import { parseUrlsFromString, parsedUrlToZmetadata, generateConfig } from './generate-config.js';
|
|
5
5
|
import spatialdataMouseLiverFixture from './json-fixtures/mouse_liver.spatialdata.json';
|
|
6
6
|
import anndataMouseLiverFixture from './json-fixtures/mouse_liver.anndata.json';
|
|
7
7
|
import imageOmeZarrMouseLiverFixture from './json-fixtures/mouse_liver.ome.json';
|
|
@@ -10,23 +10,23 @@ import obsSegmentationsOmeZarrMouseLiverFixture from './json-fixtures/mouse_live
|
|
|
10
10
|
describe('generateConfig', () => {
|
|
11
11
|
it('parses URLs', () => {
|
|
12
12
|
const s1 = 'https://example.com/my_image.ome.tif';
|
|
13
|
-
expect(
|
|
13
|
+
expect(parseUrlsFromString(s1)).toEqual([
|
|
14
14
|
{
|
|
15
15
|
url: 'https://example.com/my_image.ome.tif',
|
|
16
16
|
fileType: 'image.ome-tiff',
|
|
17
17
|
},
|
|
18
18
|
]);
|
|
19
19
|
|
|
20
|
-
const s2 = 'https://example.com/my_image.ome.tif
|
|
21
|
-
expect(
|
|
20
|
+
const s2 = 'https://example.com/my_image.ome.tif$obsSegmentations.ome-tiff';
|
|
21
|
+
expect(parseUrlsFromString(s2)).toEqual([
|
|
22
22
|
{
|
|
23
23
|
url: 'https://example.com/my_image.ome.tif',
|
|
24
24
|
fileType: 'obsSegmentations.ome-tiff',
|
|
25
25
|
},
|
|
26
26
|
]);
|
|
27
27
|
|
|
28
|
-
const s3 = 'https://example.com/my_image.ome.tif
|
|
29
|
-
expect(
|
|
28
|
+
const s3 = 'https://example.com/my_image.ome.tif$obsSegmentations.ome-tiff;http://another.com/obj.zarr$anndata.zarr';
|
|
29
|
+
expect(parseUrlsFromString(s3)).toEqual([
|
|
30
30
|
{
|
|
31
31
|
url: 'https://example.com/my_image.ome.tif',
|
|
32
32
|
fileType: 'obsSegmentations.ome-tiff',
|