Build Packages / Unit tests (push) Successful in 1h31m59s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 8m43s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 10m5s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 9m27s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 8m56s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 9m24s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 10m27s
Build Packages / build:rpm (rocky8) (push) Successful in 9m20s
Build Packages / build:rpm (rocky9) (push) Successful in 10m50s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 9m54s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 8m38s
Build Packages / DIALS test (push) Successful in 12m13s
Build Packages / XDS test (durin plugin) (push) Successful in 7m8s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m8s
Build Packages / XDS test (neggia plugin) (push) Successful in 7m50s
Build Packages / Generate python client (push) Successful in 16s
Build Packages / Build documentation (push) Successful in 50s
Build Packages / Create release (push) Skipped
This is an UNSTABLE release. It includes many experimental features, as well as many AI generated fixes. We recommend using rc.152 for production use. * jfjoch_broker: Add EXPERIMENTAL pixelrefine mode for image processing * jfjoch_broker: Allow to load user mask from 8-bit and 16-bit TIFF files * jfjoch_broker: Add ROI calculation in non-FPGA workflow * jfjoch_broker: Fixes to TCP image pusher * jfjoch_broker: Remove NUMA bindings * jfjoch_broker: Improvements to indexing * jfjoch_broker: For PSI EIGER, trimming energies are taken from the detector configuration (now compulsory) instead of hardcoded values * jfjoch_writer: Save ROI definitions and the per-pixel ROI bitmap in the master file; azimuthal ROIs support phi (angular) sectors * jfjoch_viewer: Major redesign with dockable panels and saved layouts, plus on-canvas creation/move/resize of box, circle and azimuthal ROIs * jfjoch_viewer: Run jfjoch_process reprocessing jobs from inside the GUI and overlay per-run results Reviewed-on: #63
262 lines
12 KiB
TypeScript
262 lines
12 KiB
TypeScript
import {ChangeEvent, memo, useEffect, useState} from 'react';
|
|
|
|
import {Checkbox, FormControlLabel, FormGroup, List, ListItem, Stack, Tooltip} from "@mui/material";
|
|
import FormControl from "@mui/material/FormControl";
|
|
import InputLabel from "@mui/material/InputLabel";
|
|
import Select, {SelectChangeEvent} from "@mui/material/Select";
|
|
import MenuItem from "@mui/material/MenuItem";
|
|
import {image_format_settings} from "../client";
|
|
import {putConfigImageFormatMutation} from "../client/@tanstack/react-query.gen";
|
|
import NumberTextField from "./NumberTextField";
|
|
import _ from "lodash";
|
|
import SettingsPanel from "./SettingsPanel";
|
|
import {useUpload} from "./useUpload";
|
|
|
|
type MyProps = {
|
|
s?: image_format_settings
|
|
}
|
|
|
|
const default_image_format_settings: image_format_settings = {
|
|
summation: true,
|
|
geometry_transform: true,
|
|
jungfrau_conversion: true,
|
|
jungfrau_conversion_factor_keV: undefined,
|
|
bit_depth_image: undefined,
|
|
signed_output: undefined,
|
|
mask_module_edges: true,
|
|
mask_chip_edges: true,
|
|
jungfrau_mask_pixels_without_g0: true,
|
|
apply_mask: false,
|
|
jungfrau_pedestal_g0_rms_limit: 100
|
|
};
|
|
|
|
function extractSignForSelection(input: image_format_settings) : string {
|
|
if (input.signed_output === undefined)
|
|
return 'a';
|
|
else if (input.signed_output)
|
|
return 's';
|
|
else
|
|
return 'u';
|
|
}
|
|
|
|
function extractDepthForSelection(input: image_format_settings) : string {
|
|
if (input.bit_depth_image === undefined)
|
|
return 'a';
|
|
else if (input.bit_depth_image === 8)
|
|
return '8';
|
|
else if (input.bit_depth_image === 16)
|
|
return '16';
|
|
else if (input.bit_depth_image === 32)
|
|
return '32';
|
|
else
|
|
return "";
|
|
}
|
|
|
|
function ImageFormatSettings({s: serverS}: MyProps) {
|
|
const [s, setS] = useState<image_format_settings>(default_image_format_settings);
|
|
const [lastDownloadedS, setLastDownloadedS] = useState<image_format_settings>(default_image_format_settings);
|
|
const [bitWidthSelection, setBitWidthSelection] = useState("a");
|
|
const [signSelection, setSignSelection] = useState("a");
|
|
const [jungfrauConversionFactorErr, setJungfrauConversionFactorErr] = useState(false);
|
|
const [jungfrauConversionFactorOld, setJungfrauConversionFactorOld] = useState(12.4);
|
|
const [downloadCounter, setDownloadCounter] = useState(0);
|
|
const { submit, pending, snackbar } = useUpload(putConfigImageFormatMutation());
|
|
|
|
useEffect(() => {
|
|
if ((serverS !== undefined) && !_.isEqual(serverS, lastDownloadedS)) {
|
|
setS(serverS);
|
|
setLastDownloadedS(serverS);
|
|
setJungfrauConversionFactorErr(false);
|
|
setDownloadCounter(c => c + 1);
|
|
setJungfrauConversionFactorOld(serverS.jungfrau_conversion_factor_keV ?? jungfrauConversionFactorOld);
|
|
setBitWidthSelection(extractDepthForSelection(serverS));
|
|
setSignSelection(extractSignForSelection(serverS));
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [serverS]);
|
|
|
|
const handleBitWidthChange = (event: SelectChangeEvent) => {
|
|
let val: image_format_settings['bit_depth_image'] = undefined;
|
|
|
|
if (event.target.value === "a")
|
|
val = undefined;
|
|
else if (event.target.value === "8")
|
|
val = 8;
|
|
else if (event.target.value === "16")
|
|
val = 16;
|
|
else if (event.target.value === "32")
|
|
val = 32;
|
|
|
|
setBitWidthSelection(event.target.value);
|
|
setS(prev => ({...prev, bit_depth_image: val}));
|
|
};
|
|
|
|
const handleSignChange = (event: SelectChangeEvent) => {
|
|
let val: boolean|undefined = undefined;
|
|
|
|
if (event.target.value === "a")
|
|
val = undefined;
|
|
else if (event.target.value === "u")
|
|
val = false;
|
|
else if (event.target.value === "s")
|
|
val = true;
|
|
|
|
setSignSelection(event.target.value);
|
|
setS(prev => ({...prev, signed_output: val}));
|
|
};
|
|
|
|
const dirty = !_.isEqual(s, lastDownloadedS);
|
|
|
|
return (
|
|
<SettingsPanel title="Output image format" dirty={dirty}
|
|
onUpload={() => submit(s)} uploadDisabled={pending || jungfrauConversionFactorErr} snackbar={snackbar}>
|
|
<FormGroup>
|
|
<FormControlLabel control={
|
|
<Checkbox checked={s.geometry_transform}
|
|
onChange={
|
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
setS(prev => ({...prev, geometry_transform: event.target.checked}));
|
|
}}/>
|
|
} label="Geometry transformation"/>
|
|
<FormControlLabel control={
|
|
<Checkbox checked={s.summation}
|
|
onChange={
|
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
setS(prev => ({...prev, summation: event.target.checked}));
|
|
}}/>
|
|
} label="Image summation"/>
|
|
<FormControlLabel control={
|
|
<Checkbox checked={s.mask_chip_edges}
|
|
onChange={
|
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
setS(prev => ({...prev, mask_chip_edges: event.target.checked}));
|
|
}}/>
|
|
} label="Mask chip edges"/>
|
|
|
|
<FormControlLabel control={
|
|
<Checkbox checked={s.mask_module_edges}
|
|
onChange={
|
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
setS(prev => ({...prev, mask_module_edges: event.target.checked}));
|
|
}}/>
|
|
} label="Mask module edges"/>
|
|
<FormControlLabel control={
|
|
<Checkbox checked={s.apply_mask}
|
|
onChange={
|
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
setS(prev => ({...prev, apply_mask: event.target.checked}));
|
|
}}/>
|
|
} label="Apply pixel masks on images"/>
|
|
</FormGroup>
|
|
|
|
<b>Output pixel value</b>
|
|
<Stack spacing={2} direction="row">
|
|
<FormControl>
|
|
<InputLabel id="demo-simple-select-label">Bit-width</InputLabel>
|
|
<Select
|
|
sx={{width: 150}}
|
|
labelId="demo-simple-select-label"
|
|
id="demo-simple-select"
|
|
label="Detector"
|
|
value={bitWidthSelection}
|
|
onChange={handleBitWidthChange}
|
|
>
|
|
<MenuItem value={"a"}>Auto</MenuItem>
|
|
<MenuItem value={"8"}>8-bit</MenuItem>
|
|
<MenuItem value={"16"}>16-bit</MenuItem>
|
|
<MenuItem value={"32"}>32-bit</MenuItem>
|
|
</Select>
|
|
</FormControl>
|
|
<FormControl>
|
|
<InputLabel id="demo-simple-select-label">Sign</InputLabel>
|
|
<Select
|
|
sx={{width: 150}}
|
|
labelId="demo-simple-select-label"
|
|
id="demo-simple-select"
|
|
label="Sign"
|
|
value={signSelection}
|
|
onChange={handleSignChange}
|
|
>
|
|
<MenuItem value={"a"}>Auto</MenuItem>
|
|
<MenuItem value={"s"}>Signed</MenuItem>
|
|
<MenuItem value={"u"}>Unsigned</MenuItem>
|
|
</Select>
|
|
</FormControl>
|
|
</Stack>
|
|
<b>JUNGFRAU specific</b>
|
|
<FormGroup>
|
|
<FormControlLabel control={
|
|
<Checkbox checked={s.jungfrau_mask_pixels_without_g0}
|
|
onChange={
|
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
setS(prev => ({...prev, jungfrau_mask_pixels_without_g0: event.target.checked}));
|
|
}}/>
|
|
} label="Mask pixels not switching to G0"/>
|
|
<FormControlLabel control={
|
|
<Checkbox checked={s.jungfrau_conversion}
|
|
onChange={
|
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
setJungfrauConversionFactorErr(false);
|
|
setS(prev => ({
|
|
...prev,
|
|
jungfrau_conversion: event.target.checked,
|
|
jungfrau_conversion_factor_keV: undefined
|
|
}));
|
|
}}/>
|
|
} label="Conversion to photons"/>
|
|
|
|
</FormGroup>
|
|
<List>
|
|
<Tooltip
|
|
title="JUNGFRAU conversion factor allows to get different unit than 1 photon count. If not provided incident_energy is used.">
|
|
<ListItem>
|
|
<Checkbox
|
|
checked={s.jungfrau_conversion_factor_keV !== undefined}
|
|
disabled={!s.jungfrau_conversion}
|
|
onChange={
|
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
setDownloadCounter(c => c + 1);
|
|
setJungfrauConversionFactorErr(false);
|
|
if (!event.target.checked)
|
|
setS(prev => ({...prev, jungfrau_conversion_factor_keV: undefined}));
|
|
else
|
|
setS(prev => ({...prev, jungfrau_conversion_factor_keV: jungfrauConversionFactorOld}));
|
|
}}
|
|
/>
|
|
<FormControl fullWidth>
|
|
<NumberTextField
|
|
start_val={s.jungfrau_conversion_factor_keV}
|
|
disabled={s.jungfrau_conversion_factor_keV === undefined}
|
|
label={"JUNGFRAU conversion factor"}
|
|
units={"keV"}
|
|
float={true}
|
|
min={0.001}
|
|
fullWidth
|
|
counter={downloadCounter}
|
|
callback={(val: number, err: boolean) => {
|
|
if (!err)
|
|
setJungfrauConversionFactorOld(val);
|
|
setJungfrauConversionFactorErr(err);
|
|
setS(prev => ({...prev, jungfrau_conversion_factor_keV: val}));
|
|
}}/>
|
|
</FormControl>
|
|
|
|
</ListItem>
|
|
</Tooltip>
|
|
</List>
|
|
<NumberTextField start_val={s.jungfrau_pedestal_g0_rms_limit}
|
|
label={"G0 max RMS"}
|
|
min={0}
|
|
default={100}
|
|
counter={downloadCounter}
|
|
callback={(val: number, _err: boolean) => {
|
|
setS(prev => ({...prev, jungfrau_pedestal_g0_rms_limit: val}));
|
|
}}
|
|
/>
|
|
|
|
</SettingsPanel>
|
|
);
|
|
}
|
|
|
|
export default memo(ImageFormatSettings);
|