@vitessce/vit-s 4.0.4 → 4.0.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/index.js +3355 -1143
- package/dist-tsc/VitS.d.ts.map +1 -1
- package/dist-tsc/VitS.js +5 -1
- package/dist-tsc/VitS.js.map +1 -1
- package/dist-tsc/data-hooks-multilevel-utils.d.ts +10 -0
- package/dist-tsc/data-hooks-multilevel-utils.d.ts.map +1 -1
- package/dist-tsc/data-hooks-multilevel-utils.js +12 -0
- package/dist-tsc/data-hooks-multilevel-utils.js.map +1 -1
- package/dist-tsc/data-hooks-multilevel.d.ts +9 -0
- package/dist-tsc/data-hooks-multilevel.d.ts.map +1 -1
- package/dist-tsc/data-hooks-multilevel.js +21 -1
- package/dist-tsc/data-hooks-multilevel.js.map +1 -1
- package/dist-tsc/hooks.d.ts.map +1 -1
- package/dist-tsc/hooks.js +23 -5
- package/dist-tsc/hooks.js.map +1 -1
- package/dist-tsc/hooks.test.d.ts +2 -0
- package/dist-tsc/hooks.test.d.ts.map +1 -0
- package/dist-tsc/hooks.test.js +36 -0
- package/dist-tsc/hooks.test.js.map +1 -0
- package/dist-tsc/index.d.ts +1 -1
- package/dist-tsc/index.js +1 -1
- package/dist-tsc/index.js.map +1 -1
- package/package.json +15 -15
- package/src/VitS.js +7 -1
- package/src/data-hooks-multilevel-utils.js +19 -0
- package/src/data-hooks-multilevel.js +32 -0
- package/src/hooks.js +24 -5
- package/src/hooks.test.jsx +39 -0
- package/src/index.js +1 -0
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
useObsLocationsMultiLevel,
|
|
11
11
|
useObsSetsMultiLevel,
|
|
12
12
|
useObsLabelsMultiLevel,
|
|
13
|
+
useObsColorsMultiLevel,
|
|
13
14
|
} from './data-hooks-multilevel-utils.js';
|
|
14
15
|
|
|
15
16
|
|
|
@@ -319,3 +320,34 @@ export function useSegmentationMultiObsSets(
|
|
|
319
320
|
);
|
|
320
321
|
return [indicesData, indicesDataStatus, indicesDataErrors];
|
|
321
322
|
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Wrapper around useObsColorsMultiLevel.
|
|
326
|
+
* @param {object} coordinationScopes
|
|
327
|
+
* @param {object} coordinationScopesBy
|
|
328
|
+
* @param {object} loaders
|
|
329
|
+
* @param {string} dataset
|
|
330
|
+
* @returns {array} [data, status, errors]
|
|
331
|
+
*/
|
|
332
|
+
export function useSegmentationMultiObsColors(
|
|
333
|
+
coordinationScopes, coordinationScopesBy, loaders, dataset,
|
|
334
|
+
) {
|
|
335
|
+
const obsTypeCoordination = useComplexCoordinationSecondary(
|
|
336
|
+
[
|
|
337
|
+
CoordinationType.OBS_TYPE,
|
|
338
|
+
],
|
|
339
|
+
coordinationScopes,
|
|
340
|
+
coordinationScopesBy,
|
|
341
|
+
CoordinationType.SEGMENTATION_LAYER,
|
|
342
|
+
CoordinationType.SEGMENTATION_CHANNEL,
|
|
343
|
+
);
|
|
344
|
+
const matchOnObj = useMemo(() => obsTypeCoordination[0],
|
|
345
|
+
// imageCoordination reference changes each render,
|
|
346
|
+
// use coordinationScopes and coordinationScopesBy which are
|
|
347
|
+
// indirect dependencies here.
|
|
348
|
+
[coordinationScopes, coordinationScopesBy]);
|
|
349
|
+
const [colorsData, colorsDataStatus, colorsDataErrors] = useObsColorsMultiLevel(
|
|
350
|
+
loaders, dataset, false, matchOnObj, 2,
|
|
351
|
+
);
|
|
352
|
+
return [colorsData, colorsDataStatus, colorsDataErrors];
|
|
353
|
+
}
|
package/src/hooks.js
CHANGED
|
@@ -5,6 +5,7 @@ import { debounce, every } from 'lodash-es';
|
|
|
5
5
|
import { extent } from 'd3-array';
|
|
6
6
|
import { useQuery } from '@tanstack/react-query';
|
|
7
7
|
import { capitalize } from '@vitessce/utils';
|
|
8
|
+
import { getObsIndexMap } from '@vitessce/sets-utils';
|
|
8
9
|
import { STATUS, AsyncFunctionType } from '@vitessce/constants-internal';
|
|
9
10
|
import { VITESSCE_CONTAINER } from './classNames.js';
|
|
10
11
|
import { useGridResize, useEmitGridResize } from './state/hooks.js';
|
|
@@ -258,6 +259,10 @@ export function useUint8FeatureSelection(expressionData) {
|
|
|
258
259
|
}, [expressionData]);
|
|
259
260
|
}
|
|
260
261
|
|
|
262
|
+
// Marks an instance index that equals the matrix row index, so that no
|
|
263
|
+
// per-observation mapping needs to be built.
|
|
264
|
+
const IDENTITY_MAPPING = 'identity';
|
|
265
|
+
|
|
261
266
|
export function useExpressionValueGetter(
|
|
262
267
|
{ instanceObsIndex, matrixObsIndex, expressionData },
|
|
263
268
|
) {
|
|
@@ -267,18 +272,32 @@ export function useExpressionValueGetter(
|
|
|
267
272
|
// we need a way to look up an obsFeatureMatrix obsIndex index
|
|
268
273
|
// given an obsEmbedding obsIndex index.
|
|
269
274
|
const toMatrixIndexMap = useMemo(() => {
|
|
270
|
-
if (instanceObsIndex
|
|
271
|
-
|
|
272
|
-
return instanceObsIndex.map(key => matrixIndexMap.get(key));
|
|
275
|
+
if (!instanceObsIndex || !matrixObsIndex) {
|
|
276
|
+
return null;
|
|
273
277
|
}
|
|
274
|
-
|
|
278
|
+
if (instanceObsIndex === matrixObsIndex) {
|
|
279
|
+
// The same array (the usual case when both come from one data source)
|
|
280
|
+
// is already aligned by position.
|
|
281
|
+
return IDENTITY_MAPPING;
|
|
282
|
+
}
|
|
283
|
+
// The map is shared with other consumers of this index via getObsIndexMap.
|
|
284
|
+
const matrixIndexMap = getObsIndexMap(matrixObsIndex);
|
|
285
|
+
const mapping = new Int32Array(instanceObsIndex.length);
|
|
286
|
+
for (let i = 0; i < instanceObsIndex.length; i += 1) {
|
|
287
|
+
const rowIndex = matrixIndexMap.get(instanceObsIndex[i]);
|
|
288
|
+
mapping[i] = rowIndex === undefined ? -1 : rowIndex;
|
|
289
|
+
}
|
|
290
|
+
return mapping;
|
|
275
291
|
}, [instanceObsIndex, matrixObsIndex]);
|
|
276
292
|
|
|
277
293
|
// Set up a getter function for gene expression values, to be used
|
|
278
294
|
// by the DeckGL layer to obtain values for instanced attributes.
|
|
279
295
|
const getExpressionValue = useCallback((entry, { index: instanceIndex }) => {
|
|
280
296
|
if (toMatrixIndexMap && expressionData && expressionData[0]) {
|
|
281
|
-
const rowIndex = toMatrixIndexMap
|
|
297
|
+
const rowIndex = toMatrixIndexMap === IDENTITY_MAPPING
|
|
298
|
+
? instanceIndex
|
|
299
|
+
: toMatrixIndexMap[instanceIndex];
|
|
300
|
+
// An observation absent from the matrix (-1) reads as undefined, as before.
|
|
282
301
|
const val = expressionData[0][rowIndex];
|
|
283
302
|
return val;
|
|
284
303
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { renderHook } from '@testing-library/react';
|
|
3
|
+
import { useExpressionValueGetter } from './hooks.js';
|
|
4
|
+
|
|
5
|
+
describe('useExpressionValueGetter', () => {
|
|
6
|
+
const expressionData = [new Uint8Array([10, 20, 30])];
|
|
7
|
+
|
|
8
|
+
it('reads by position when the instance and matrix indices are the same array', () => {
|
|
9
|
+
const obsIndex = ['a', 'b', 'c'];
|
|
10
|
+
const { result } = renderHook(() => useExpressionValueGetter({
|
|
11
|
+
instanceObsIndex: obsIndex, matrixObsIndex: obsIndex, expressionData,
|
|
12
|
+
}));
|
|
13
|
+
expect(result.current(null, { index: 0 })).toEqual(10);
|
|
14
|
+
expect(result.current(null, { index: 2 })).toEqual(30);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('maps through observation IDs when the indices differ', () => {
|
|
18
|
+
const { result } = renderHook(() => useExpressionValueGetter({
|
|
19
|
+
instanceObsIndex: ['c', 'unknown', 'a'],
|
|
20
|
+
matrixObsIndex: ['a', 'b', 'c'],
|
|
21
|
+
expressionData,
|
|
22
|
+
}));
|
|
23
|
+
expect(result.current(null, { index: 0 })).toEqual(30);
|
|
24
|
+
// An observation absent from the matrix reads as undefined, as before.
|
|
25
|
+
expect(result.current(null, { index: 1 })).toEqual(undefined);
|
|
26
|
+
expect(result.current(null, { index: 2 })).toEqual(10);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('returns 0 without indices or without data', () => {
|
|
30
|
+
const { result: noIndices } = renderHook(() => useExpressionValueGetter({
|
|
31
|
+
instanceObsIndex: null, matrixObsIndex: ['a'], expressionData,
|
|
32
|
+
}));
|
|
33
|
+
expect(noIndices.current(null, { index: 0 })).toEqual(0);
|
|
34
|
+
const { result: noData } = renderHook(() => useExpressionValueGetter({
|
|
35
|
+
instanceObsIndex: ['a'], matrixObsIndex: ['a'], expressionData: null,
|
|
36
|
+
}));
|
|
37
|
+
expect(noData.current(null, { index: 0 })).toEqual(0);
|
|
38
|
+
});
|
|
39
|
+
});
|