import {ChangeEvent, memo, useState} from 'react'; import Paper from '@mui/material/Paper'; import {Stack, TextField, Radio, RadioGroup, FormControlLabel, FormControl, Checkbox} from "@mui/material"; import NumberTextField from "./NumberTextField"; import {dataset_settings, grid_scan, rotation_axis} from "../client"; import ButtonWithSnackbar from "./ButtonWithSnackbar"; type MyProps = { frame_time_us: number }; function DataCollection({frame_time_us}: MyProps) { const [s, setS] = useState(() => ({ beam_x_pxl: 0, beam_y_pxl: 0, detector_distance_mm: 100, incident_energy_keV: 12.398, images_per_trigger: 1, image_time_us: frame_time_us, ntrigger: 1, images_per_file: 1000 })); const [goniometer, setGoniometer] = useState({ start: 0, step: 0.1, name: "omega", vector: [0,1,0] }); const [grid, setGrid] = useState({ n_fast: 10, step_x_um: 10.0, step_y_um: 10.0, vertical: false, snake: false }); const [beamXPxlErr, setBeamXPxlErr] = useState(false); const [beamYPxlErr, setBeamYPxlErr] = useState(false); const [detectorDistanceMmErr, setDetectorDistanceMmErr] = useState(false); const [incidentEnergyKevErr, setIncidentEnergyKevErr] = useState(false); const [imagesPerTriggerErr, setImagesPerTriggerErr] = useState(false); const [imageTimeUsErr, setImageTimeUsErr] = useState(false); const [ntriggerErr, setNtriggerErr] = useState(false); const [imagesPerFileErr, setImagesPerFileErr] = useState(false); const [mode, setMode] = useState<'still' | 'rotation' | 'grid'>('still'); const error = () : boolean => beamXPxlErr || beamYPxlErr || detectorDistanceMmErr || incidentEnergyKevErr || imageTimeUsErr || imagesPerTriggerErr || imagesPerFileErr || ntriggerErr; const getDatasetSettings = () : dataset_settings => { let d = {...s}; if (mode === 'rotation') d.goniometer = goniometer; else if (mode === 'grid') d.grid_scan = grid; return d; }; return
) => { setS(prev => ({...prev, file_prefix: event.target.value})); } } value={s.file_prefix} sx={{width:"90%"}} /> { setS(prev => ({...prev, images_per_trigger: val})); setImagesPerTriggerErr(err); }} min={1} default={s.images_per_trigger} /> { setS(prev => ({...prev, ntrigger: val})); setNtriggerErr(err); }} min={1} default={s.ntrigger} /> { let image_time_us = Math.round(val * 1000.0); setS(prev => ({...prev, image_time_us: image_time_us})); setImageTimeUsErr(err); }} units={"ms"} float={true} min={0.01} default={(s.image_time_us ?? 500) / 1000.0} /> { setS(prev => ({...prev, images_per_file: val})); setImagesPerFileErr(err); }} float={false} min={1} default={s.images_per_file} /> { setS(prev => ({...prev, beam_x_pxl: val})); setBeamXPxlErr(err); }} units={"pxl"} float={true} default={s.beam_x_pxl} /> { setS(prev => ({...prev, beam_y_pxl: val})); setBeamYPxlErr(err); }} units={"pxl"} float={true} default={s.beam_y_pxl} /> { setS(prev => ({...prev, detector_distance_mm: val})); setDetectorDistanceMmErr(err); }} units={"mm"} min={0.1} float={true} default={s.detector_distance_mm} /> { setS(prev => ({...prev, incident_energy_keV: val})); setIncidentEnergyKevErr(err); }} min={0.1} max={500.0} units={"keV"} float={true} default={s.incident_energy_keV} /> setMode(event.target.value as 'still' | 'rotation' | 'grid')}> } label="Still"/> } label="Rotation"/> } label="Grid scan"/> {mode === 'rotation' && ( setGoniometer(prev => ({...prev, start: val}))} units="°" float={true} default={goniometer.start} /> setGoniometer(prev => ({...prev, step: val}))} units="°" float={true} min={0.001} default={goniometer.step} /> setGoniometer(prev => ({...prev, name: e.target.value}))} /> )} {mode === 'grid' && ( setGrid(prev => ({...prev, n_fast: val}))} min={1} default={grid.n_fast} /> setGrid(prev => ({...prev, step_x_um: val}))} units="μm" float={true} default={grid.step_x_um} /> setGrid(prev => ({...prev, step_y_um: val}))} units="μm" float={true} default={grid.step_y_um} /> setGrid(prev => ({...prev, snake: e.target.checked}))} /> } label="Snake scan" /> setGrid(prev => ({...prev, vertical: e.target.checked}))} /> } label="Vertical scan" /> )}
} export default memo(DataCollection);