From 9f0f3dc3dd7044d9e241bcec3d46ec7903f596ea Mon Sep 17 00:00:00 2001 From: Axel Bocciarelli Date: Mon, 24 Jun 2024 09:09:27 +0200 Subject: [PATCH] Support complex image auxiliaries --- cypress/e2e/app.cy.ts | 16 ++++++------ packages/app/src/__tests__/NexusPack.test.tsx | 2 +- packages/app/src/providers/mock/mock-file.ts | 12 +++++---- .../containers/NxComplexImageContainer.tsx | 21 ++++++++++++---- .../nexus/containers/NxImageContainer.tsx | 14 ++--------- packages/app/src/vis-packs/nexus/hooks.ts | 25 +++++++++++++++++-- 6 files changed, 57 insertions(+), 33 deletions(-) diff --git a/cypress/e2e/app.cy.ts b/cypress/e2e/app.cy.ts index 60c57d170..b03639145 100644 --- a/cypress/e2e/app.cy.ts +++ b/cypress/e2e/app.cy.ts @@ -399,29 +399,29 @@ describe('/mock', () => { } }); - it('visualize 2D complex signal as NxImage', () => { + it('visualize 2D complex signal with "spectrum" interpretation and auxiliaries as NxLine', () => { cy.selectExplorerNode('nexus_entry'); - cy.selectExplorerNode('complex'); + cy.selectExplorerNode('complex_spectrum'); cy.findByRole('heading', { - name: 'nexus_entry / complex', + name: 'nexus_entry / complex_spectrum', }).should('be.visible'); if (Cypress.env('TAKE_SNAPSHOTS')) { - cy.matchImageSnapshot('nximage_complex_2d'); + cy.matchImageSnapshot('nxline_complex_2d_aux'); } }); - it('visualize 2D complex signal with "spectrum" interpretation and auxiliaries as NxLine', () => { + it('visualize 2D complex signal as NxImage', () => { cy.selectExplorerNode('nexus_entry'); - cy.selectExplorerNode('complex_spectrum'); + cy.selectExplorerNode('complex_image'); cy.findByRole('heading', { - name: 'nexus_entry / complex_spectrum', + name: 'nexus_entry / complex_image', }).should('be.visible'); if (Cypress.env('TAKE_SNAPSHOTS')) { - cy.matchImageSnapshot('nxline_complex_2d_aux'); + cy.matchImageSnapshot('nximage_complex_2d'); } }); diff --git a/packages/app/src/__tests__/NexusPack.test.tsx b/packages/app/src/__tests__/NexusPack.test.tsx index ba62a6cc6..1c572f6f9 100644 --- a/packages/app/src/__tests__/NexusPack.test.tsx +++ b/packages/app/src/__tests__/NexusPack.test.tsx @@ -55,7 +55,7 @@ test('visualize NXdata group without explicit signal interpretation', async () = expect(screen.getByRole('figure', { name: 'oneD' })).toBeVisible(); // signal name // 2D complex signal (no interpretation) - await selectExplorerNode('complex'); + await selectExplorerNode('complex_image'); expect(getVisTabs()).toEqual([NexusVis.NxSpectrum, NexusVis.NxImage]); expect(getSelectedVisTab()).toBe(NexusVis.NxImage); expect( diff --git a/packages/app/src/providers/mock/mock-file.ts b/packages/app/src/providers/mock/mock-file.ts index 7d55ef45d..a6bc68158 100644 --- a/packages/app/src/providers/mock/mock-file.ts +++ b/packages/app/src/providers/mock/mock-file.ts @@ -219,11 +219,6 @@ export function makeMockFile(): GroupWithChildren { }, auxAttr: ['secondary', 'tertiary'], }), - nxData('complex', { - signal: array('twoD_cplx'), - axes: { position: array('position') }, - axesAttr: ['.', 'position'], - }), nxData('complex_spectrum', { signal: withNxAttr(array('twoD_cplx'), { interpretation: 'spectrum', @@ -231,6 +226,13 @@ export function makeMockFile(): GroupWithChildren { auxiliary: { secondary_cplx: array('secondary_cplx') }, auxAttr: ['secondary_cplx'], }), + nxData('complex_image', { + signal: array('twoD_cplx'), + axes: { position: array('position') }, + axesAttr: ['.', 'position'], + auxiliary: { secondary_cplx: array('secondary_cplx') }, + auxAttr: ['secondary_cplx'], + }), nxData('rgb-image', { signal: withImageAttr( withNxAttr(array('fourD_rgb'), { diff --git a/packages/app/src/vis-packs/nexus/containers/NxComplexImageContainer.tsx b/packages/app/src/vis-packs/nexus/containers/NxComplexImageContainer.tsx index cd98986e2..e258553d3 100644 --- a/packages/app/src/vis-packs/nexus/containers/NxComplexImageContainer.tsx +++ b/packages/app/src/vis-packs/nexus/containers/NxComplexImageContainer.tsx @@ -1,4 +1,5 @@ import { assertGroup, assertMinDims } from '@h5web/shared/guards'; +import { useState } from 'react'; import DimensionMapper from '../../../dimension-mapper/DimensionMapper'; import { useDimMappingState } from '../../../dimension-mapper/hooks'; @@ -9,7 +10,8 @@ import { getSliceSelection } from '../../core/utils'; import type { VisContainerProps } from '../../models'; import VisBoundary from '../../VisBoundary'; import { assertComplexNxData } from '../guards'; -import { useNxData, useNxValuesCached } from '../hooks'; +import { useNxData, useNxImageDataToFetch, useNxValuesCached } from '../hooks'; +import NxSignalPicker from '../NxSignalPicker'; import NxValuesFetcher from '../NxValuesFetcher'; import { guessKeepRatio } from '../utils'; @@ -20,10 +22,11 @@ function NxComplexImageContainer(props: VisContainerProps) { const nxData = useNxData(entity); assertComplexNxData(nxData); - const { signalDef, axisDefs, silxStyle } = nxData; - assertMinDims(signalDef.dataset, 2); + const { signalDef, axisDefs, auxDefs, silxStyle } = nxData; + const [selectedDef, setSelectedDef] = useState(signalDef); + assertMinDims(selectedDef.dataset, 2); - const { shape: dims } = signalDef.dataset; + const { shape: dims } = selectedDef.dataset; const [dimMapping, setDimMapping] = useDimMappingState(dims, 2); const axisLabels = axisDefs.map((def) => def?.label); @@ -36,8 +39,16 @@ function NxComplexImageContainer(props: VisContainerProps) { keepRatio: guessKeepRatio(xAxisDef, yAxisDef), }); + const nxDataToFetch = useNxImageDataToFetch(nxData, selectedDef); + return ( <> + {auxDefs.length > 0 && ( + + )} { const { signal, axisValues, title } = nxValues; diff --git a/packages/app/src/vis-packs/nexus/containers/NxImageContainer.tsx b/packages/app/src/vis-packs/nexus/containers/NxImageContainer.tsx index f9022ac46..008bd9c5e 100644 --- a/packages/app/src/vis-packs/nexus/containers/NxImageContainer.tsx +++ b/packages/app/src/vis-packs/nexus/containers/NxImageContainer.tsx @@ -1,5 +1,4 @@ import { assertGroup, assertMinDims } from '@h5web/shared/guards'; -import type { NumericType } from '@h5web/shared/hdf5-models'; import { useState } from 'react'; import DimensionMapper from '../../../dimension-mapper/DimensionMapper'; @@ -10,8 +9,7 @@ import { getSliceSelection } from '../../core/utils'; import type { VisContainerProps } from '../../models'; import VisBoundary from '../../VisBoundary'; import { assertNumericNxData } from '../guards'; -import { useNxData, useNxValuesCached } from '../hooks'; -import type { NxData } from '../models'; +import { useNxData, useNxImageDataToFetch, useNxValuesCached } from '../hooks'; import NxSignalPicker from '../NxSignalPicker'; import NxValuesFetcher from '../NxValuesFetcher'; import { guessKeepRatio } from '../utils'; @@ -39,15 +37,7 @@ function NxImageContainer(props: VisContainerProps) { keepRatio: guessKeepRatio(xAxisDef, yAxisDef), }); - const nxDataToFetch: NxData = { - ...nxData, - signalDef: selectedDef, - auxDefs: [], // fetch selected signal only - titleDataset: - selectedDef.dataset === signalDef.dataset - ? nxData.titleDataset - : undefined, // when auxiliary signal is selected, always use its label as title - }; + const nxDataToFetch = useNxImageDataToFetch(nxData, selectedDef); return ( <> diff --git a/packages/app/src/vis-packs/nexus/hooks.ts b/packages/app/src/vis-packs/nexus/hooks.ts index e97353766..e236ebc8e 100644 --- a/packages/app/src/vis-packs/nexus/hooks.ts +++ b/packages/app/src/vis-packs/nexus/hooks.ts @@ -1,9 +1,13 @@ -import type { GroupWithChildren } from '@h5web/shared/hdf5-models'; +import type { + ComplexType, + GroupWithChildren, + NumericType, +} from '@h5web/shared/hdf5-models'; import type { DimensionMapping } from '../../dimension-mapper/models'; import { useDataContext } from '../../providers/DataProvider'; import { useValuesInCache } from '../core/hooks'; -import type { NxData } from './models'; +import type { DatasetDef, NxData } from './models'; import { assertNxDataGroup, findAuxErrorDataset, @@ -44,6 +48,23 @@ export function useNxData(group: GroupWithChildren): NxData { }; } +export function useNxImageDataToFetch( + nxData: NxData, + selectedDef: DatasetDef, +): NxData { + const { signalDef } = nxData; + + return { + ...nxData, + signalDef: selectedDef, + auxDefs: [], // fetch selected signal only + titleDataset: + selectedDef.dataset === signalDef.dataset + ? nxData.titleDataset + : undefined, // when auxiliary signal is selected, always use its label as title + }; +} + export function useNxValuesCached( nxData: NxData, ): (dimMapping: DimensionMapping) => boolean {