From 012da633d1e47dc7dc8410806e837c12535f7709 Mon Sep 17 00:00:00 2001 From: tizayi Date: Thu, 11 Jul 2024 16:11:55 +0100 Subject: [PATCH 01/16] start working on logging --- src/calculations/numericRange.ts | 10 ++++------ src/calculations/qrange.ts | 30 +++++++++++++++++++++++++++--- src/dialogs/beamlineDialog.tsx | 2 ++ src/plot/Plotter.ts | 1 + src/plot/centrePlot.tsx | 6 ++++-- src/plot/plotUtils.ts | 15 ++------------- src/presets/presetManager.ts | 1 + src/utils/units.ts | 5 +++++ 8 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/calculations/numericRange.ts b/src/calculations/numericRange.ts index 1c570ea..f16ee1a 100644 --- a/src/calculations/numericRange.ts +++ b/src/calculations/numericRange.ts @@ -1,6 +1,5 @@ /** - * A class which represents a unitless numeric range - * by storing it's minimum and maximum numbers + * A class which represents a unitless numeric range. */ export default class NumericRange { min: number; @@ -19,8 +18,7 @@ export default class NumericRange { } /** - * Checks if the input is contained in this range. - * + * Checks if an input number is contained in this range. * @param value - Input number * @returns */ @@ -38,9 +36,9 @@ export default class NumericRange { } /** - * Finds the intersection of this range and the input range. + * Finds the intersection of this range and the input range. Or returns null * @param input input NumericRange - * @returns The intersection NumericRange or null + * @returns */ intersect(input: NumericRange | null): NumericRange | null { if (input === null) { diff --git a/src/calculations/qrange.ts b/src/calculations/qrange.ts index f5a6542..acaf203 100644 --- a/src/calculations/qrange.ts +++ b/src/calculations/qrange.ts @@ -9,6 +9,7 @@ import { AppDetector, } from "../utils/types"; import NumericRange from "./numericRange"; +import { formatLogMessage } from "../utils/units"; /** * Is returned from computeQrange if the full @@ -61,6 +62,9 @@ export function computeQrange( ); if (typeof initialPositionX === "number" || !("units" in initialPositionX)) { + console.error( + formatLogMessage( + "Units are wrong for either beamcentre x or clearance width")); return defaultReturn; } @@ -68,7 +72,11 @@ export function computeQrange( mathjs.multiply(clearanceHeight, mathjs.sin(beamProperties.angle)), beamcentreY, ); + if (typeof initialPositionY === "number" || !("units" in initialPositionY)) { + console.error( + formatLogMessage( + "Units are wrong for either beamcentre y or clearance width")); return defaultReturn; } @@ -90,7 +98,12 @@ export function computeQrange( detectorHeight.toSI().toNumber(), ); - if (t1 === null) return defaultReturn; + if (t1 === null){ + console.warn( + formatLogMessage("Ray does not intersect with detector") + ) + return defaultReturn; + } const cameraOk = cameraTube !== null && cameraTube.diameter.toSI().toNumber() != 0; @@ -104,7 +117,11 @@ export function computeQrange( t1 = t1.intersect(ray.getCircleIntersectionParameterRange(radius, centre)); } - if (t1 === null) return defaultReturn; + if (t1 === null) { + console.warn( + formatLogMessage("Ray does not intersect with camera tube") + ) + return defaultReturn;} // set up the min, max and qspace values const ptMin = ray.getPoint(t1.min); @@ -149,7 +166,14 @@ export function computeQrange( visibleQMax.length(), ); const fullQRange = new NumericRange(fullQMin.length(), fullQMax.length()); - + console.info( + formatLogMessage( + ` The visible q range is: ${visibleQRange.toString()}` + )) + console.info( + formatLogMessage( + ` The full q range is: ${fullQRange.toString()}` + )) return { ptMin, ptMax, visibleQRange, fullQRange }; } diff --git a/src/dialogs/beamlineDialog.tsx b/src/dialogs/beamlineDialog.tsx index 33c842a..67e5605 100644 --- a/src/dialogs/beamlineDialog.tsx +++ b/src/dialogs/beamlineDialog.tsx @@ -17,6 +17,7 @@ import { IOBeamline } from "../utils/types"; import { useBeamlineConfigStore } from "../data-entry/beamlineconfigStore"; import { createInternalBeamline } from "../presets/presetManager"; import { SubmitHandler, useForm } from "react-hook-form"; +import { formatLogMessage } from "../utils/units"; const INPUT_PRECISION = 0.000001; @@ -37,6 +38,7 @@ export default function PresetDialog(props: { data.name, createInternalBeamline(data.beamline), ); + console.info(formatLogMessage(`New detector created : ${data.name} `)); console.log(data); props.handleClose(); reset(); diff --git a/src/plot/Plotter.ts b/src/plot/Plotter.ts index 27f1371..1c55eda 100644 --- a/src/plot/Plotter.ts +++ b/src/plot/Plotter.ts @@ -50,6 +50,7 @@ export class Plotter { if (!this.scaleFactor) { throw TypeError("reciprocal units need a scaleFactor"); } + const newcentre = Plotter.convert2QSpace( centre, this.scaleFactor, diff --git a/src/plot/centrePlot.tsx b/src/plot/centrePlot.tsx index 93befff..431fd28 100644 --- a/src/plot/centrePlot.tsx +++ b/src/plot/centrePlot.tsx @@ -40,6 +40,7 @@ import { usePlotStore } from "./plotStore"; import { UnitVector, color2String, getDomains } from "./plotUtils"; import SvgAxisAlignedEllipse from "./svgEllipse"; import { useMemo } from "react"; +import { formatLogMessage } from "../utils/units"; /** * A react componenet that plots the items that make up the system @@ -59,6 +60,7 @@ export default function CentrePlot(): JSX.Element { ); const { ptMin, ptMax, visibleQRange, fullQRange } = useMemo(() => { + console.info(formatLogMessage("Calculating Q range")); // todo this might need to be moved elsewhere /* eslint-disable */ // @ts-ignore @@ -105,7 +107,7 @@ export default function CentrePlot(): JSX.Element { visibleQRange, "m^-1", ).to("nm^-1"); - console.log(visibleQRange); + const fullQRangeUnits = UnitRange.fromNumericRange(fullQRange, "m^-1").to( "nm^-1", ); @@ -165,7 +167,7 @@ export default function CentrePlot(): JSX.Element { } const domains = getDomains(plotDetector); - + console.info(formatLogMessage("Refreshing plot")) return ( diff --git a/src/plot/plotUtils.ts b/src/plot/plotUtils.ts index ef96d94..3ac0645 100644 --- a/src/plot/plotUtils.ts +++ b/src/plot/plotUtils.ts @@ -6,20 +6,9 @@ import NumericRange from "../calculations/numericRange"; export const getDomains = ( detector: PlotRectangle, ): { xAxis: NumericRange; yAxis: NumericRange } => { - const maxAxis = - detector.upperBound.x > detector.upperBound.y - ? detector.upperBound.x - : detector.upperBound.y; - - // todo suggestion - why not to use Math.max() or Math.min(). - // todo ctnd or the mathjs equivalent? - const minAxis = - detector.lowerBound.x < detector.lowerBound.y - ? detector.lowerBound.x - : detector.lowerBound.y; - + const maxAxis = Math.max(detector.upperBound.x, detector.upperBound.y) + const minAxis = Math.min(detector.lowerBound.x,detector.lowerBound.y) const offset = 0.2 * (maxAxis - minAxis); - const min = Math.round(minAxis - offset); const max = Math.round(maxAxis + offset); const range = new NumericRange(min, max); diff --git a/src/presets/presetManager.ts b/src/presets/presetManager.ts index ee38780..f3ba4a5 100644 --- a/src/presets/presetManager.ts +++ b/src/presets/presetManager.ts @@ -11,6 +11,7 @@ import { IOPresetConfig, } from "../utils/types"; + /** * Creates an internal detector with pixel size units from an IODetector * @param detectorData IOdetector input diff --git a/src/utils/units.ts b/src/utils/units.ts index 48a7f15..8fcada7 100644 --- a/src/utils/units.ts +++ b/src/utils/units.ts @@ -100,3 +100,8 @@ export const enforceRangeLimits = ( if (value < min) return min; return value; }; + +export function formatLogMessage(message: string): string{ + const timestamp = new Date().toISOString(); + return `[${timestamp}] ${message}` +} \ No newline at end of file From 9cdd17953328c7f547808cbf2f6bbb6e37525486 Mon Sep 17 00:00:00 2001 From: tizayi Date: Thu, 15 Aug 2024 17:16:17 +0100 Subject: [PATCH 02/16] working mask stripes --- package-lock.json | 60 ++++++++-------- package.json | 2 +- src/app.tsx | 16 ++++- src/plot/centrePlot.tsx | 16 ++++- src/plot/svgMask.tsx | 105 ++++++++++++++++++++++++++++ src/results/rangeTable.tsx | 16 ++--- src/results/resultsBar.tsx | 6 +- src/results/resultsStore.ts | 9 +-- src/results/scatteringQuantities.ts | 16 ++--- 9 files changed, 186 insertions(+), 60 deletions(-) create mode 100644 src/plot/svgMask.tsx diff --git a/package-lock.json b/package-lock.json index 43b2eff..426ef98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@h5web/lib": "^11.2.0", + "@h5web/lib": "^12.0.1", "@mui/icons-material": "^5.15.3", "@mui/material": "^5.14.17", "@mui/system": "^5.15.9", @@ -800,6 +800,20 @@ "@floating-ui/utils": "^0.2.0" } }, + "node_modules/@floating-ui/react": { + "version": "0.26.14", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.14.tgz", + "integrity": "sha512-I2EhfezC+H0WfkMEkCcF9+++PU1Wq08bDKhHHGIoBZVCciiftEQHgrSI4dTUTsa7446SiIVW0gWATliIlVNgfg==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@floating-ui/utils": "^0.2.0", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@floating-ui/react-dom": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", @@ -818,10 +832,11 @@ "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, "node_modules/@h5web/lib": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@h5web/lib/-/lib-11.2.0.tgz", - "integrity": "sha512-itB2zy/cv+tn55ydUk4zqc5/2aVL8984v98rClxrwxj10JIRlLKFz+g0RSDyAqhWUOjONcAG7Ud1kX9byX0WsQ==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@h5web/lib/-/lib-12.0.1.tgz", + "integrity": "sha512-HuJJjsgxkWn6rPAX0W4tMJSMNh6xYLHw9YZqraAo2t8Gk5Xcddh0Pnd1ilJNss3LHu+vz2ASich5NUHxV01MOA==", "dependencies": { + "@floating-ui/react": "0.26.14", "@react-hookz/web": "24.0.4", "@visx/axis": "3.10.1", "@visx/drag": "3.3.0", @@ -837,8 +852,7 @@ "d3-scale-chromatic": "3.1.0", "ndarray": "1.0.19", "ndarray-ops": "1.2.2", - "react-aria-menubutton": "7.0.3", - "react-icons": "5.0.1", + "react-icons": "5.2.1", "react-keyed-flatten-children": "3.0.0", "react-measure": "2.5.2", "react-slider": "2.0.4", @@ -4422,11 +4436,6 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, - "node_modules/focus-group": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/focus-group/-/focus-group-0.3.1.tgz", - "integrity": "sha512-IA01dzk2cStQso/qnt2rWhXCFBZlBfjZmohB9mXUx9feEaJcORAK0FQGvwaApsNNGwzEnqrp/2qTR4lq8PXfnQ==" - }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -6733,19 +6742,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-aria-menubutton": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/react-aria-menubutton/-/react-aria-menubutton-7.0.3.tgz", - "integrity": "sha512-Ql4W3rNiZmuVJ1wQ0UUeV4OZX3IZq2evsfEqJGefSMdfkK6o8X/6Ufxrzu0wL+/Dr7JUY3xnrnIQimSCFghlCQ==", - "dependencies": { - "focus-group": "^0.3.1", - "prop-types": "^15.6.0", - "teeny-tap": "^0.2.0" - }, - "peerDependencies": { - "react": "^16.3.0 || ^17.0.0" - } - }, "node_modules/react-color": { "version": "2.19.3", "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", @@ -6791,9 +6787,9 @@ } }, "node_modules/react-icons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz", - "integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", + "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", "peerDependencies": { "react": "*" } @@ -7789,10 +7785,10 @@ "react": ">=17.0" } }, - "node_modules/teeny-tap": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/teeny-tap/-/teeny-tap-0.2.0.tgz", - "integrity": "sha512-HnA3I2sxRQe/SZgQTQgQvvA17DhfzhBJ1LfSOXZ5VUTbxGLvnAqUef84ZGNNSEbk1ZMEIDeghTHZagJ7LifAgg==" + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" }, "node_modules/text-table": { "version": "0.2.0", @@ -8060,7 +8056,7 @@ "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "devOptional": true, + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 0b6944d..2e110f4 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@h5web/lib": "^11.2.0", + "@h5web/lib": "^12.0.1", "@mui/icons-material": "^5.15.3", "@mui/material": "^5.14.17", "@mui/system": "^5.15.9", diff --git a/src/app.tsx b/src/app.tsx index 6398410..a5a29e5 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,14 +1,27 @@ -import { Stack} from "@mui/material"; +import { Stack, ThemeProvider, createTheme } from "@mui/material"; import DataSideBar from "./data-entry/dataSideBar"; import CentrePlot from "./plot/centrePlot"; import BasicAppBar from "./basicAppBar"; import CssBaseline from '@mui/material/CssBaseline'; +const theme = createTheme({ + breakpoints: { + values: { + xs: 0, + sm: 600, + md: 900, + lg: 1500, + xl: 1536, + }, + }, +}); + export default function App(): JSX.Element { return ( <> + + ); diff --git a/src/plot/centrePlot.tsx b/src/plot/centrePlot.tsx index 431fd28..fe4e4ae 100644 --- a/src/plot/centrePlot.tsx +++ b/src/plot/centrePlot.tsx @@ -25,7 +25,7 @@ import { } from "../results/resultsStore"; import { convertBetweenQAndD, - convertBetweenQAndS, + convertFromQTooS, } from "../results/scatteringQuantities"; import { AppBeamline, @@ -41,6 +41,7 @@ import { UnitVector, color2String, getDomains } from "./plotUtils"; import SvgAxisAlignedEllipse from "./svgEllipse"; import { useMemo } from "react"; import { formatLogMessage } from "../utils/units"; +import SvgMask from "./svgMask"; /** * A react componenet that plots the items that make up the system @@ -171,7 +172,7 @@ export default function CentrePlot(): JSX.Element { return ( - +
)} + {plotConfig.detector && ( + + )} {plotConfig.inaccessibleRange && ( UnitRange | null { result = convertBetweenQAndD(unit(value, state.dUnits)); break; case ScatteringOptions.s: - result = convertBetweenQAndS(unit(value, state.sUnits)); + result = convertFromQTooS(unit(value, state.sUnits)); break; default: result = unit(value, state.qUnits); diff --git a/src/plot/svgMask.tsx b/src/plot/svgMask.tsx new file mode 100644 index 0000000..75c65cb --- /dev/null +++ b/src/plot/svgMask.tsx @@ -0,0 +1,105 @@ +import { SvgRect } from '@h5web/lib'; +import type { SVGProps } from 'react'; +import { Vector3 } from 'three'; + +type Rect = [Vector3, Vector3]; + +interface Props extends SVGProps { + coords: Rect; + strokePosition?: 'inside' | 'outside'; + strokeWidth?: number; + numModules: Vector3, + gapFraction: Vector3, + missingSegments: number[] +} + +function SvgMask(props: Props){ + // watch out some crazy insane big boy maths is incoming + const [detectorUpper, detectorLower] = props.coords; + // check if clone is needed later on + const fulllength = detectorLower.clone().sub(detectorUpper); + const gaplength = fulllength.clone().multiply(props.gapFraction); + const moduleLength = + fulllength.clone() + .sub(gaplength.clone() + .multiply(props.numModules)) + .divide(props.numModules); + + return ( + <> + {/* plot vertical stripes */} + {[...Array(props.numModules.x -1).keys()].map((i:number) => + ) + } + {/* plot horizontal stripes */} + {[...Array(props.numModules.y -1).keys()].map((i:number) => + ) + } + + ) +} + +export type {Props as SvgMaskProps}; +export default SvgMask; + + + +function generateLowerBound( + moduleLen: number, gapLen:number, moduleNum: number): number{ + return moduleNum*moduleLen + (moduleNum-1)*gapLen +} + +function generateUpperBound( + moduleLen: number, gapLen:number, moduleNum: number): number{ + return moduleNum*moduleLen + moduleNum*gapLen +} + +function generateVerticalStripes( + coords: Rect, + moduleLenX: number, + gapLenX: number, + moduleNum: number): Rect{ + return [ + new Vector3( + coords[0].x + generateLowerBound(moduleLenX, gapLenX, moduleNum), + coords[0].y), + new Vector3( + coords[0].x + generateUpperBound(moduleLenX, gapLenX, moduleNum), + coords[1].y) + ] +} + +function generateHorizontalStripes( + coords: Rect, + moduleLenY: number, + gapLenY: number, + moduleNum: number): Rect{ + return [ + new Vector3(coords[0].x, + coords[0].y + generateLowerBound(moduleLenY, gapLenY, moduleNum)), + new Vector3(coords[1].x, + coords[0].y + generateUpperBound(moduleLenY, gapLenY, moduleNum)) + ] +} \ No newline at end of file diff --git a/src/results/rangeTable.tsx b/src/results/rangeTable.tsx index af6332b..9d3b780 100644 --- a/src/results/rangeTable.tsx +++ b/src/results/rangeTable.tsx @@ -15,7 +15,7 @@ import { ScatteringOptions, useResultStore } from "./resultsStore"; import { ReciprocalWavelengthUnits, WavelengthUnits } from "../utils/units"; import { convertBetweenQAndD, - convertBetweenQAndS, + convertFromQTooS, } from "./scatteringQuantities"; import UnitRange from "../calculations/unitRange"; @@ -31,8 +31,8 @@ export default function RangeTable(props: { qRange: UnitRange }): JSX.Element { updateQUnits(event.target.value as ReciprocalWavelengthUnits); }; - const handleSunits = (event: SelectChangeEvent) => { - updateSUnits(event.target.value as WavelengthUnits); + const handleSunits = (event: SelectChangeEvent) => { + updateSUnits(event.target.value as ReciprocalWavelengthUnits); }; const handleDunits = (event: SelectChangeEvent) => { @@ -40,7 +40,7 @@ export default function RangeTable(props: { qRange: UnitRange }): JSX.Element { }; const qRange = props.qRange.to(resultsStore.qUnits as string); const sRange = props.qRange - .apply(convertBetweenQAndS) + .apply(convertFromQTooS) .to(resultsStore.sUnits as string); const dRange = props.qRange .apply(convertBetweenQAndD) @@ -118,11 +118,11 @@ export default function RangeTable(props: { qRange: UnitRange }): JSX.Element { value={resultsStore.sUnits} onChange={handleSunits} > - - {WavelengthUnits.nanometres} + + {"1 / nm"} - - {"\u212B"} + + {"1 / " + "\u212B"} diff --git a/src/results/resultsBar.tsx b/src/results/resultsBar.tsx index 08a1ae4..2855b5d 100644 --- a/src/results/resultsBar.tsx +++ b/src/results/resultsBar.tsx @@ -25,7 +25,7 @@ import RangeTable from "./rangeTable"; import { ResultStore, ScatteringOptions, useResultStore } from "./resultsStore"; import { convertBetweenQAndD, - convertBetweenQAndS, + convertFromSTooQ, } from "./scatteringQuantities"; function getVisibilitySettings( @@ -55,8 +55,8 @@ function getVisibilitySettings( textBoxUnits = resultStore.dUnits; break; case ScatteringOptions.s: - diagramVisible = visableQRange.apply(convertBetweenQAndS).to("nm"); - diagramFull = fullQrange.apply(convertBetweenQAndS).to("nm"); + diagramVisible = visableQRange.apply(convertFromSTooQ).to("nm"); + diagramFull = fullQrange.apply(convertFromSTooQ).to("nm"); diagramRequested = UnitRange.fromNumericRange( requestedRange, resultStore.sUnits as string, diff --git a/src/results/resultsStore.ts b/src/results/resultsStore.ts index e8c3411..4cfecb1 100644 --- a/src/results/resultsStore.ts +++ b/src/results/resultsStore.ts @@ -12,7 +12,7 @@ export enum ScatteringOptions { export interface ResultStore { requested: ScatteringOptions; qUnits: ReciprocalWavelengthUnits; - sUnits: WavelengthUnits; + sUnits: ReciprocalWavelengthUnits; dUnits: WavelengthUnits; requestedMin: number | null; requestedMax: number | null; @@ -24,7 +24,7 @@ export interface ResultStore { }>, ) => void; updateQUnits: (newunits: ReciprocalWavelengthUnits) => void; - updateSUnits: (newunits: WavelengthUnits) => void; + updateSUnits: (newunits: ReciprocalWavelengthUnits) => void; updateDUnits: (newunits: WavelengthUnits) => void; } @@ -34,7 +34,7 @@ export interface ResultStore { export const useResultStore = create((set) => ({ requested: ScatteringOptions.q, qUnits: ReciprocalWavelengthUnits.nanometres, - sUnits: WavelengthUnits.nanometres, + sUnits: ReciprocalWavelengthUnits.nanometres, dUnits: WavelengthUnits.nanometres, requestedMin: null, requestedMax: null, @@ -51,6 +51,7 @@ export const useResultStore = create((set) => ({ }, updateQUnits: (newunits: ReciprocalWavelengthUnits) => set({ qUnits: newunits }), - updateSUnits: (newunits: WavelengthUnits) => set({ sUnits: newunits }), + updateSUnits: (newunits: ReciprocalWavelengthUnits) => + set({ sUnits: newunits }), updateDUnits: (newunits: WavelengthUnits) => set({ dUnits: newunits }), })); diff --git a/src/results/scatteringQuantities.ts b/src/results/scatteringQuantities.ts index d460196..82a2a89 100644 --- a/src/results/scatteringQuantities.ts +++ b/src/results/scatteringQuantities.ts @@ -1,7 +1,7 @@ import { Unit, divide, multiply } from "mathjs"; -export const convertBetweenQAndS = (quantity: Unit): Unit => { - const result = divide(1, quantity); +export const convertFromQTooS = (quantity: Unit): Unit => { + const result = multiply(quantity, 2 * Math.PI); if (typeof result == "number" || !("units" in result)) { throw TypeError("name this error later "); } @@ -16,18 +16,18 @@ export const convertBetweenQAndD = (quantity: Unit): Unit => { return result; }; -export const convertFromDTooS = (quantity: Unit): Unit => { - const result = divide(quantity, 2 * Math.PI); +export const convertBetweenDandS = (quantity: Unit): Unit => { + const result = divide(4* Math.pow(Math.PI,2),quantity); if (typeof result == "number" || !("units" in result)) { throw TypeError(""); } return result; }; -export const convertFromStooD = (quantity: Unit): Unit => { - const result = multiply(quantity, 2 * Math.PI); +export const convertFromSTooQ = (quantity: Unit): Unit => { + const result = divide(quantity, 2 * Math.PI); if (typeof result == "number" || !("units" in result)) { - throw TypeError(""); + throw TypeError("name this error later "); } return result; -}; +} \ No newline at end of file From ffb94e8950efe87fdd2481cd5076daa1d5e3a1ce Mon Sep 17 00:00:00 2001 From: tizayi Date: Thu, 15 Aug 2024 17:20:53 +0100 Subject: [PATCH 03/16] correct offset --- src/plot/svgMask.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plot/svgMask.tsx b/src/plot/svgMask.tsx index 75c65cb..8948c21 100644 --- a/src/plot/svgMask.tsx +++ b/src/plot/svgMask.tsx @@ -22,7 +22,7 @@ function SvgMask(props: Props){ const moduleLength = fulllength.clone() .sub(gaplength.clone() - .multiply(props.numModules)) + .multiply(props.numModules.clone().subScalar(1))) .divide(props.numModules); return ( From 3df8d2e08b8ec4b8d5d416770b33e9e3aacaa0b6 Mon Sep 17 00:00:00 2001 From: tizayi Date: Fri, 16 Aug 2024 10:34:11 +0100 Subject: [PATCH 04/16] working missing sections --- package-lock.json | 2 +- src/plot/centrePlot.tsx | 2 +- src/plot/svgMask.tsx | 61 ++++++++++++++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 426ef98..02d7fbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8056,7 +8056,7 @@ "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/src/plot/centrePlot.tsx b/src/plot/centrePlot.tsx index fe4e4ae..538d5d3 100644 --- a/src/plot/centrePlot.tsx +++ b/src/plot/centrePlot.tsx @@ -254,7 +254,7 @@ export default function CentrePlot(): JSX.Element { coords={[detectorLower, detectorUpper]} fill={color2String(plotConfig.visibleColor)} numModules={new Vector3(3,4)} - gapFraction= {new Vector3(0.1,0.1)} + gapFraction= {new Vector3(0.01,0.01)} missingSegments={[6]} /> )} diff --git a/src/plot/svgMask.tsx b/src/plot/svgMask.tsx index 8948c21..5f4c359 100644 --- a/src/plot/svgMask.tsx +++ b/src/plot/svgMask.tsx @@ -14,7 +14,6 @@ interface Props extends SVGProps { } function SvgMask(props: Props){ - // watch out some crazy insane big boy maths is incoming const [detectorUpper, detectorLower] = props.coords; // check if clone is needed later on const fulllength = detectorLower.clone().sub(detectorUpper); @@ -39,24 +38,38 @@ function SvgMask(props: Props){ i+1) } fill={props.fill} - id="mask" />) } {/* plot horizontal stripes */} - {[...Array(props.numModules.y -1).keys()].map((i:number) => + {[...Array(props.numModules.y -1).keys()].map((item:number) => ) } + {/* plot missing sections*/} + { + props.missingSegments.map((item: number) => + + ) + } ) } @@ -80,13 +93,13 @@ function generateVerticalStripes( coords: Rect, moduleLenX: number, gapLenX: number, - moduleNum: number): Rect{ + idx: number): Rect{ return [ new Vector3( - coords[0].x + generateLowerBound(moduleLenX, gapLenX, moduleNum), + coords[0].x + generateLowerBound(moduleLenX, gapLenX, idx), coords[0].y), new Vector3( - coords[0].x + generateUpperBound(moduleLenX, gapLenX, moduleNum), + coords[0].x + generateUpperBound(moduleLenX, gapLenX, idx), coords[1].y) ] } @@ -95,11 +108,33 @@ function generateHorizontalStripes( coords: Rect, moduleLenY: number, gapLenY: number, - moduleNum: number): Rect{ + idx: number): Rect{ return [ new Vector3(coords[0].x, - coords[0].y + generateLowerBound(moduleLenY, gapLenY, moduleNum)), + coords[0].y + generateLowerBound(moduleLenY, gapLenY, idx)), new Vector3(coords[1].x, - coords[0].y + generateUpperBound(moduleLenY, gapLenY, moduleNum)) + coords[0].y + generateUpperBound(moduleLenY, gapLenY, idx)) ] -} \ No newline at end of file +} + +function generateMissingModule( + coords: Rect, + moduleNum: Vector3, + moduleLen: Vector3, + gapLen: Vector3, + idx: number): Rect{ + return [ + new Vector3( + coords[0].x + (moduleLen.x + gapLen.x) * + (idx % moduleNum.x), + coords[0].y + (moduleLen.y + gapLen.y) * + (Math.floor(idx / moduleNum.x)) + ), + new Vector3( + coords[0].x + (moduleLen.x + gapLen.x) * + (idx % moduleNum.x) + moduleLen.x, + coords[0].y + (moduleLen.y + gapLen.y) * + (Math.floor(idx / moduleNum.x)) + moduleLen.y + ) + ] + } \ No newline at end of file From 79f9c41bd20e8939baa82f431f61c0204d4a92f3 Mon Sep 17 00:00:00 2001 From: tizayi Date: Mon, 19 Aug 2024 13:10:04 +0100 Subject: [PATCH 05/16] add mask to dialog --- src/dialogs/detectorDialog.tsx | 81 +++++++++++++++++++++++++++++++++- src/plot/centrePlot.tsx | 18 +++++--- src/plot/legendBar.tsx | 31 +++++++++++++ src/plot/plotStore.ts | 4 ++ src/plot/svgMask.tsx | 1 - src/presets/detectors.json | 42 ++++++++++++++++++ src/presets/presetManager.ts | 7 +++ src/utils/types.ts | 2 + 8 files changed, 178 insertions(+), 8 deletions(-) diff --git a/src/dialogs/detectorDialog.tsx b/src/dialogs/detectorDialog.tsx index 70cf9c3..2247f54 100644 --- a/src/dialogs/detectorDialog.tsx +++ b/src/dialogs/detectorDialog.tsx @@ -14,8 +14,9 @@ import { useDetectorStore } from "../data-entry/detectorStore"; import DetectorTable from "./detectorTable"; import CloseIcon from "@mui/icons-material/Close"; import { IODetector } from "../utils/types"; -import { useForm, SubmitHandler } from "react-hook-form"; +import { useForm, SubmitHandler, Controller } from "react-hook-form"; import { createInternalDetector } from "../presets/presetManager"; +import Autocomplete from '@mui/material/Autocomplete'; interface DetectorForm { name: string; @@ -28,7 +29,8 @@ export default function DetectorDialog(props: { handleOpen: () => void; }): JSX.Element { const detectorStore = useDetectorStore(); - const { register, reset, handleSubmit } = useForm(); + const { register, + reset, handleSubmit, control} = useForm(); const onSubmit: SubmitHandler = (data: DetectorForm) => { detectorStore.addNewDetector( data.name, @@ -39,6 +41,7 @@ export default function DetectorDialog(props: { reset(); }; + return ( + Mask: + + + px + ), + }} + /> + px + ), + }} + /> + ( + `${option}`} + defaultValue={[]} + filterSelectedOptions + renderInput={(params) => ( + + )} + onChange={(_, data) => onChange(data)} + /> + )} + /> diff --git a/src/plot/centrePlot.tsx b/src/plot/centrePlot.tsx index 538d5d3..1e3643c 100644 --- a/src/plot/centrePlot.tsx +++ b/src/plot/centrePlot.tsx @@ -249,13 +249,21 @@ export default function CentrePlot(): JSX.Element { id="detector" /> )} - {plotConfig.detector && ( + {plotConfig.mask && ( )} {plotConfig.inaccessibleRange && ( diff --git a/src/plot/legendBar.tsx b/src/plot/legendBar.tsx index 92498c8..1adfb80 100644 --- a/src/plot/legendBar.tsx +++ b/src/plot/legendBar.tsx @@ -27,6 +27,7 @@ export default function LegendBar(): JSX.Element { Legend + {/* Detector */} } /> + {/* Camera Tube */} } /> + {/* Beamstop */} } /> + {/* Clearance */} } /> + {/* Visible Range */} } /> + {/* Requested Range */} } /> + {/* Inaccessible Range */} } /> + {/* Mask */} + + plotConfig.update({ mask: checked }) + } + /> + } + label={ + + + plotConfig.update({ maskColor: color.rgb }) + } + /> + + Mask + + + } + /> Axes: diff --git a/src/plot/plotStore.ts b/src/plot/plotStore.ts index e4ed3d9..7d04994 100644 --- a/src/plot/plotStore.ts +++ b/src/plot/plotStore.ts @@ -10,6 +10,8 @@ export enum PlotAxes { export interface PlotConfig { detector: boolean; detectorColor: RGBColor; + mask: boolean; + maskColor: RGBColor; beamstop: boolean; beamstopColor: RGBColor; cameraTube: boolean; @@ -29,6 +31,8 @@ export interface PlotConfig { export const usePlotStore = create((set) => ({ detector: true, detectorColor: { r: 144, g: 19, b: 254, a: 0.4 }, + mask: false, + maskColor: { r: 0, g: 0, b: 0, a: 1 }, beamstop: true, beamstopColor: { r: 0, g: 0, b: 0, a: 1 }, cameraTube: true, diff --git a/src/plot/svgMask.tsx b/src/plot/svgMask.tsx index 5f4c359..bcb0115 100644 --- a/src/plot/svgMask.tsx +++ b/src/plot/svgMask.tsx @@ -78,7 +78,6 @@ export type {Props as SvgMaskProps}; export default SvgMask; - function generateLowerBound( moduleLen: number, gapLen:number, moduleNum: number): number{ return moduleNum*moduleLen + (moduleNum-1)*gapLen diff --git a/src/presets/detectors.json b/src/presets/detectors.json index 213f321..336e004 100644 --- a/src/presets/detectors.json +++ b/src/presets/detectors.json @@ -7,6 +7,13 @@ "pixelSize": { "width": 0.172, "height": 0.172 + }, + "mask": { + "horizontalModules": 3, + "verticalModules": 8, + "horizontalGap": 7, + "verticalGap": 17, + "missingModules":[] } }, "Pilatus P3-2M-DLS (for WAXS)": { @@ -17,6 +24,13 @@ "pixelSize": { "width": 0.172, "height": 0.172 + }, + "mask": { + "horizontalModules": 3, + "verticalModules": 8, + "horizontalGap": 7, + "verticalGap": 17, + "missingModules":[17,20,23] } }, "Pilatus6m": { @@ -27,6 +41,13 @@ "pixelSize": { "width": 0.172, "height": 0.172 + }, + "mask": { + "horizontalModules": 12, + "verticalModules": 5, + "horizontalGap": 17, + "verticalGap": 7, + "missingModules":[] } }, "Pilatus100k": { @@ -37,6 +58,13 @@ "pixelSize": { "width": 0.172, "height": 0.172 + }, + "mask": { + "horizontalModules": 3, + "verticalModules": 1, + "horizontalGap": 17, + "verticalGap": 0, + "missingModules":[] } }, "Pilatus300k-W":{ @@ -47,6 +75,13 @@ "pixelSize": { "width": 0.172, "height": 0.172 + }, + "mask": { + "horizontalModules": 1, + "verticalModules": 3, + "horizontalGap": 0, + "verticalGap": 7, + "missingModules":[] } }, "Eiger 500k": { @@ -57,6 +92,13 @@ "pixelSize": { "width": 7.5e-2, "height": 7.5e-2 + }, + "mask": { + "horizontalModules": 3, + "verticalModules": 8, + "horizontalGap": 7, + "verticalGap": 17, + "missingModules":[] } }, "Eiger 1M": { diff --git a/src/presets/presetManager.ts b/src/presets/presetManager.ts index f3ba4a5..fa57ece 100644 --- a/src/presets/presetManager.ts +++ b/src/presets/presetManager.ts @@ -19,6 +19,13 @@ import { */ export function createInternalDetector(detectorData: IODetector): AppDetector { return { + mask: { + horizontalModules: 1, + verticalModules: 1, + horizontalGap: 0, + verticalGap: 0, + missingModules: [] + }, ...detectorData, pixelSize: { height: unit(detectorData.pixelSize.height, "mm"), diff --git a/src/utils/types.ts b/src/utils/types.ts index d4af3e8..131c9d8 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -14,6 +14,7 @@ export interface SimpleVector2 { export interface AppDetector { readonly resolution: { height: number; width: number }; readonly pixelSize: { height: Unit; width: Unit }; + readonly mask: DetectorMask } /** @@ -63,6 +64,7 @@ export interface AppConfig { export interface IODetector { readonly resolution: { height: number; width: number }; readonly pixelSize: { height: number; width: number }; + readonly mask?: DetectorMask } /** From 099ae221301ba8eb26c199014150609f59668547 Mon Sep 17 00:00:00 2001 From: tizayi Date: Mon, 19 Aug 2024 16:08:20 +0100 Subject: [PATCH 06/16] ad mask to detector form --- src/dialogs/detectorDialog.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dialogs/detectorDialog.tsx b/src/dialogs/detectorDialog.tsx index 2247f54..626cab7 100644 --- a/src/dialogs/detectorDialog.tsx +++ b/src/dialogs/detectorDialog.tsx @@ -30,7 +30,7 @@ export default function DetectorDialog(props: { }): JSX.Element { const detectorStore = useDetectorStore(); const { register, - reset, handleSubmit, control} = useForm(); + reset, handleSubmit, control, getValues} = useForm(); const onSubmit: SubmitHandler = (data: DetectorForm) => { detectorStore.addNewDetector( data.name, @@ -185,7 +185,9 @@ export default function DetectorDialog(props: { `${option}`} defaultValue={[]} filterSelectedOptions From d43fec5e7133d53043c11a0021cc58e2057fb47b Mon Sep 17 00:00:00 2001 From: tizayi Date: Tue, 20 Aug 2024 11:18:36 +0100 Subject: [PATCH 07/16] remove misssing module --- src/dialogs/detectorDialog.tsx | 32 +++----------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/src/dialogs/detectorDialog.tsx b/src/dialogs/detectorDialog.tsx index 626cab7..7e9f852 100644 --- a/src/dialogs/detectorDialog.tsx +++ b/src/dialogs/detectorDialog.tsx @@ -14,9 +14,8 @@ import { useDetectorStore } from "../data-entry/detectorStore"; import DetectorTable from "./detectorTable"; import CloseIcon from "@mui/icons-material/Close"; import { IODetector } from "../utils/types"; -import { useForm, SubmitHandler, Controller } from "react-hook-form"; +import { useForm, SubmitHandler } from "react-hook-form"; import { createInternalDetector } from "../presets/presetManager"; -import Autocomplete from '@mui/material/Autocomplete'; interface DetectorForm { name: string; @@ -30,7 +29,7 @@ export default function DetectorDialog(props: { }): JSX.Element { const detectorStore = useDetectorStore(); const { register, - reset, handleSubmit, control, getValues} = useForm(); + reset, handleSubmit, setValue} = useForm(); const onSubmit: SubmitHandler = (data: DetectorForm) => { detectorStore.addNewDetector( data.name, @@ -40,7 +39,7 @@ export default function DetectorDialog(props: { props.handleClose(); reset(); }; - + setValue("detector.mask.missingModules", []) return ( - ( - `${option}`} - defaultValue={[]} - filterSelectedOptions - renderInput={(params) => ( - - )} - onChange={(_, data) => onChange(data)} - /> - )} - /> From 356268516b9e1626d563360fe25fdfdd28e769d6 Mon Sep 17 00:00:00 2001 From: tizayi Date: Tue, 20 Aug 2024 11:20:21 +0100 Subject: [PATCH 08/16] line too long --- src/results/rangeTable.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/results/rangeTable.tsx b/src/results/rangeTable.tsx index 9d3b780..daec687 100644 --- a/src/results/rangeTable.tsx +++ b/src/results/rangeTable.tsx @@ -31,7 +31,8 @@ export default function RangeTable(props: { qRange: UnitRange }): JSX.Element { updateQUnits(event.target.value as ReciprocalWavelengthUnits); }; - const handleSunits = (event: SelectChangeEvent) => { + const handleSunits = ( + event: SelectChangeEvent) => { updateSUnits(event.target.value as ReciprocalWavelengthUnits); }; From e74d80b210a1ef97d3a60207c59ad80653b0fcf7 Mon Sep 17 00:00:00 2001 From: tizayi Date: Thu, 29 Aug 2024 09:46:11 +0100 Subject: [PATCH 09/16] fix bug with requested s --- src/dialogs/detectorDialog.tsx | 4 +- src/plot/centrePlot.tsx | 22 +++++----- src/results/resultsBar.tsx | 73 +++++++++++++++++++--------------- src/results/resultsStore.ts | 2 - 4 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/dialogs/detectorDialog.tsx b/src/dialogs/detectorDialog.tsx index 7e9f852..56b65d1 100644 --- a/src/dialogs/detectorDialog.tsx +++ b/src/dialogs/detectorDialog.tsx @@ -57,12 +57,12 @@ export default function DetectorDialog(props: { - + - + Add new Detector: UnitRange | null { } const getUnit = (value: number): Unit => { - let result: Unit; - switch (state.requested) { - case ScatteringOptions.d: - result = convertBetweenQAndD(unit(value, state.dUnits)); - break; - case ScatteringOptions.s: - result = convertFromQTooS(unit(value, state.sUnits)); - break; - default: - result = unit(value, state.qUnits); + + if(state.requested === ScatteringOptions.d){ + return convertBetweenQAndD(unit(value, state.dUnits)); + } + + if(state.requested === ScatteringOptions.s){ + return convertFromSTooQ(unit(value, state.sUnits)); } - return result; + + return unit(value, state.qUnits); }; return new UnitRange( diff --git a/src/results/resultsBar.tsx b/src/results/resultsBar.tsx index 2855b5d..051dffb 100644 --- a/src/results/resultsBar.tsx +++ b/src/results/resultsBar.tsx @@ -25,54 +25,63 @@ import RangeTable from "./rangeTable"; import { ResultStore, ScatteringOptions, useResultStore } from "./resultsStore"; import { convertBetweenQAndD, - convertFromSTooQ, + convertFromQTooS, } from "./scatteringQuantities"; +interface VisibilitySettings { + textBoxUnits: WavelengthUnits | ReciprocalWavelengthUnits | null, + diagramVisible: UnitRange | null, + diagramFull: UnitRange | null, + diagramRequested: UnitRange | null, +} + function getVisibilitySettings( visableQRange: UnitRange, fullQrange: UnitRange, requestedRange: NumericRange | null, resultStore: ResultStore, -) { - let diagramVisible: UnitRange | null = null; - let diagramFull: UnitRange | null = null; - let diagramRequested: UnitRange | null = null; +): VisibilitySettings { - let textBoxUnits: WavelengthUnits | ReciprocalWavelengthUnits | null = null; - // NOTE early return pattern , reduces nesting logic if (!(visableQRange && fullQrange && requestedRange)) { - return { textBoxUnits, diagramVisible, diagramFull, diagramRequested }; + return { + textBoxUnits: null, + diagramVisible: null, + diagramFull: null, + diagramRequested: null}; } - switch (resultStore.requested) { - case ScatteringOptions.d: - diagramVisible = visableQRange.apply(convertBetweenQAndD).to("nm"); - diagramFull = fullQrange.apply(convertBetweenQAndD).to("nm"); - diagramRequested = UnitRange.fromNumericRange( + if(resultStore.requested === ScatteringOptions.d){ + return { + textBoxUnits: resultStore.dUnits, + diagramVisible: visableQRange.apply(convertBetweenQAndD).to("nm"), + diagramFull: fullQrange.apply(convertBetweenQAndD).to("nm"), + diagramRequested: UnitRange.fromNumericRange( requestedRange, resultStore.dUnits as string, - ).to("nm"); - textBoxUnits = resultStore.dUnits; - break; - case ScatteringOptions.s: - diagramVisible = visableQRange.apply(convertFromSTooQ).to("nm"); - diagramFull = fullQrange.apply(convertFromSTooQ).to("nm"); - diagramRequested = UnitRange.fromNumericRange( + ).to("nm") + }; + } + + if(resultStore.requested === ScatteringOptions.s){ + return { + textBoxUnits :resultStore.sUnits, + diagramVisible:visableQRange.apply(convertFromQTooS).to("nm^-1"), + diagramFull: fullQrange.apply(convertFromQTooS).to("nm^-1"), + diagramRequested: UnitRange.fromNumericRange( requestedRange, resultStore.sUnits as string, - ).to("nm"); - textBoxUnits = resultStore.sUnits; - break; - default: - diagramVisible = visableQRange.to("nm^-1"); - diagramFull = fullQrange.to("nm^-1"); - diagramRequested = UnitRange.fromNumericRange( - requestedRange, - resultStore.qUnits as string, - ).to("nm^-1"); - textBoxUnits = resultStore.qUnits; + ).to("nm^-1") + } } - return { textBoxUnits, diagramVisible, diagramFull, diagramRequested }; + + return { + textBoxUnits:resultStore.qUnits, + diagramVisible:visableQRange.to("nm^-1"), + diagramFull: fullQrange.to("nm^-1") , + diagramRequested: UnitRange.fromNumericRange( + requestedRange, + resultStore.qUnits as string, + ).to("nm^-1")}; } function RangeFormControl({ resultStore }: { resultStore: ResultStore }) { diff --git a/src/results/resultsStore.ts b/src/results/resultsStore.ts index 4cfecb1..b2b1ac0 100644 --- a/src/results/resultsStore.ts +++ b/src/results/resultsStore.ts @@ -1,8 +1,6 @@ import { create } from "zustand"; import { WavelengthUnits, ReciprocalWavelengthUnits } from "../utils/units"; -export const theta = "\u03B8"; - export enum ScatteringOptions { q = "q", s = "s", From 810b17b65bb578ac02668eae8e9dceec1c3ef343 Mon Sep 17 00:00:00 2001 From: tizayi Date: Thu, 29 Aug 2024 09:54:04 +0100 Subject: [PATCH 10/16] add doc string for log message --- src/utils/units.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/utils/units.ts b/src/utils/units.ts index 8fcada7..741f8b7 100644 --- a/src/utils/units.ts +++ b/src/utils/units.ts @@ -101,7 +101,12 @@ export const enforceRangeLimits = ( return value; }; +/** + * Add timestamp to log message + * @param message + * @returns + */ export function formatLogMessage(message: string): string{ const timestamp = new Date().toISOString(); - return `[${timestamp}] ${message}` + return `[${timestamp}]: ${message}` } \ No newline at end of file From 7c1729ecb0b9cdd3594063035297dacaa2ffbc60 Mon Sep 17 00:00:00 2001 From: tizayi Date: Thu, 29 Aug 2024 16:32:21 +0100 Subject: [PATCH 11/16] using enums for unit names --- arkit.svg | 235 +++++++++++++------------- package-lock.json | 17 +- package.json | 1 + src/calculations/qvalue.ts | 5 +- src/data-entry/beamProperties.tsx | 4 +- src/data-entry/beamlineconfigStore.ts | 5 +- src/data-entry/beamstop.tsx | 7 +- src/data-entry/cameraTube.tsx | 8 +- src/data-entry/dataSideBar.tsx | 4 +- src/dialogs/beamlineDialog.tsx | 24 ++- src/plot/centrePlot.tsx | 25 +-- src/plot/svgMask.tsx | 8 +- src/presets/presetManager.ts | 28 +-- src/results/rangeTable.tsx | 19 ++- src/results/resultsBar.tsx | 36 ++-- src/results/scatteringQuantities.ts | 20 +-- src/utils/types.ts | 12 ++ src/utils/units.ts | 5 + 18 files changed, 271 insertions(+), 192 deletions(-) diff --git a/arkit.svg b/arkit.svg index 9a658c8..37650c7 100644 --- a/arkit.svg +++ b/arkit.svg @@ -1,116 +1,120 @@ -appbasicAppBarbeamlineconfigStorebeamlineDialogBeamlineTablebeamPropertiesbeamstopbeamstopStorecameraTubecameraTubeStorecentrePlotcolourPickerdataSideBardetectorDialogdetectorStoredetectorTablelegendBarmainMessageDiagramnumericRangeplotStorePlotterplotUtilspresetManagerqrangeqspaceqvaluerangeDiagramrangeTablerayresultsBarresultsStorescatteringQuantitiessvgEllipsetypesunitRangeunitsvite-env.dvite.config