Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions apps/visr/src/components/spectroscopy/SpectroscopyControls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
Box,
FormControlLabel,
Radio,
RadioGroup,
Typography,
} from "@mui/material";
import { DataSource } from "./dataSource";

interface Props {
onSetDataSource: (event: React.ChangeEvent<HTMLInputElement>) => void;
dataSource: DataSource;
}

export default function Controls({ onSetDataSource, dataSource }: Props) {
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: 3,
p: 3,
}}
>
<Typography variant="overline" color="primary">
Plots
</Typography>

<Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
<Typography variant="body2" color="primary">
Data Source
</Typography>
<RadioGroup row value={dataSource} onChange={onSetDataSource}>
<FormControlLabel
value={DataSource.Camera}
control={<Radio />}
label="Camera"
/>
<FormControlLabel
value={DataSource.Diodes}
control={<Radio />}
label="Diodes"
/>
</RadioGroup>
</Box>
</Box>
);
}
90 changes: 75 additions & 15 deletions apps/visr/src/components/spectroscopy/SpectroscopyPlots.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ndarray from "ndarray";
import { ReactGridLayout, useContainerWidth } from "react-grid-layout";
import { useLayoutEffect, useState, type ComponentProps } from "react";
import { useSpectroscopyData, type RGBColour } from "./useSpectroscopyData";
import { DataSource } from "./dataSource";

// ---------------------------------------------------------------------------
// Helpers: data conversion
Expand Down Expand Up @@ -72,14 +73,32 @@ async function fetchMap(
datapath: string,
colour: RGBColour,
snake: boolean,
) {
dataSource: DataSource,
): Promise<NDT | null> {
// while there is only one data source fake fetch
if (dataSource === DataSource.Diodes) return null;
// add data source string from enum ('camera' or 'diodes') when enz-locum data is available
const url = `/api/data/map?filepath=${encodeURIComponent(filepath)}&datapath=${encodeURIComponent(datapath)}&snake=${encodeURIComponent(snake)}`;
const resp = await fetch(url);
if (!resp.ok) throw new Error(resp.statusText);
const mapResponse: MapResponse = await resp.json();
return toNDT(mapResponse.values, colour);
}

const fetchCamera = (
filepath: string,
datapath: string,
colour: RGBColour,
snake: boolean,
) => fetchMap(filepath, datapath, colour, snake, DataSource.Camera);

const fetchDiodes = (
filepath: string,
datapath: string,
colour: RGBColour,
snake: boolean,
) => fetchMap(filepath, datapath, colour, snake, DataSource.Diodes);

// ---------------------------------------------------------------------------
// Channel definitions
// ---------------------------------------------------------------------------
Expand All @@ -88,7 +107,7 @@ const CHANNELS = [
{ key: "red", label: "Red channel" },
{ key: "green", label: "Green channel" },
{ key: "blue", label: "Blue channel" },
//{ key: "gray", label: "Gray channel" },
//{ key: "gray?", label: "Composite" },
] as const;

type ChannelKey = (typeof CHANNELS)[number]["key"];
Expand All @@ -100,15 +119,22 @@ export type SpectroscopyData = Partial<Record<ChannelKey, PlotValues>>;
// ---------------------------------------------------------------------------

interface SpectroscopyPlotsProps {
dataSource: DataSource;
expanded: boolean;
plotAspectRatio: number | "auto" | "equal";
}

function SpectroscopyPlots({
dataSource,
expanded,
plotAspectRatio,
}: SpectroscopyPlotsProps) {
const { data: channels } = useSpectroscopyData(fetchMap);
const { data: cameraChannels } = useSpectroscopyData(fetchCamera);
const { data: diodeChannels } = useSpectroscopyData(fetchDiodes);

const channels =
dataSource === DataSource.Camera ? cameraChannels : diodeChannels;

const { width, containerRef, mounted } = useContainerWidth();

// -------------------------------------------------------------------------
Expand Down Expand Up @@ -143,7 +169,7 @@ function SpectroscopyPlots({
const gridHeight = rowHeight * totalRows;

// -------------------------------------------------------------------------
// Layout: 3x1 collapsed, 2x2 expanded
// Layout: 4x1 collapsed, 2x2 expanded
// -------------------------------------------------------------------------
const layout = [
{ i: "0", x: 0, y: 0, w: w, h: rowsPerPlot, static: true },
Expand All @@ -156,22 +182,36 @@ function SpectroscopyPlots({
h: rowsPerPlot,
static: true,
},
{
i: "3",
x: expanded ? 1 : 3,
y: expanded ? rowsPerPlot : 0,
w: w,
h: rowsPerPlot,
static: true,
},
];

// -------------------------------------------------------------------------
// Views
// -------------------------------------------------------------------------
const views = CHANNELS.map(({ key }) => (
<ImagePlot
aspect={plotAspectRatio}
plotConfig={{}}
customToolbarChildren={null}
values={channels[key] ?? EMPTY_NDT}
//tightAxes //requires Davidia 1.1.0
/>
));
const views = [
...CHANNELS.map(({ key }) => {
const values = channels[key];
if (!values) return <EmptyPlot message="No data" />;
return (
<ImagePlot
aspect={plotAspectRatio}
plotConfig={{}}
customToolbarChildren={null}
values={values}
/>
);
}),
<EmptyPlot message="Composite placeholder" />,
];

const titles = CHANNELS.map(({ label }) => label);
const titles = [...CHANNELS.map(({ label }) => label), "Composite"];

// -------------------------------------------------------------------------
// Plot cells
Expand Down Expand Up @@ -216,6 +256,26 @@ function SpectroscopyPlots({
</Box>
));

// -------------------------------------------------------------------------
// Empty plot
// -------------------------------------------------------------------------
function EmptyPlot({ message }: { message: string }) {
return (
<Box
sx={{
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<Typography variant="body2" color="text.secondary">
{message}
</Typography>
</Box>
);
}

// -------------------------------------------------------------------------
// Render
// -------------------------------------------------------------------------
Expand All @@ -237,7 +297,7 @@ function SpectroscopyPlots({
width={width}
style={{ height: gridHeight }}
gridConfig={{
cols: expanded ? 2 : 3,
cols: expanded ? 2 : 4,
rowHeight: rowHeight,
margin: [0, 0],
}}
Expand Down
15 changes: 14 additions & 1 deletion apps/visr/src/components/spectroscopy/SpectroscopyView.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Box } from "@mui/material";
import SpectroscopyPlots from "./SpectroscopyPlots";
import { DataSource } from "./dataSource";
import { useEffect, useState } from "react";
import { useScanEvents } from "../../hooks/scanEvents";
import { useSubmitWorkflow } from "../../hooks/useSubmitWorkflow";
import { useInstrumentSession } from "../../context/instrumentSession/useInstrumentSession";
import { visitTextToVisit } from "../../utils/common";
import ControlsDrawer from "../ControlsDrawer";
import { SpectroscopyForm } from "./SpectroscopyForm";
import SpectroscopyControls from "./SpectroscopyControls";

export type SpectroscopyFormData = {
total_number_of_scan_points: number;
Expand All @@ -26,6 +28,7 @@ const PLOT_ASPECT_RATIO = "equal";

function SpectroscopyView() {
const [drawerOpen, setDrawerOpen] = useState(true);
const [dataSource, setDataSource] = useState(DataSource.Camera);

// -------------------------------------------------------------------------
// Set off workflow when scan ends
Expand All @@ -49,6 +52,9 @@ function SpectroscopyView() {
}
}, [scanEvent, instrumentSession, submitWorkflow]);

const handleSetDataSource = (event: React.ChangeEvent<HTMLInputElement>) =>
setDataSource(event.target.value as DataSource);

// -------------------------------------------------------------------------
// Render
// -------------------------------------------------------------------------
Expand All @@ -66,14 +72,21 @@ function SpectroscopyView() {
}}
>
<SpectroscopyPlots
dataSource={dataSource}
expanded={!drawerOpen}
plotAspectRatio={PLOT_ASPECT_RATIO}
/>
<ControlsDrawer
open={drawerOpen}
collapsedHeight={DRAWER_COLLAPSED_HEIGHT}
onToggle={() => setDrawerOpen(prev => !prev)}
controls={<SpectroscopyForm />}
controls={[
<SpectroscopyForm />,
<SpectroscopyControls
dataSource={dataSource}
onSetDataSource={handleSetDataSource}
/>,
]}
/>
</Box>
);
Expand Down
4 changes: 4 additions & 0 deletions apps/visr/src/components/spectroscopy/dataSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum DataSource {
Camera = "camera",
Diodes = "diodes",
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type FetchMapFunction = (
datapath: string,
colour: RGBColour,
snake: boolean,
) => Promise<NDT>;
) => Promise<NDT | null>;

export interface DataChannels {
red: NDT | null;
Expand Down
8 changes: 7 additions & 1 deletion apps/visr/src/components/tomography/SliceViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Box } from "@mui/material";
import { Plane } from "./PlaneEnum";
import { HeatmapPlot } from "@diamondlightsource/davidia";
import ndarray from "ndarray";
import createArrayFromView from "../../utils/createArrayFromView";

// Not importing Plane in case we move SliceViewer somewhere else as a generic component
enum Plane {
X,
Y,
Z,
}

interface Props {
volumeData: Uint8Array;
volumeShape: [number, number, number];
Expand Down
2 changes: 1 addition & 1 deletion apps/visr/src/components/tomography/TomographyControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
Slider,
Typography,
} from "@mui/material";
import { Plane } from "./PlaneEnum";
import { Plane } from "./plane";

interface Props {
onSlide: (event: Event, newValue: number | number[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion apps/visr/src/components/tomography/TomographyPlots.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ReactGridLayout, useContainerWidth } from "react-grid-layout";
import { useLayoutEffect, useState } from "react";
import SliceViewer from "./SliceViewer";
import VolumeRenderer from "./VolumeRenderer";
import { Plane } from "./PlaneEnum";
import { Plane } from "./plane";

// ---------------------------------------------------------------------------
// Types
Expand Down
2 changes: 1 addition & 1 deletion apps/visr/src/components/tomography/TomographyView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Box } from "@mui/material";
import { useEffect, useState } from "react";
import TomographyControls from "./TomographyControls";
import { TomographyForm } from "./TomographyForm";
import { Plane } from "./PlaneEnum";
import { Plane } from "./plane";
import ControlsDrawer from "../ControlsDrawer";
import TomographyPlots from "./TomographyPlots";

Expand Down
Loading