@vitessce/config 3.8.9 → 3.8.10

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 CHANGED
@@ -41,11 +41,11 @@ function requirePluralize() {
41
41
  if (hasRequiredPluralize) return pluralize$1.exports;
42
42
  hasRequiredPluralize = 1;
43
43
  (function(module2, exports) {
44
- (function(root2, pluralize2) {
44
+ (function(root, pluralize2) {
45
45
  if (typeof commonjsRequire === "function" && true && true) {
46
46
  module2.exports = pluralize2();
47
47
  } else {
48
- root2.pluralize = pluralize2();
48
+ root.pluralize = pluralize2();
49
49
  }
50
50
  })(pluralize, function() {
51
51
  var pluralRules = [];
@@ -443,11 +443,11 @@ function requireLoglevel() {
443
443
  if (hasRequiredLoglevel) return loglevel$1.exports;
444
444
  hasRequiredLoglevel = 1;
445
445
  (function(module2) {
446
- (function(root2, definition) {
446
+ (function(root, definition) {
447
447
  if (module2.exports) {
448
448
  module2.exports = definition();
449
449
  } else {
450
- root2.log = definition();
450
+ root.log = definition();
451
451
  }
452
452
  })(loglevel, function() {
453
453
  var noop = function() {
@@ -2122,8 +2122,8 @@ function assert$1(expression, msg = "") {
2122
2122
  if (!expression)
2123
2123
  throw new Error(msg);
2124
2124
  }
2125
- function resolve(root2, path) {
2126
- const base = typeof root2 === "string" ? new URL(root2) : root2;
2125
+ function resolve(root, path) {
2126
+ const base = typeof root === "string" ? new URL(root) : root;
2127
2127
  if (!base.pathname.endsWith("/")) {
2128
2128
  base.pathname += "/";
2129
2129
  }
@@ -3070,9 +3070,6 @@ class Location {
3070
3070
  return new Location(this.store, decodeURIComponent(new URL(path, root2).pathname));
3071
3071
  }
3072
3072
  }
3073
- function root(store) {
3074
- return new Location(store ?? /* @__PURE__ */ new Map());
3075
- }
3076
3073
  class Group extends Location {
3077
3074
  constructor(store, path, metadata) {
3078
3075
  super(store, path);
@@ -4272,13 +4269,7 @@ class SpatialDataAutoConfig extends AbstractAutoConfig2 {
4272
4269
  };
4273
4270
  }
4274
4271
  if (relPath.match(/^(shapes)\/([^/]*)$/)) {
4275
- options.obsSpots = {
4276
- path: relPath,
4277
- coordinateSystem: firstCoordinateSystem
4278
- };
4279
- }
4280
- if (relPath.match(/^(points)\/([^/]*)$/)) {
4281
- options.obsPoints = {
4272
+ options.obsSegmentations = {
4282
4273
  path: relPath,
4283
4274
  coordinateSystem: firstCoordinateSystem
4284
4275
  };
@@ -4292,21 +4283,6 @@ class SpatialDataAutoConfig extends AbstractAutoConfig2 {
4292
4283
  // region: null,
4293
4284
  };
4294
4285
  }
4295
- const hasObs = tableEls.find((el) => el.path === `${path}/obs`);
4296
- if (hasObs) {
4297
- const columnOrder = hasObs.attrs?.["column-order"];
4298
- options.obsSets = {
4299
- // region: null,
4300
- tablePath: relPath,
4301
- obsSets: columnOrder.map((c) => ({
4302
- // TODO: determine whether this column is string/categorical.
4303
- // TODO: determine whether this column contains too many
4304
- // categories to make sense to consider a cell set.
4305
- path: `${hasObs.path.substring(1)}/${c}`,
4306
- name: c
4307
- }))
4308
- };
4309
- }
4310
4286
  }
4311
4287
  });
4312
4288
  return options;
@@ -4461,8 +4437,19 @@ async function parsedUrlToZmetadata(parsedUrl) {
4461
4437
  store = await withConsolidated(initialStore, { metadataKey: "zmetadata" });
4462
4438
  }
4463
4439
  const contents = store.contents();
4440
+ const consolidatedRoot = await open(store, { kind: "group" });
4464
4441
  promises = contents.map(async (value) => {
4465
- const item = await open(root(store).resolve(value.path));
4442
+ let item;
4443
+ try {
4444
+ item = await open(
4445
+ consolidatedRoot.resolve(value.path),
4446
+ { kind: value.kind }
4447
+ );
4448
+ } catch {
4449
+ item = {
4450
+ attrs: {}
4451
+ };
4452
+ }
4466
4453
  return {
4467
4454
  ...value,
4468
4455
  attrs: item.attrs
@@ -4493,9 +4480,10 @@ async function parsedUrlToZmetadata(parsedUrl) {
4493
4480
  // Note: For spatialData, we assume the store is always consolidated.
4494
4481
  // TODO: throw error if spatialdata + not consolidated?
4495
4482
  ];
4483
+ const storeRoot = await open(store, { kind: "group" });
4496
4484
  promises = keysToTry.map(async (k) => {
4497
4485
  try {
4498
- const item = await open(root(store).resolve(k));
4486
+ const item = await open(storeRoot.resolve(k));
4499
4487
  return {
4500
4488
  path: k,
4501
4489
  kind: item.kind,
@@ -1 +1 @@
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
+ {"version":3,"file":"generate-config-spatialdata.d.ts","sourceRoot":"","sources":["../src/generate-config-spatialdata.js"],"names":[],"mappings":"AAIA;IACE,iBAiGC;CAqCF;mCAzIkC,8BAA8B"}
@@ -36,20 +36,23 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
36
36
  if (relPath.match(/^(shapes)\/([^/]*)$/)) {
37
37
  // TODO: check if shapes are circles or polygons
38
38
  // to determine which Vitessce data type to use.
39
- options.obsSpots = {
39
+ options.obsSegmentations = {
40
40
  path: relPath,
41
41
  coordinateSystem: firstCoordinateSystem,
42
42
  };
43
43
  // TODO: check which table annotates these shapes.
44
44
  }
45
45
  // Handle point elements.
46
+ /* TODO: uncomment once points are more scalable
46
47
  if (relPath.match(/^(points)\/([^/]*)$/)) {
47
- options.obsPoints = {
48
- path: relPath,
49
- coordinateSystem: firstCoordinateSystem,
50
- };
51
- // TODO: check which table annotates these shapes.
48
+ options.obsPoints = {
49
+ path: relPath,
50
+ coordinateSystem: firstCoordinateSystem,
51
+ };
52
+
53
+ // TODO: check which table annotates these shapes.
52
54
  }
55
+ */
53
56
  // Handle table elements.
54
57
  if (relPath.match(/^(tables|table)\/([^/]*)$/)) {
55
58
  // Identify all sub-paths within this table element.
@@ -63,22 +66,24 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
63
66
  };
64
67
  }
65
68
  // Check if the table contains an obs dataframe.
69
+ /* TODO: uncomment once logic for checking num. unique categories
66
70
  const hasObs = tableEls.find(el => el.path === `${path}/obs`);
67
71
  if (hasObs) {
68
- const columnOrder = hasObs.attrs?.['column-order'];
69
- // Use the columns of this dataframe to configure the obsSets.
70
- options.obsSets = {
71
- // region: null,
72
- tablePath: relPath,
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.
77
- path: `${hasObs.path.substring(1)}/${c}`,
78
- name: c,
79
- })),
80
- };
72
+ const columnOrder = hasObs.attrs?.['column-order'];
73
+ // Use the columns of this dataframe to configure the obsSets.
74
+ options.obsSets = {
75
+ // region: null,
76
+ tablePath: relPath,
77
+ obsSets: columnOrder.map(c => ({
78
+ // TODO: determine whether this column is string/categorical.
79
+ // TODO: determine whether this column contains too many
80
+ // categories to make sense to consider a cell set.
81
+ path: `${hasObs.path.substring(1)}/${c}`,
82
+ name: c,
83
+ })),
84
+ };
81
85
  }
86
+ */
82
87
  }
83
88
  });
84
89
  return options;
@@ -19,10 +19,14 @@ export function parseUrlsFromString(s: string): {
19
19
  fileType: string;
20
20
  }[];
21
21
  export function parsedUrlToZmetadata(parsedUrl: any): Promise<{
22
+ attrs: {};
23
+ path: import("zarrita").AbsolutePath;
24
+ kind: "array" | "group";
25
+ }[] | ({
22
26
  path: string;
23
27
  kind: string;
24
28
  attrs: import("zarrita").Attributes;
25
- }[] | null>;
29
+ } | null)[] | null>;
26
30
  /**
27
31
  *
28
32
  * @param {{ url, fileType, store }[]} parsedUrls
@@ -1 +1 @@
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
+ {"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;;;;;;;;oBA4FC;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;+BA5S8B,qBAAqB"}
@@ -1,6 +1,6 @@
1
1
  // TODO: ts-check
2
2
  import { FileType } from '@vitessce/constants-internal';
3
- import { withConsolidated, FetchStore, open as zarrOpen, root as zarrRoot } from 'zarrita';
3
+ import { withConsolidated, FetchStore, open as zarrOpen } from 'zarrita';
4
4
  // eslint-disable-next-line import/no-unresolved
5
5
  import ZipFileStore from '@zarrita/storage/zip';
6
6
  import { transformEntriesForZipFileStore } from '@vitessce/zarr-utils';
@@ -149,8 +149,27 @@ export async function parsedUrlToZmetadata(parsedUrl) {
149
149
  }
150
150
  // Is consolidated.
151
151
  const contents = store.contents();
152
+ // Open all entries to get their attributes.
153
+ const consolidatedRoot = await zarrOpen(store, { kind: 'group' });
152
154
  promises = contents.map(async (value) => {
153
- const item = await zarrOpen(zarrRoot(store).resolve(value.path));
155
+ let item;
156
+ try {
157
+ // Note: if `kind` is not provided,
158
+ // then zarrita must make extra network requests.
159
+ // TODO: open issue in Zarrita to avoid network requests for
160
+ // arrays that lack .zattrs (e.g., OME-NGFF multiscale arrays)
161
+ // (as determined from omission in consolidated metadata).
162
+ item = await zarrOpen(consolidatedRoot.resolve(value.path), { kind: value.kind });
163
+ }
164
+ catch {
165
+ // Opening can fail if the dtype is unsupported,
166
+ // since zarrita assumes string dtypes
167
+ // but Scanpy rank_genes_groups can result in recarrays
168
+ // that have an array of dtypes.
169
+ item = {
170
+ attrs: {},
171
+ };
172
+ }
154
173
  return {
155
174
  ...value,
156
175
  attrs: item.attrs,
@@ -183,9 +202,10 @@ export async function parsedUrlToZmetadata(parsedUrl) {
183
202
  // Note: For spatialData, we assume the store is always consolidated.
184
203
  // TODO: throw error if spatialdata + not consolidated?
185
204
  ];
205
+ const storeRoot = await zarrOpen(store, { kind: 'group' });
186
206
  promises = keysToTry.map(async (k) => {
187
207
  try {
188
- const item = await zarrOpen(zarrRoot(store).resolve(k));
208
+ const item = await zarrOpen(storeRoot.resolve(k));
189
209
  return {
190
210
  path: k,
191
211
  kind: item.kind,
@@ -150,6 +150,13 @@ describe('generateConfig', () => {
150
150
  },
151
151
  ];
152
152
  const { config, stores } = await generateConfig(parsedUrls);
153
+ const configJson = config.toJSON();
154
+ // TODO: include all options in the test once implemented.
155
+ delete configJson.datasets[0].files[0].options.obsSegmentations;
156
+ delete configJson.datasets[0].files[0].options.obsSpots;
157
+ delete configJson.datasets[0].files[0].options.obsSets;
158
+ delete configJson.datasets[0].files[0].options.obsPoints;
159
+ // End TODO
153
160
  expect(config.toJSON().datasets[0].files).toEqual([
154
161
  {
155
162
  url: './mouse_liver.spatialdata.json',
@@ -159,38 +166,9 @@ describe('generateConfig', () => {
159
166
  path: 'images/raw_image',
160
167
  coordinateSystem: 'global',
161
168
  },
162
- obsSegmentations: {
163
- path: 'labels/segmentation_mask',
164
- coordinateSystem: 'global',
165
- },
166
- obsSpots: {
167
- // TODO: the test should be updated once fixed in the implementaiton,
168
- // since these are not circle shapes.
169
- path: 'shapes/nucleus_boundaries',
170
- },
171
169
  obsFeatureMatrix: {
172
170
  path: 'tables/table/X',
173
171
  },
174
- obsPoints: {
175
- path: 'points/transcripts',
176
- },
177
- obsSets: {
178
- tablePath: 'tables/table',
179
- obsSets: [
180
- {
181
- path: 'tables/table/obs/cell_ID',
182
- name: 'cell_ID',
183
- },
184
- {
185
- path: 'tables/table/obs/fov_labels',
186
- name: 'fov_labels',
187
- },
188
- {
189
- path: 'tables/table/obs/annotation',
190
- name: 'annotation',
191
- },
192
- ],
193
- },
194
172
  },
195
173
  },
196
174
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/config",
3
- "version": "3.8.9",
3
+ "version": "3.8.10",
4
4
  "author": "HIDIVE Lab at HMS",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -18,10 +18,10 @@
18
18
  "dependencies": {
19
19
  "zarrita": "0.5.4",
20
20
  "@zarrita/storage": "0.1.3",
21
- "@vitessce/constants-internal": "3.8.9",
22
- "@vitessce/utils": "3.8.9",
23
- "@vitessce/globals": "3.8.9",
24
- "@vitessce/zarr-utils": "3.8.9"
21
+ "@vitessce/constants-internal": "3.8.10",
22
+ "@vitessce/utils": "3.8.10",
23
+ "@vitessce/globals": "3.8.10",
24
+ "@vitessce/zarr-utils": "3.8.10"
25
25
  },
26
26
  "scripts": {
27
27
  "bundle": "pnpm exec vite build -c ../../scripts/vite.config.mjs",
@@ -43,7 +43,7 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
43
43
  if (relPath.match(/^(shapes)\/([^/]*)$/)) {
44
44
  // TODO: check if shapes are circles or polygons
45
45
  // to determine which Vitessce data type to use.
46
- options.obsSpots = {
46
+ options.obsSegmentations = {
47
47
  path: relPath,
48
48
  coordinateSystem: firstCoordinateSystem,
49
49
  };
@@ -52,6 +52,7 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
52
52
  }
53
53
 
54
54
  // Handle point elements.
55
+ /* TODO: uncomment once points are more scalable
55
56
  if (relPath.match(/^(points)\/([^/]*)$/)) {
56
57
  options.obsPoints = {
57
58
  path: relPath,
@@ -60,6 +61,7 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
60
61
 
61
62
  // TODO: check which table annotates these shapes.
62
63
  }
64
+ */
63
65
 
64
66
  // Handle table elements.
65
67
  if (relPath.match(/^(tables|table)\/([^/]*)$/)) {
@@ -76,6 +78,7 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
76
78
  }
77
79
 
78
80
  // Check if the table contains an obs dataframe.
81
+ /* TODO: uncomment once logic for checking num. unique categories
79
82
  const hasObs = tableEls.find(el => el.path === `${path}/obs`);
80
83
  if (hasObs) {
81
84
  const columnOrder = hasObs.attrs?.['column-order'];
@@ -92,6 +95,7 @@ export class SpatialDataAutoConfig extends AbstractAutoConfig {
92
95
  })),
93
96
  };
94
97
  }
98
+ */
95
99
  }
96
100
  });
97
101
 
@@ -1,7 +1,7 @@
1
1
  // TODO: ts-check
2
2
 
3
3
  import { FileType } from '@vitessce/constants-internal';
4
- import { withConsolidated, FetchStore, open as zarrOpen, root as zarrRoot } from 'zarrita';
4
+ import { withConsolidated, FetchStore, open as zarrOpen } from 'zarrita';
5
5
  // eslint-disable-next-line import/no-unresolved
6
6
  import ZipFileStore from '@zarrita/storage/zip';
7
7
  import { transformEntriesForZipFileStore } from '@vitessce/zarr-utils';
@@ -164,8 +164,29 @@ export async function parsedUrlToZmetadata(parsedUrl) {
164
164
  }
165
165
  // Is consolidated.
166
166
  const contents = store.contents();
167
+ // Open all entries to get their attributes.
168
+ const consolidatedRoot = await zarrOpen(store, { kind: 'group' });
167
169
  promises = contents.map(async (value) => {
168
- const item = await zarrOpen(zarrRoot(store).resolve(value.path));
170
+ let item;
171
+ try {
172
+ // Note: if `kind` is not provided,
173
+ // then zarrita must make extra network requests.
174
+ // TODO: open issue in Zarrita to avoid network requests for
175
+ // arrays that lack .zattrs (e.g., OME-NGFF multiscale arrays)
176
+ // (as determined from omission in consolidated metadata).
177
+ item = await zarrOpen(
178
+ consolidatedRoot.resolve(value.path),
179
+ { kind: value.kind },
180
+ );
181
+ } catch {
182
+ // Opening can fail if the dtype is unsupported,
183
+ // since zarrita assumes string dtypes
184
+ // but Scanpy rank_genes_groups can result in recarrays
185
+ // that have an array of dtypes.
186
+ item = {
187
+ attrs: {},
188
+ };
189
+ }
169
190
  return {
170
191
  ...value,
171
192
  attrs: item.attrs,
@@ -198,9 +219,10 @@ export async function parsedUrlToZmetadata(parsedUrl) {
198
219
  // Note: For spatialData, we assume the store is always consolidated.
199
220
  // TODO: throw error if spatialdata + not consolidated?
200
221
  ];
222
+ const storeRoot = await zarrOpen(store, { kind: 'group' });
201
223
  promises = keysToTry.map(async (k) => {
202
224
  try {
203
- const item = await zarrOpen(zarrRoot(store).resolve(k));
225
+ const item = await zarrOpen(storeRoot.resolve(k));
204
226
  return {
205
227
  path: k,
206
228
  kind: item.kind,
@@ -163,6 +163,13 @@ describe('generateConfig', () => {
163
163
  },
164
164
  ];
165
165
  const { config, stores } = await generateConfig(parsedUrls);
166
+ const configJson = config.toJSON();
167
+ // TODO: include all options in the test once implemented.
168
+ delete configJson.datasets[0].files[0].options.obsSegmentations;
169
+ delete configJson.datasets[0].files[0].options.obsSpots;
170
+ delete configJson.datasets[0].files[0].options.obsSets;
171
+ delete configJson.datasets[0].files[0].options.obsPoints;
172
+ // End TODO
166
173
  expect(config.toJSON().datasets[0].files).toEqual([
167
174
  {
168
175
  url: './mouse_liver.spatialdata.json',
@@ -172,38 +179,9 @@ describe('generateConfig', () => {
172
179
  path: 'images/raw_image',
173
180
  coordinateSystem: 'global',
174
181
  },
175
- obsSegmentations: {
176
- path: 'labels/segmentation_mask',
177
- coordinateSystem: 'global',
178
- },
179
- obsSpots: {
180
- // TODO: the test should be updated once fixed in the implementaiton,
181
- // since these are not circle shapes.
182
- path: 'shapes/nucleus_boundaries',
183
- },
184
182
  obsFeatureMatrix: {
185
183
  path: 'tables/table/X',
186
184
  },
187
- obsPoints: {
188
- path: 'points/transcripts',
189
- },
190
- obsSets: {
191
- tablePath: 'tables/table',
192
- obsSets: [
193
- {
194
- path: 'tables/table/obs/cell_ID',
195
- name: 'cell_ID',
196
- },
197
- {
198
- path: 'tables/table/obs/fov_labels',
199
- name: 'fov_labels',
200
- },
201
- {
202
- path: 'tables/table/obs/annotation',
203
- name: 'annotation',
204
- },
205
- ],
206
- },
207
185
  },
208
186
  },
209
187
  ]);