@vitessce/vit-s 2.0.2 → 2.0.3

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.
Files changed (172) hide show
  1. package/dist/index.mjs +84801 -0
  2. package/{dist → dist-tsc}/index.js +2 -2
  3. package/package.json +7 -7
  4. package/src/CallbackPublisher.js +81 -0
  5. package/src/LoadingIndicator.js +34 -0
  6. package/src/TitleInfo.js +240 -0
  7. package/src/VitS.js +180 -0
  8. package/src/VitessceGrid.js +110 -0
  9. package/src/VitessceGrid.test.jsx +48 -0
  10. package/src/Warning.js +62 -0
  11. package/{dist → src}/classNames.js +0 -0
  12. package/src/component-registry.js +21 -0
  13. package/src/data/AbstractLoader.js +46 -0
  14. package/{dist → src}/data/AbstractTwoStepLoader.js +5 -4
  15. package/src/data/LoaderResult.js +8 -0
  16. package/{dist → src}/data/index.js +0 -0
  17. package/src/data/loader-registry.js +19 -0
  18. package/src/data-hook-utils.js +197 -0
  19. package/src/data-hooks.js +354 -0
  20. package/src/errors/AbstractLoaderError.js +14 -0
  21. package/src/errors/DataSourceFetchError.js +15 -0
  22. package/src/errors/DatasetNotFoundError.js +23 -0
  23. package/src/errors/LoaderNotFoundError.js +24 -0
  24. package/src/errors/LoaderValidationError.js +23 -0
  25. package/src/errors/OptionsValidationError.js +25 -0
  26. package/{dist → src}/errors/index.js +0 -0
  27. package/src/file-options-schemas-legacy.js +139 -0
  28. package/src/file-options-schemas-legacy.test.js +138 -0
  29. package/src/file-options-schemas.js +327 -0
  30. package/src/file-options-schemas.test.js +26 -0
  31. package/src/hooks.js +252 -0
  32. package/src/index.js +101 -0
  33. package/src/joint-file-types-legacy.js +298 -0
  34. package/src/joint-file-types-legacy.test.js +412 -0
  35. package/src/joint-file-types.js +171 -0
  36. package/src/joint-file-types.test.js +144 -0
  37. package/{dist/schemas.js → src/json-schemas.js} +6 -1
  38. package/{dist → src}/plugins.js +102 -70
  39. package/src/plugins.test.fixtures.js +78 -0
  40. package/src/plugins.test.js +42 -0
  41. package/src/schemas/config-0.1.0.schema.json +85 -0
  42. package/src/schemas/config-1.0.0.schema.json +733 -0
  43. package/src/schemas/config-1.0.1.schema.json +909 -0
  44. package/src/schemas/config-1.0.10.schema.json +969 -0
  45. package/src/schemas/config-1.0.11.schema.json +990 -0
  46. package/src/schemas/config-1.0.12.schema.json +997 -0
  47. package/src/schemas/config-1.0.13.schema.json +1013 -0
  48. package/src/schemas/config-1.0.14.schema.json +1048 -0
  49. package/src/schemas/config-1.0.15.schema.json +1048 -0
  50. package/src/schemas/config-1.0.16.schema.json +1069 -0
  51. package/src/schemas/config-1.0.16.schema.test.js +32 -0
  52. package/src/schemas/config-1.0.2.schema.json +911 -0
  53. package/src/schemas/config-1.0.3.schema.json +911 -0
  54. package/src/schemas/config-1.0.4.schema.json +949 -0
  55. package/src/schemas/config-1.0.5.schema.json +949 -0
  56. package/src/schemas/config-1.0.6.schema.json +950 -0
  57. package/src/schemas/config-1.0.7.schema.json +950 -0
  58. package/src/schemas/config-1.0.8.schema.json +966 -0
  59. package/src/schemas/config-1.0.9.schema.json +965 -0
  60. package/src/schemas/fixtures/cellSets.good.json +16 -0
  61. package/src/schemas/fixtures/config-1.0.1.bad.json +1 -0
  62. package/src/schemas/fixtures/config-1.0.1.bad.message.json +11 -0
  63. package/src/schemas/fixtures/config-1.0.1.good.json +37 -0
  64. package/src/schemas/fixtures/config-1.0.2.bad.json +1 -0
  65. package/src/schemas/fixtures/config-1.0.2.bad.message.json +11 -0
  66. package/src/schemas/fixtures/config-1.0.2.good.json +38 -0
  67. package/src/schemas/fixtures/config-1.0.3.bad.json +1 -0
  68. package/src/schemas/fixtures/config-1.0.3.bad.message.json +11 -0
  69. package/src/schemas/fixtures/config-1.0.3.good.json +38 -0
  70. package/src/schemas/fixtures/obsSets.bad.json +1 -0
  71. package/src/schemas/fixtures/obsSets.bad.message.json +11 -0
  72. package/src/schemas/fixtures/obsSets.good.json +16 -0
  73. package/src/schemas/fixtures/obsSetsTabular.bad.json +1 -0
  74. package/src/schemas/fixtures/obsSetsTabular.bad.message.json +11 -0
  75. package/src/schemas/fixtures/obsSetsTabular.good.json +26 -0
  76. package/src/schemas/fixtures/raster.bad.json +1 -0
  77. package/src/schemas/fixtures/raster.bad.message.json +11 -0
  78. package/src/schemas/fixtures/raster.good.json +39 -0
  79. package/src/schemas/obsSets.schema.js +195 -0
  80. package/src/schemas/obsSetsTabular.schema.js +39 -0
  81. package/src/schemas/raster.schema.js +121 -0
  82. package/src/schemas/schema-schema.sh +34 -0
  83. package/{dist → src}/schemas/schema.test-old.js +0 -1
  84. package/src/shared-mui/components.js +79 -0
  85. package/src/shared-mui/container.js +212 -0
  86. package/src/shared-mui/styles.js +110 -0
  87. package/src/shared-plot-options/CellColorEncodingOption.js +43 -0
  88. package/src/shared-plot-options/OptionSelect.js +19 -0
  89. package/src/shared-plot-options/OptionsContainer.js +26 -0
  90. package/{dist → src}/shared-plot-options/index.js +0 -0
  91. package/src/shared-plot-options/styles.js +49 -0
  92. package/src/state/hooks.js +633 -0
  93. package/src/view-config-upgraders.js +628 -0
  94. package/src/view-config-utils.js +315 -0
  95. package/src/view-config-utils.test.fixtures.js +893 -0
  96. package/src/view-config-utils.test.js +95 -0
  97. package/src/view-config-versions.js +68 -0
  98. package/src/vitessce-grid-layout/VitessceGridLayout.js +158 -0
  99. package/src/vitessce-grid-layout/VitessceGridLayout.test.jsx +56 -0
  100. package/{dist → src}/vitessce-grid-layout/index.js +0 -0
  101. package/src/vitessce-grid-layout/layout-utils.js +76 -0
  102. package/src/vitessce-grid-layout/layout-utils.test.js +167 -0
  103. package/src/vitessce-grid-utils.js +160 -0
  104. package/dist/CallbackPublisher.js +0 -68
  105. package/dist/LoadingIndicator.js +0 -27
  106. package/dist/TitleInfo.js +0 -151
  107. package/dist/VitS.js +0 -112
  108. package/dist/VitessceGrid.js +0 -59
  109. package/dist/VitessceGrid.test.js +0 -36
  110. package/dist/Warning.js +0 -45
  111. package/dist/component-registry.js +0 -16
  112. package/dist/data/AbstractLoader.js +0 -35
  113. package/dist/data/LoaderResult.js +0 -7
  114. package/dist/data/loader-registry.js +0 -15
  115. package/dist/data-hook-utils.js +0 -175
  116. package/dist/data-hooks.js +0 -241
  117. package/dist/errors/AbstractLoaderError.js +0 -13
  118. package/dist/errors/DataSourceFetchError.js +0 -13
  119. package/dist/errors/DatasetNotFoundError.js +0 -17
  120. package/dist/errors/LoaderNotFoundError.js +0 -17
  121. package/dist/errors/LoaderValidationError.js +0 -15
  122. package/dist/errors/OptionsValidationError.js +0 -15
  123. package/dist/file-options-schemas-legacy.js +0 -136
  124. package/dist/file-options-schemas-legacy.test.js +0 -126
  125. package/dist/file-options-schemas.js +0 -322
  126. package/dist/file-options-schemas.test.js +0 -23
  127. package/dist/hooks.js +0 -215
  128. package/dist/joint-file-types-legacy.js +0 -278
  129. package/dist/joint-file-types-legacy.test.js +0 -400
  130. package/dist/joint-file-types.js +0 -148
  131. package/dist/joint-file-types.test.js +0 -139
  132. package/dist/plugins.test.fixtures.js +0 -76
  133. package/dist/plugins.test.js +0 -30
  134. package/dist/schemas/config-0.1.0.schema.json +0 -84
  135. package/dist/schemas/config-1.0.0.schema.json +0 -733
  136. package/dist/schemas/config-1.0.1.schema.json +0 -909
  137. package/dist/schemas/config-1.0.10.schema.json +0 -969
  138. package/dist/schemas/config-1.0.11.schema.json +0 -990
  139. package/dist/schemas/config-1.0.12.schema.json +0 -997
  140. package/dist/schemas/config-1.0.13.schema.json +0 -1013
  141. package/dist/schemas/config-1.0.14.schema.json +0 -1048
  142. package/dist/schemas/config-1.0.15.schema.json +0 -1048
  143. package/dist/schemas/config-1.0.15.schema.test.js +0 -22
  144. package/dist/schemas/config-1.0.2.schema.json +0 -910
  145. package/dist/schemas/config-1.0.3.schema.json +0 -910
  146. package/dist/schemas/config-1.0.4.schema.json +0 -949
  147. package/dist/schemas/config-1.0.5.schema.json +0 -949
  148. package/dist/schemas/config-1.0.6.schema.json +0 -949
  149. package/dist/schemas/config-1.0.7.schema.json +0 -949
  150. package/dist/schemas/config-1.0.8.schema.json +0 -965
  151. package/dist/schemas/config-1.0.9.schema.json +0 -965
  152. package/dist/schemas/obsSets.schema.js +0 -195
  153. package/dist/schemas/obsSetsTabular.schema.js +0 -38
  154. package/dist/schemas/raster.schema.js +0 -120
  155. package/dist/shared-mui/components.js +0 -35
  156. package/dist/shared-mui/container.js +0 -211
  157. package/dist/shared-mui/styles.js +0 -73
  158. package/dist/shared-plot-options/CellColorEncodingOption.js +0 -18
  159. package/dist/shared-plot-options/OptionSelect.js +0 -12
  160. package/dist/shared-plot-options/OptionsContainer.js +0 -12
  161. package/dist/shared-plot-options/styles.js +0 -48
  162. package/dist/state/hooks.js +0 -549
  163. package/dist/view-config-upgraders.js +0 -525
  164. package/dist/view-config-utils.js +0 -286
  165. package/dist/view-config-utils.test.fixtures.js +0 -765
  166. package/dist/view-config-utils.test.js +0 -66
  167. package/dist/view-config-versions.js +0 -47
  168. package/dist/vitessce-grid-layout/VitessceGridLayout.js +0 -95
  169. package/dist/vitessce-grid-layout/VitessceGridLayout.test.js +0 -40
  170. package/dist/vitessce-grid-layout/layout-utils.js +0 -60
  171. package/dist/vitessce-grid-layout/layout-utils.test.js +0 -146
  172. package/dist/vitessce-grid-utils.js +0 -140
@@ -0,0 +1,354 @@
1
+ import { useState, useEffect, useMemo } from 'react';
2
+ import { CoordinationType, DataType, STATUS } from '@vitessce/constants-internal';
3
+ import { fromEntries } from '@vitessce/utils';
4
+ import { useMatchingLoader, useMultiCoordinationValues, useSetWarning } from './state/hooks';
5
+ import {
6
+ LoaderNotFoundError,
7
+ } from './errors/index';
8
+ import {
9
+ warn,
10
+ useDataType,
11
+ useDataTypeMulti,
12
+ } from './data-hook-utils';
13
+
14
+ /**
15
+ * Get the dataset description string.
16
+ * @param {object} loaders The object mapping
17
+ * datasets and data types to loader instances.
18
+ * @param {string} dataset The key for a dataset,
19
+ * used to identify which loader to use.
20
+ * @returns {array} [description] where
21
+ * description is a string.
22
+ */
23
+ export function useDescription(loaders, dataset) {
24
+ const [description, setDescription] = useState();
25
+
26
+ useEffect(() => {
27
+ if (!loaders[dataset]) {
28
+ return;
29
+ }
30
+
31
+ if (loaders[dataset].description) {
32
+ setDescription(loaders[dataset].description);
33
+ } else {
34
+ setDescription(null);
35
+ }
36
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
+ }, [loaders, dataset]);
38
+
39
+ return [description];
40
+ }
41
+
42
+ /**
43
+ * Get data from a cells data type loader,
44
+ * updating "ready" and URL state appropriately.
45
+ * Throw warnings if the data is marked as required.
46
+ * Subscribe to loader updates.
47
+ * @param {object} loaders The object mapping
48
+ * datasets and data types to loader instances.
49
+ * @param {string} dataset The key for a dataset,
50
+ * used to identify which loader to use.
51
+ * @param {function} addUrl A function to call to update
52
+ * the URL list.
53
+ * @param {boolean} isRequired Should a warning be thrown if
54
+ * loading is unsuccessful?
55
+ * @param {object} coordinationSetters Object where
56
+ * keys are coordination type names with the prefix 'set',
57
+ * values are coordination setter functions.
58
+ * @param {object} initialCoordinationValues Object where
59
+ * keys are coordination type names with the prefix 'initialize',
60
+ * values are initialization preferences as boolean values.
61
+ * @returns {array} [cells, cellsCount] where
62
+ * cells is an object and cellsCount is the
63
+ * number of items in the cells object.
64
+ */
65
+ export function useObsEmbeddingData(
66
+ loaders, dataset, addUrl, isRequired,
67
+ coordinationSetters, initialCoordinationValues, matchOn,
68
+ ) {
69
+ return useDataType(
70
+ DataType.OBS_EMBEDDING,
71
+ loaders, dataset, addUrl, isRequired,
72
+ coordinationSetters, initialCoordinationValues, matchOn,
73
+ );
74
+ }
75
+
76
+ export function useObsLocationsData(
77
+ loaders, dataset, addUrl, isRequired,
78
+ coordinationSetters, initialCoordinationValues, matchOn,
79
+ ) {
80
+ return useDataType(
81
+ DataType.OBS_LOCATIONS,
82
+ loaders, dataset, addUrl, isRequired,
83
+ coordinationSetters, initialCoordinationValues, matchOn,
84
+ );
85
+ }
86
+
87
+ export function useObsLabelsData(
88
+ loaders, dataset, addUrl, isRequired,
89
+ coordinationSetters, initialCoordinationValues, matchOn,
90
+ ) {
91
+ return useDataType(
92
+ DataType.OBS_LABELS,
93
+ loaders, dataset, addUrl, isRequired,
94
+ coordinationSetters, initialCoordinationValues, matchOn,
95
+ );
96
+ }
97
+
98
+ export function useObsSegmentationsData(
99
+ loaders, dataset, addUrl, isRequired,
100
+ coordinationSetters, initialCoordinationValues, matchOn,
101
+ ) {
102
+ return useDataType(
103
+ DataType.OBS_SEGMENTATIONS,
104
+ loaders, dataset, addUrl, isRequired,
105
+ coordinationSetters, initialCoordinationValues, matchOn,
106
+ );
107
+ }
108
+
109
+ export function useObsSetsData(
110
+ loaders, dataset, addUrl, isRequired,
111
+ coordinationSetters, initialCoordinationValues, matchOn,
112
+ ) {
113
+ return useDataType(
114
+ DataType.OBS_SETS,
115
+ loaders, dataset, addUrl, isRequired,
116
+ coordinationSetters, initialCoordinationValues, matchOn,
117
+ );
118
+ }
119
+
120
+ export function useObsFeatureMatrixData(
121
+ loaders, dataset, addUrl, isRequired,
122
+ coordinationSetters, initialCoordinationValues, matchOn,
123
+ ) {
124
+ return useDataType(
125
+ DataType.OBS_FEATURE_MATRIX,
126
+ loaders, dataset, addUrl, isRequired,
127
+ coordinationSetters, initialCoordinationValues, matchOn,
128
+ );
129
+ }
130
+
131
+ export function useFeatureLabelsData(
132
+ loaders, dataset, addUrl, isRequired,
133
+ coordinationSetters, initialCoordinationValues, matchOn,
134
+ ) {
135
+ return useDataType(
136
+ DataType.FEATURE_LABELS,
137
+ loaders, dataset, addUrl, isRequired,
138
+ coordinationSetters, initialCoordinationValues, matchOn,
139
+ );
140
+ }
141
+
142
+ export function useImageData(
143
+ loaders, dataset, addUrl, isRequired,
144
+ coordinationSetters, initialCoordinationValues, matchOn,
145
+ ) {
146
+ return useDataType(
147
+ DataType.IMAGE,
148
+ loaders, dataset, addUrl, isRequired,
149
+ coordinationSetters, initialCoordinationValues, matchOn,
150
+ );
151
+ }
152
+
153
+ export function useGenomicProfilesData(
154
+ loaders, dataset, addUrl, isRequired,
155
+ coordinationSetters, initialCoordinationValues, matchOn,
156
+ ) {
157
+ return useDataType(
158
+ DataType.GENOMIC_PROFILES,
159
+ loaders, dataset, addUrl, isRequired,
160
+ coordinationSetters, initialCoordinationValues, matchOn,
161
+ );
162
+ }
163
+
164
+ export function useNeighborhoodsData(
165
+ loaders, dataset, addUrl, isRequired,
166
+ coordinationSetters, initialCoordinationValues, matchOn,
167
+ ) {
168
+ return useDataType(
169
+ DataType.NEIGHBORHOODS,
170
+ loaders, dataset, addUrl, isRequired,
171
+ coordinationSetters, initialCoordinationValues, matchOn,
172
+ );
173
+ }
174
+
175
+ /**
176
+ * Get data from the expression matrix data type loader for a given gene selection.
177
+ * Throw warnings if the data is marked as required.
178
+ * Subscribe to loader updates.
179
+ * @param {object} loaders The object mapping
180
+ * datasets and data types to loader instances.
181
+ * @param {string} dataset The key for a dataset,
182
+ * used to identify which loader to use.
183
+ * @param {boolean} isRequired Should a warning be thrown if
184
+ * loading is unsuccessful?
185
+ * @param {boolean} selection A list of gene names to get expression data for.
186
+ * @returns {array} [geneData] where geneData is an array [Uint8Array, ..., Uint8Array]
187
+ * for however many genes are in the selection.
188
+ */
189
+ export function useFeatureSelection(
190
+ loaders,
191
+ dataset,
192
+ isRequired,
193
+ selection,
194
+ matchOn,
195
+ ) {
196
+ const [geneData, setGeneData] = useState();
197
+ const [status, setStatus] = useState(STATUS.LOADING);
198
+ const [loadedGeneName, setLoadedGeneName] = useState(null);
199
+
200
+ const setWarning = useSetWarning();
201
+ const loader = useMatchingLoader(loaders, dataset, DataType.OBS_FEATURE_MATRIX, matchOn);
202
+
203
+ useEffect(() => {
204
+ if (!selection) {
205
+ setGeneData(null);
206
+ setLoadedGeneName(null);
207
+ setStatus(STATUS.SUCCESS);
208
+ return;
209
+ }
210
+ if (loader) {
211
+ setGeneData(null);
212
+ setLoadedGeneName(null);
213
+ setStatus(STATUS.LOADING);
214
+ const implementsGeneSelection = typeof loader.loadGeneSelection === 'function';
215
+ if (implementsGeneSelection) {
216
+ loader
217
+ .loadGeneSelection({ selection })
218
+ .catch(e => warn(e, setWarning))
219
+ .then((payload) => {
220
+ if (!payload) return;
221
+ const { data } = payload;
222
+ setGeneData(data);
223
+ setStatus(STATUS.SUCCESS);
224
+ setLoadedGeneName(selection);
225
+ });
226
+ } else {
227
+ loader.load().catch(e => warn(e, setWarning)).then((payload) => {
228
+ if (!payload) return;
229
+ const { data } = payload;
230
+ const { obsIndex, featureIndex, obsFeatureMatrix } = data;
231
+ const expressionDataForSelection = selection.map((sel) => {
232
+ const geneIndex = featureIndex.indexOf(sel);
233
+ const numGenes = featureIndex.length;
234
+ const numCells = obsIndex.length;
235
+ const expressionData = new Uint8Array(numCells);
236
+ for (let cellIndex = 0; cellIndex < numCells; cellIndex += 1) {
237
+ expressionData[cellIndex] = obsFeatureMatrix.data[cellIndex * numGenes + geneIndex];
238
+ }
239
+ return expressionData;
240
+ });
241
+ setGeneData(expressionDataForSelection);
242
+ setStatus(STATUS.SUCCESS);
243
+ setLoadedGeneName(selection);
244
+ });
245
+ }
246
+ } else {
247
+ setGeneData(null);
248
+ setLoadedGeneName(null);
249
+ if (isRequired) {
250
+ warn(
251
+ new LoaderNotFoundError(loaders, dataset, DataType.OBS_FEATURE_MATRIX, matchOn),
252
+ setWarning,
253
+ );
254
+ setStatus(STATUS.ERROR);
255
+ } else {
256
+ setStatus(STATUS.SUCCESS);
257
+ }
258
+ }
259
+ // eslint-disable-next-line react-hooks/exhaustive-deps
260
+ }, [loader, selection]);
261
+
262
+ return [geneData, loadedGeneName, status];
263
+ }
264
+
265
+ /**
266
+ * Get the attributes for the expression matrix data type loader,
267
+ * i.e names of cells and genes.
268
+ * Throw warnings if the data is marked as required.
269
+ * Subscribe to loader updates. Should not be used in conjunction (called in the same component)
270
+ * with useExpressionMatrixData.
271
+ * @param {object} loaders The object mapping
272
+ * datasets and data types to loader instances.
273
+ * @param {string} dataset The key for a dataset,
274
+ * used to identify which loader to use.
275
+ * @param {function} addUrl A function to call to update
276
+ * the URL list.
277
+ * @param {boolean} isRequired Should a warning be thrown if
278
+ * loading is unsuccessful?
279
+ * @returns {object} [attrs] { rows, cols } object containing cell and gene names.
280
+ */
281
+ export function useObsFeatureMatrixIndices(
282
+ loaders, dataset, addUrl, isRequired, matchOn,
283
+ ) {
284
+ const [data, setData] = useState({});
285
+ const [status, setStatus] = useState(STATUS.LOADING);
286
+
287
+ const setWarning = useSetWarning();
288
+ const loader = useMatchingLoader(loaders, dataset, DataType.OBS_FEATURE_MATRIX, matchOn);
289
+
290
+ useEffect(() => {
291
+ if (loader) {
292
+ setStatus(STATUS.LOADING);
293
+ const implementsLoadAttrs = typeof loader.loadAttrs === 'function';
294
+ if (implementsLoadAttrs) {
295
+ loader.loadAttrs().catch(e => warn(e, setWarning)).then((payload) => {
296
+ if (!payload) return;
297
+ const { data: payloadData, url } = payload;
298
+ setData({
299
+ obsIndex: payloadData.rows,
300
+ featureIndex: payloadData.cols,
301
+ });
302
+ addUrl(url, DataType.OBS_FEATURE_MATRIX);
303
+ setStatus(STATUS.SUCCESS);
304
+ });
305
+ } else {
306
+ loader.load().catch(e => warn(e, setWarning)).then((payload) => {
307
+ if (!payload) return;
308
+ const { data: payloadData, url } = payload;
309
+ setData({
310
+ obsIndex: payloadData.obsIndex,
311
+ featureIndex: payloadData.featureIndex,
312
+ });
313
+ addUrl(url, DataType.OBS_FEATURE_MATRIX);
314
+ setStatus(STATUS.SUCCESS);
315
+ });
316
+ }
317
+ } else {
318
+ setData({});
319
+ if (isRequired) {
320
+ warn(
321
+ new LoaderNotFoundError(loaders, dataset, DataType.OBS_FEATURE_MATRIX, matchOn),
322
+ setWarning,
323
+ );
324
+ setStatus(STATUS.ERROR);
325
+ } else {
326
+ setStatus(STATUS.SUCCESS);
327
+ }
328
+ }
329
+ // eslint-disable-next-line react-hooks/exhaustive-deps
330
+ }, [loader]);
331
+
332
+ return [data, status];
333
+ }
334
+
335
+ export function useMultiObsLabels(
336
+ coordinationScopes, obsType, loaders, dataset, addUrl,
337
+ ) {
338
+ const obsLabelsTypes = useMultiCoordinationValues(
339
+ CoordinationType.OBS_LABELS_TYPE,
340
+ coordinationScopes,
341
+ );
342
+ const obsLabelsMatchOnObj = useMemo(() => fromEntries(
343
+ Object.entries(obsLabelsTypes).map(([scope, obsLabelsType]) => ([
344
+ scope,
345
+ { obsLabelsType, obsType },
346
+ ])),
347
+ ), [obsLabelsTypes, obsType]);
348
+ const [obsLabelsData, obsLabelsDataStatus] = useDataTypeMulti(
349
+ DataType.OBS_LABELS, loaders, dataset,
350
+ addUrl, false, {}, {},
351
+ obsLabelsMatchOnObj,
352
+ );
353
+ return [obsLabelsTypes, obsLabelsData, obsLabelsDataStatus];
354
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A loader error ancestor class containing a default constructor
3
+ * and a stub for the required warnInConsole() method.
4
+ */
5
+ export default class AbstractLoaderError {
6
+ constructor(message) {
7
+ this.message = message;
8
+ }
9
+
10
+ // eslint-disable-next-line class-methods-use-this
11
+ warnInConsole() {
12
+ throw new Error('The warnInConsole() method has not been implemented.');
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ import AbstractLoaderError from './AbstractLoaderError';
2
+
3
+ export default class DataSourceFetchError extends AbstractLoaderError {
4
+ constructor(source, url, headers) {
5
+ super(`${source} Error HTTP Status fetching from ${url}`);
6
+ this.source = source;
7
+ this.url = url;
8
+ this.headers = headers;
9
+ }
10
+
11
+ warnInConsole() {
12
+ const { source, url, headers } = this;
13
+ console.warn(`${source} failed to fetch from ${url} with headers ${headers}`);
14
+ }
15
+ }
@@ -0,0 +1,23 @@
1
+ import AbstractLoaderError from './AbstractLoaderError';
2
+
3
+ export default class DatasetNotFoundError extends AbstractLoaderError {
4
+ constructor(datasetUid) {
5
+ super(`Error finding dataset for ${datasetUid}. Please check that at least one dataset exists in the view config.`);
6
+ this.name = 'DatasetNotFoundError';
7
+
8
+ this.datasetUid = datasetUid;
9
+ }
10
+
11
+ warnInConsole() {
12
+ const {
13
+ datasetUid,
14
+ } = this;
15
+ if (datasetUid) {
16
+ console.warn(
17
+ `Unable to find dataset for ${datasetUid}`,
18
+ );
19
+ } else {
20
+ console.warn('No dataset uid specified.');
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,24 @@
1
+ import AbstractLoaderError from './AbstractLoaderError';
2
+
3
+ export default class LoaderNotFoundError extends AbstractLoaderError {
4
+ constructor(loaders, dataset, fileType, viewCoordinationValues) {
5
+ super(`Error: unable to find matching ${fileType} file in dataset ${dataset}.`);
6
+ this.name = 'LoaderNotFoundError';
7
+
8
+ this.loaders = loaders;
9
+ this.dataset = dataset;
10
+ this.fileType = fileType;
11
+ this.viewCoordinationValues = viewCoordinationValues;
12
+ }
13
+
14
+ warnInConsole() {
15
+ const {
16
+ loaders, viewCoordinationValues,
17
+ } = this;
18
+ console.warn(
19
+ // eslint-disable-next-line prefer-template
20
+ `Expected to match on { ${Object.entries(viewCoordinationValues).map(([k, v]) => k + ': ' + v).join(', ')} }`,
21
+ loaders,
22
+ );
23
+ }
24
+ }
@@ -0,0 +1,23 @@
1
+ import AbstractLoaderError from './AbstractLoaderError';
2
+
3
+ export default class LoaderValidationError extends AbstractLoaderError {
4
+ constructor(datasetType, datasetFileType, datasetUrl, reason) {
5
+ super(`Error while validating ${datasetType}.`);
6
+ this.name = 'LoaderValidationError';
7
+
8
+ this.datasetType = datasetType;
9
+ this.datasetFileType = datasetFileType;
10
+ this.datasetUrl = datasetUrl;
11
+ this.reason = reason;
12
+ }
13
+
14
+ warnInConsole() {
15
+ const {
16
+ datasetType, datasetUrl, reason,
17
+ } = this;
18
+ console.warn(
19
+ `${datasetType} from ${datasetUrl}: validation failed`,
20
+ JSON.stringify(reason, null, 2),
21
+ );
22
+ }
23
+ }
@@ -0,0 +1,25 @@
1
+ import AbstractLoaderError from './AbstractLoaderError';
2
+
3
+ export default class OptionsValidationError extends AbstractLoaderError {
4
+ constructor(fileType, url, options, reason) {
5
+ super(`Error while validating file definition options: ${fileType} from ${url}.`);
6
+ this.name = 'OptionsValidationError';
7
+
8
+ this.fileType = fileType;
9
+ this.url = url;
10
+ this.options = options;
11
+ this.reason = reason;
12
+ }
13
+
14
+ warnInConsole() {
15
+ const {
16
+ options, reason,
17
+ } = this;
18
+ console.warn(
19
+ 'Received options\n',
20
+ JSON.stringify(options, null, 2),
21
+ 'JSON schema validation failure reason\n',
22
+ JSON.stringify(reason, null, 2),
23
+ );
24
+ }
25
+ }
File without changes
@@ -0,0 +1,139 @@
1
+ export const cellsJsonSchema = {
2
+ $schema: 'http://json-schema.org/draft-07/schema#',
3
+ $id: 'https://github.com/vitessce/vitessce/#cells-json-options',
4
+ title: 'cells.json options',
5
+ oneOf: [
6
+ { type: 'null' },
7
+ {
8
+ type: 'object',
9
+ additionalProperties: false,
10
+ required: [],
11
+ properties: {
12
+ obsLabelsTypes: {
13
+ type: 'array',
14
+ items: { type: 'string' },
15
+ },
16
+ embeddingTypes: {
17
+ type: 'array',
18
+ items: { type: 'string' },
19
+ },
20
+ },
21
+ },
22
+ ],
23
+ };
24
+
25
+ export const anndataCellsZarrSchema = {
26
+ $schema: 'http://json-schema.org/draft-07/schema#',
27
+ $id: 'https://github.com/vitessce/vitessce/#anndata-cells-zarr-options',
28
+ title: 'anndata-cells.zarr options',
29
+ type: 'object',
30
+ minProperties: 1,
31
+ additionalProperties: false,
32
+ required: [],
33
+ properties: {
34
+ xy: {
35
+ type: 'string',
36
+ description: "The location in the AnnData store of cell centroids, like 'obsm/X_centroids.'",
37
+ },
38
+ poly: {
39
+ type: 'string',
40
+ description: "The location in the AnnData store of cell polygon outlines, like 'obsm/X_polygons.'",
41
+ },
42
+ factors: {
43
+ type: 'array',
44
+ description: "List of locations in the AnnData store of cell sets, like 'obs/louvain'",
45
+ items: {
46
+ type: 'string',
47
+ },
48
+ },
49
+ mappings: {
50
+ patternProperties: {
51
+ '.': {
52
+ type: 'object',
53
+ description: "An object containing key-values for mappings like { UMAP: { key: 'obsm/X_umap', dims: [0, 1] } }.",
54
+ additionalProperties: false,
55
+ required: ['key'],
56
+ properties: {
57
+ key: {
58
+ type: 'string',
59
+ description: "Where to look in the AnnData store for this mapping, like 'obsm/X_umap.'",
60
+ },
61
+ dims: {
62
+ type: 'array',
63
+ description: 'Which indices of the obsm object to take for a scatterplot, allowing for, for example, different PCs from obsm/X_pca',
64
+ minItems: 2,
65
+ maxItems: 2,
66
+ items: { type: 'number' },
67
+ },
68
+ },
69
+ },
70
+ },
71
+ },
72
+ },
73
+ };
74
+
75
+ export const anndataCellSetsZarrSchema = {
76
+ $schema: 'http://json-schema.org/draft-07/schema#',
77
+ $id: 'https://github.com/vitessce/vitessce/#anndata-cell-sets-zarr-options',
78
+ title: 'anndata-cell-sets.zarr options',
79
+ type: 'array',
80
+ items: {
81
+ type: 'object',
82
+ additionalProperties: false,
83
+ required: ['groupName', 'setName'],
84
+ properties: {
85
+ groupName: {
86
+ type: 'string',
87
+ description: "The display name for the set, like 'Cell Type' or 'Louvain.'",
88
+ },
89
+ setName: {
90
+ oneOf: [
91
+ {
92
+ type: 'string',
93
+ description: "The location in the AnnData store for the set, like 'obs/louvain' or 'obs/celltype.'",
94
+ },
95
+ {
96
+ type: 'array',
97
+ items: { type: 'string' },
98
+ description: 'An array of locations in the AnnData store for a hierarchy of set names, from coarse to fine levels.',
99
+ },
100
+ ],
101
+ },
102
+ scoreName: {
103
+ oneOf: [
104
+ {
105
+ type: 'string',
106
+ description: "The location in the AnnData store for the set confidence scores, like 'obs/celltype_prediction_score.'",
107
+ },
108
+ ],
109
+ },
110
+ },
111
+ },
112
+ };
113
+
114
+ export const anndataExpressionMatrixZarrSchema = {
115
+ $schema: 'http://json-schema.org/draft-07/schema#',
116
+ $id: 'https://github.com/vitessce/vitessce/#anndata-expression-matrix-zarr-options',
117
+ title: 'anndata-expression-matrix.zarr options',
118
+ type: 'object',
119
+ additionalProperties: false,
120
+ required: ['matrix'],
121
+ properties: {
122
+ matrix: {
123
+ type: 'string',
124
+ description: "The location in the AnnData store of the cell x gene matrix, like 'obsm/hvg_subset.' or 'X'",
125
+ },
126
+ geneFilter: {
127
+ type: 'string',
128
+ description: "The location in the AnnData store of a filter for the genes if using a subset of the data, like 'var.highly_variable.' if the matrix comes from 'obsm/hvg_subset.'",
129
+ },
130
+ matrixGeneFilter: {
131
+ type: 'string',
132
+ description: "The location in the AnnData store of a filter for the matrix data (used in heatmap and histogram), like 'var.highly_variable.''",
133
+ },
134
+ geneAlias: {
135
+ type: 'string',
136
+ description: 'The location in the AnnData store of a different list of names for gene list component, other than the `var` index',
137
+ },
138
+ },
139
+ };