Files
Jungfraujoch/frontend/src/components/DataCollection.tsx
T
2024-11-17 14:55:09 +01:00

199 lines
7.9 KiB
TypeScript

import React from 'react';
import Paper from '@mui/material/Paper';
import {Stack, TextField} from "@mui/material";
import NumberTextField from "./NumberTextField";
import {dataset_settings} from "../openapi";
import ButtonWithSnackbar from "./ButtonWithSnackbar";
type MyProps = {
frame_time_us: number
};
type MyState = {
s: dataset_settings,
beam_x_pxl_err: boolean,
beam_y_pxl_err: boolean,
detector_distance_mm_err: boolean,
incident_energy_kev_err: boolean,
images_per_trigger_err: boolean,
image_time_us_err: boolean,
image_time_us_mult_err: boolean,
ntrigger_err: boolean
};
class DataCollection extends React.Component<MyProps, MyState> {
state : MyState = {
s : {
beam_x_pxl: 0,
beam_y_pxl: 0,
detector_distance_mm: 100,
incident_energy_keV: 12.398,
images_per_trigger: 1,
image_time_us: this.props.frame_time_us,
ntrigger: 1
},
beam_x_pxl_err: false,
beam_y_pxl_err: false,
detector_distance_mm_err: false,
incident_energy_kev_err: false,
images_per_trigger_err: false,
image_time_us_err: false,
image_time_us_mult_err: false,
ntrigger_err: false
}
error() : boolean {
return this.state.beam_x_pxl_err
|| this.state.beam_y_pxl_err
|| this.state.detector_distance_mm_err
|| this.state.incident_energy_kev_err
|| this.state.image_time_us_err
|| this.state.images_per_trigger_err
|| this.state.ntrigger_err;
}
render() {
return <Paper style={{textAlign: 'center'}} sx={{ width: '100%'}}>
<br/>
<Stack spacing={5} sx={{
justifyContent: "center",
alignItems: "center",
}}>
<TextField label={"File prefix"}
variant="outlined"
onChange={
(event: React.ChangeEvent<HTMLInputElement>) => {
this.setState(prevState => ({
s: {...prevState.s, file_prefix: event.target.value}
}));
}
}
value={this.state.s.file_prefix}
sx={{width:"90%"}}
/>
<Stack direction="row" spacing={2} sx={{width: '90%'}}>
<NumberTextField
label={"Number of images per trigger"}
callback={(val: number, err: boolean) => {
this.setState(prevState => ({
s: {...prevState.s, images_per_trigger: val},
images_per_trigger_err: err
}
));
}}
min={1}
default={this.state.s.images_per_trigger}
/>
<NumberTextField
label={"Number of triggers"}
callback={(val: number, err: boolean) => {
this.setState(prevState => ({
s: {...prevState.s, ntrigger: val},
ntrigger_err: err
}
));
}}
min={1}
default={this.state.s.ntrigger}
/>
<NumberTextField
label={"Image time"}
callback={(val: number, err: boolean) => {
let image_time_us = Math.round(val * 1000.0);
// image_time_us_mult_err makes sense only if there is no non-sense condition
let image_time_us_mult_err = !err
&& (this.props.frame_time_us > 0)
&& (image_time_us % this.props.frame_time_us != 0);
this.setState(prevState => ({
s: {...prevState.s,
image_time_us: image_time_us
},
image_time_us_err: err,
image_time_us_mult_err: image_time_us_mult_err
}
));
}}
units={"ms"}
float={true}
min={this.props.frame_time_us / 1000.0}
default={(this.state.s.image_time_us ?? 500) / 1000.0}
/>
</Stack>
<Stack direction="row" spacing={2} sx={{width: '90%'}}>
<NumberTextField
label={"Beam X [pxl]"}
callback={(val: number, err: boolean) => {
this.setState(prevState => ({
s: {...prevState.s, beam_x_pxl: val},
beam_x_pxl_err: err
}
));
}}
units={"pxl"}
float={true}
default={this.state.s.beam_x_pxl}
/>
<NumberTextField
label={"Beam Y"}
callback={(val: number, err: boolean) => {
this.setState(prevState => ({
s: {...prevState.s, beam_y_pxl: val},
beam_y_pxl_err: err
}
));
}}
units={"pxl"}
float={true}
default={this.state.s.beam_y_pxl}
/>
<NumberTextField
label={"Detector distance"}
callback={(val: number, err: boolean) => {
this.setState(prevState => ({
s: {...prevState.s, detector_distance_mm: val},
detector_distance_mm_err: err
}
));
}}
units={"mm"}
min={0.1}
float={true}
default={this.state.s.detector_distance_mm}
/>
<NumberTextField
label={"Energy"}
callback={(val: number, err: boolean) => {
this.setState(prevState => ({
s: {...prevState.s, incident_energy_keV: val},
incident_energy_kev_err: err
}
));
}}
min={0.1}
max={500.0}
units={"keV"}
float={true}
default={this.state.s.incident_energy_keV}
/>
</Stack>
<div style={{color: "red"}}>
{this.state.image_time_us_mult_err ? <>Image time must be multiple of frame time ({this.props.frame_time_us} &micro;s)</> : <br/>}
</div>
<ButtonWithSnackbar
path={"/start"}
text={"start"}
disabled={this.error()}
input={JSON.stringify(this.state.s)}
color={"primary"}
/>
</Stack>
<br/>
</Paper>
}
}
export default DataCollection;