diff --git a/src/data-entry/beamProperties.tsx b/src/data-entry/beamProperties.tsx
index 4d2eff8..fb90f6b 100644
--- a/src/data-entry/beamProperties.tsx
+++ b/src/data-entry/beamProperties.tsx
@@ -139,9 +139,9 @@ export default function BeampropertiesDataEntry() {
value={beamlineConfig.cameraLength ?? ""}
InputProps={{
inputProps: {
- max: beamlineConfig.maxCameraLength,
- min: beamlineConfig.minCameraLength,
- step: beamlineConfig.cameraLengthStep,
+ max: beamlineConfig.maxCameraLength.toNumber(),
+ min: beamlineConfig.minCameraLength.toNumber(),
+ step: beamlineConfig.cameraLengthStep.toNumber(),
},
}}
onChange={handleCameraLength}
diff --git a/src/data-entry/dataSideBar.tsx b/src/data-entry/dataSideBar.tsx
index 5ec03a3..76d1a7b 100644
--- a/src/data-entry/dataSideBar.tsx
+++ b/src/data-entry/dataSideBar.tsx
@@ -67,7 +67,7 @@ export default function DataSideBar(): JSX.Element {
{DistanceUnits.millimetre} x {DistanceUnits.millimetre}
diff --git a/src/data-entry/detectorStore.ts b/src/data-entry/detectorStore.ts
index df51546..c3ca242 100644
--- a/src/data-entry/detectorStore.ts
+++ b/src/data-entry/detectorStore.ts
@@ -16,7 +16,7 @@ export const useDetectorStore = create((set) => ({
detectorList: detectorList,
updateDetector: (newDetector: string) =>
set((state) => ({
- current: state.detectorList[newDetector],
+ ...state.detectorList[newDetector],
name: newDetector,
})),
updatePixelUnits: (newUnits: DistanceUnits) =>
diff --git a/src/plot/centrePlot.tsx b/src/plot/centrePlot.tsx
index fa0a960..1978901 100644
--- a/src/plot/centrePlot.tsx
+++ b/src/plot/centrePlot.tsx
@@ -14,13 +14,10 @@ import { useDetectorStore } from "../data-entry/detectorStore";
import { useCameraTubeStore } from "../data-entry/cameraTubeStore";
import {
UnitVector,
- createPlotEllipse,
- createPlotEllipseClearance,
- createPlotRange,
- createPlotRectangle,
+ Plotter,
getDomains,
} from "./plotUtils";
-import { usePlotStore } from "./plotStore";
+import { PlotAxes, usePlotStore } from "./plotStore";
import {
BeamlineConfig,
Beamstop,
@@ -74,6 +71,15 @@ export default function CentrePlot(): JSX.Element {
return { centre: state.centre, diameter: state.diameter };
});
+
+ const scaleFactor: mathjs.Unit | null = null;
+ if (
+ beamlineConfig.cameraLength &&
+ beamlineConfig.wavelength
+ ) {
+ const scaleFactor = mathjs.divide(2e-12 * Math.PI, mathjs.multiply(mathjs.unit(beamlineConfig.cameraLength, "m"), beamlineConfig.wavelength));
+ }
+
// evil :( :( :( :()
/* eslint-disable */
if (mathjs.Unit.UNITS.xpixel) {
@@ -90,6 +96,7 @@ export default function CentrePlot(): JSX.Element {
mathjs.createUnit("xpixel", detector.pixelSize.width.toString());
mathjs.createUnit("ypixel", detector.pixelSize.height.toString());
+
const { ptMin, ptMax, visibleQRange, fullQRange } = computeQrange(
detector,
beamstop,
@@ -121,35 +128,31 @@ export default function CentrePlot(): JSX.Element {
y: mathjs.unit(cameraTube.centre.y ?? NaN, "ypixel")
}
- const plotBeamstop = createPlotEllipse(
+ const plotter = new Plotter(plotConfig.plotAxes, scaleFactor)
+
+ const plotBeamstop = plotter.createPlotEllipse(
beamstopCentre,
- beamstop.diameter,
- plotConfig.plotAxes,
+ beamstop.diameter
);
- const plotCameraTube = createPlotEllipse(
+ const plotCameraTube = plotter.createPlotEllipse(
cameraTubeCentre,
- cameraTube.diameter,
- plotConfig.plotAxes,
+ cameraTube.diameter
);
- const plotClearance = createPlotEllipseClearance(
+ const plotClearance = plotter.createPlotEllipseClearance(
beamstopCentre,
beamstop.diameter,
- beamstop.clearance ?? 0,
- plotConfig.plotAxes,
+ beamstop.clearance ?? 0
);
- const plotDetector = createPlotRectangle(
- new Vector3(0, 0),
+ const plotDetector = plotter.createPlotRectangle(
detector.resolution,
- plotConfig.plotAxes,
);
- const plotVisibleRange = createPlotRange(
+ const plotVisibleRange = plotter.createPlotRange(
minPoint,
maxPoint,
- plotConfig.plotAxes,
);
// I am up to here
@@ -180,13 +183,15 @@ export default function CentrePlot(): JSX.Element {
)
});
+
let plotRequestedRange = {
start: new Vector3(0, 0),
end: new Vector3(0, 0),
};
if (
requestedRange &&
- beamlineConfig.cameraLength
+ beamlineConfig.cameraLength &&
+ beamlineConfig.wavelength
) {
const requestedMaxPt = getPointForQ(
requestedRange.max,
@@ -202,13 +207,14 @@ export default function CentrePlot(): JSX.Element {
beamlineConfig.wavelength,
beamstopCentre,
);
- plotRequestedRange = createPlotRange(
+ plotRequestedRange = plotter.createPlotRange(
requestedMinPt,
- requestedMaxPt,
- plotConfig.plotAxes,
+ requestedMaxPt
);
}
+
+
const domains = getDomains(plotDetector, plotConfig.plotAxes);
return (
diff --git a/src/plot/plotStore.ts b/src/plot/plotStore.ts
index f21b6f9..2fa1213 100644
--- a/src/plot/plotStore.ts
+++ b/src/plot/plotStore.ts
@@ -4,7 +4,7 @@ import { create } from "zustand";
export enum PlotAxes {
milimeter = "mm",
pixel = "pixel",
- reciprocal = "reciprocal",
+ reciprocal = "mm^-1",
}
export interface PlotConfig {
@@ -34,13 +34,13 @@ export const usePlotStore = create((set) => ({
cameraTube: true,
cameraTubeColor: { r: 80, g: 227, b: 194, a: 0.4 },
visibleRange: true,
- visibleColor: { r: 208, g: 2, b: 27, a: 1 },
+ visibleColor: { r: 245, g: 166, b: 35, a: 1 },
requestedRange: true,
requestedRangeColor: { r: 65, g: 117, b: 5, a: 1 },
clearance: true,
clearanceColor: { r: 0, g: 0, b: 0, a: 0.2 },
- inaccessibleRange: false,
- inaccessibleRangeColor: { r: 245, g: 166, b: 35, a: 1 },
+ inaccessibleRange: true,
+ inaccessibleRangeColor: { r: 208, g: 2, b: 27, a: 1 },
plotAxes: PlotAxes.milimeter,
update: (newConfig) => {
set({ ...newConfig });
diff --git a/src/plot/plotUtils.ts b/src/plot/plotUtils.ts
index b70b028..a2bf64a 100644
--- a/src/plot/plotUtils.ts
+++ b/src/plot/plotUtils.ts
@@ -43,113 +43,98 @@ export interface UnitVector {
y: math.Unit
}
-export const createPlotEllipse = (
- centre: UnitVector,
- diameter: math.Unit,
- plotAxes: PlotAxes,
-): PlotEllipse => {
- let xunit = plotAxes as string;
- let yunit = plotAxes as string;
-
- if (plotAxes === PlotAxes.pixel) {
- xunit = "xpixel";
- yunit = "ypixel";
- }
-
- const centreVec = new Vector3(
- centre.x.to(xunit).toNumber(),
- centre.y.to(yunit).toNumber(),
- );
-
- return {
- centre: centreVec,
- endPointX: new Vector3(
- centreVec.x + mathjs.divide(diameter, 2).to(xunit).toNumber(),
- centreVec.y,
- ),
- endPointY: new Vector3(
- centreVec.x,
- centreVec.y + mathjs.divide(diameter, 2).to(yunit).toNumber(),
- ),
- };
-};
-
-export const createPlotEllipseClearance = (
- centre: UnitVector,
- diameter: math.Unit,
- clearance: number,
- plotAxes: PlotAxes,
-): PlotEllipse => {
- let xunit = plotAxes as string;
- let yunit = plotAxes as string;
-
- if (plotAxes === PlotAxes.pixel) {
- xunit = "xpixel";
- yunit = "ypixel";
- }
-
- const centreVec = new Vector3(
- centre.x.to(xunit).toNumber(),
- centre.y.to(yunit).toNumber(),
- );
-
- return {
- centre: centreVec,
- endPointX: new Vector3(
- centreVec.x + mathjs.divide(diameter, 2).to(xunit).toNumber() + mathjs.unit(clearance, "xpixel").to(xunit).toNumber(),
- centreVec.y,
- ),
- endPointY: new Vector3(
- centreVec.x,
- centreVec.y + mathjs.divide(diameter, 2).to(yunit).toNumber() + mathjs.unit(clearance, "ypixel").to(yunit).toNumber(),
- ),
- };
-};
-
export interface PlotRectangle {
upperBound: Vector3;
lowerBound: Vector3;
}
-export const createPlotRectangle = (
- pinnedCorner: Vector3,
- resolution: { height: number; width: number },
- plotAxes: PlotAxes,
-): PlotRectangle => {
- let xunit = plotAxes as string;
- let yunit = plotAxes as string;
- if (plotAxes === PlotAxes.pixel) {
- xunit = "xpixel";
- yunit = "ypixel";
- }
- return {
- lowerBound: pinnedCorner,
- upperBound: new Vector3(mathjs.unit(resolution.width, "xpixel").to(xunit).toNumber(), mathjs.unit(resolution.height, "ypixel").to(yunit).toNumber()),
- };
-};
-
export interface PlotRange {
start: Vector3;
end: Vector3;
}
-export const createPlotRange = (
- startPoint: UnitVector,
- endPoint: UnitVector,
- plotAxes: PlotAxes,
-): PlotRange => {
- let xunit = plotAxes as string;
- let yunit = plotAxes as string;
- if (plotAxes === PlotAxes.pixel) {
- xunit = "xpixel";
- yunit = "ypixel";
+export class Plotter {
+ plotAxes: PlotAxes;
+ private xunit: string;
+ private yunit: string;
+ private scaleFactor: mathjs.Unit | null;
+ constructor(plotAxes: PlotAxes, scaleFactor: mathjs.Unit | null) {
+ this.xunit = plotAxes as string;
+ this.yunit = plotAxes as string;
+ this.plotAxes = plotAxes;
+ this.scaleFactor = scaleFactor;
+ if (plotAxes === PlotAxes.pixel) {
+ this.xunit = "xpixel";
+ this.yunit = "ypixel";
+ }
}
- return {
- start: new Vector3(startPoint.x.to(xunit).toNumber(), startPoint.y.to(yunit).toNumber()),
- end: new Vector3(endPoint.x.to(xunit).toNumber(), endPoint.y.to(yunit).toNumber()),
+ createPlotEllipse(
+ centre: UnitVector,
+ diameter: math.Unit,
+ ): PlotEllipse {
+ const centreVec = new Vector3(
+ centre.x.to(this.xunit).toNumber(),
+ centre.y.to(this.yunit).toNumber(),
+ );
+
+ return {
+ centre: centreVec,
+ endPointX: new Vector3(
+ centreVec.x + mathjs.divide(diameter, 2).to(this.xunit).toNumber(),
+ centreVec.y,
+ ),
+ endPointY: new Vector3(
+ centreVec.x,
+ centreVec.y + mathjs.divide(diameter, 2).to(this.yunit).toNumber(),
+ ),
+ };
+ };
+
+ createPlotEllipseClearance = (
+ centre: UnitVector,
+ diameter: math.Unit,
+ clearance: number,
+ ): PlotEllipse => {
+
+ const centreVec = new Vector3(
+ centre.x.to(this.xunit).toNumber(),
+ centre.y.to(this.yunit).toNumber(),
+ );
+
+ return {
+ centre: centreVec,
+ endPointX: new Vector3(
+ centreVec.x + mathjs.divide(diameter, 2).to(this.xunit).toNumber() + mathjs.unit(clearance, "xpixel").to(this.xunit).toNumber(),
+ centreVec.y,
+ ),
+ endPointY: new Vector3(
+ centreVec.x,
+ centreVec.y + mathjs.divide(diameter, 2).to(this.yunit).toNumber() + mathjs.unit(clearance, "ypixel").to(this.yunit).toNumber(),
+ ),
+ };
+ };
+
+ createPlotRectangle(
+ resolution: { height: number; width: number },
+ ): PlotRectangle {
+ return {
+ lowerBound: new Vector3(0, 0),
+ upperBound: new Vector3(mathjs.unit(resolution.width, "xpixel").to(this.xunit).toNumber(), mathjs.unit(resolution.height, "ypixel").to(this.yunit).toNumber()),
+ };
+ };
+
+ createPlotRange = (
+ startPoint: UnitVector,
+ endPoint: UnitVector,
+ ): PlotRange => {
+ return {
+ start: new Vector3(startPoint.x.to(this.xunit).toNumber(), startPoint.y.to(this.yunit).toNumber()),
+ end: new Vector3(endPoint.x.to(this.xunit).toNumber(), endPoint.y.to(this.yunit).toNumber()),
+ };
};
};
+
diff --git a/src/presets/presetConfigs.json b/src/presets/presetConfigs.json
index 1eeb0d9..b172cfb 100644
--- a/src/presets/presetConfigs.json
+++ b/src/presets/presetConfigs.json
@@ -16,7 +16,7 @@
},
"diameter": 310
},
- "angle": 1.57,
+ "angle": 90,
"wavelength": null,
"cameraLength": 1.9,
"minWavelength": 0.062,
@@ -42,13 +42,13 @@
},
"diameter": 310
},
- "angle": 1.57,
+ "angle": 90,
"wavelength": null,
"cameraLength": 1.9,
- "minWavelength": 6.2e-2,
+ "minWavelength": 0.062,
"maxWavelength": 0.335,
"minCameraLength": 1.9,
"maxCameraLength": 9.9,
"cameraLengthStep": 2
}
-}
+}
\ No newline at end of file
diff --git a/src/presets/presetManager.ts b/src/presets/presetManager.ts
index 1153972..5957827 100644
--- a/src/presets/presetManager.ts
+++ b/src/presets/presetManager.ts
@@ -81,7 +81,7 @@ export const presetList: Record = Object.fromEntries(
cameraLengthStep: mathjs.unit(value.cameraLengthStep, "m"),
wavelength: mathjs.unit(value.wavelength ?? NaN, "nm"),
- angle: mathjs.unit(value.angle ?? NaN, "rad"),
+ angle: mathjs.unit(value.angle ?? NaN, "deg"),
},
]),
);
diff --git a/src/results/rangeTable.tsx b/src/results/rangeTable.tsx
index 86792bc..9f5d078 100644
--- a/src/results/rangeTable.tsx
+++ b/src/results/rangeTable.tsx
@@ -66,10 +66,10 @@ export default function RangeTable(props: {
{ScatteringOptions.q}
- {qRange.min.toNumber().toFixed(4)}
+ {isNaN(qRange.min.toNumber()) ? "" : qRange.min.toNumber().toFixed(4)}
- {qRange.max.toNumber().toFixed(4)}
+ {isNaN(qRange.max.toNumber()) ? "" : qRange.max.toNumber().toFixed(4)}
@@ -95,10 +95,10 @@ export default function RangeTable(props: {
{ScatteringOptions.s}
- {sRange.min.toNumber().toFixed(4)}
+ {isNaN(sRange.min.toNumber()) ? "" : sRange.min.toNumber().toFixed(4)}
- {sRange.max.toNumber().toFixed(4)}
+ {isNaN(sRange.max.toNumber()) ? "" : sRange.max.toNumber().toFixed(4)}
@@ -124,10 +124,10 @@ export default function RangeTable(props: {
{ScatteringOptions.d}
- {dRange.min.toNumber().toFixed(4)}
+ {isNaN(dRange.min.toNumber()) ? "" : dRange.min.toNumber().toFixed(4)}
- {dRange.max.toNumber().toFixed(4)}
+ {isNaN(dRange.max.toNumber()) ? "" : dRange.max.toNumber().toFixed(4)}
diff --git a/src/utils/units.ts b/src/utils/units.ts
index 865ef87..2608909 100644
--- a/src/utils/units.ts
+++ b/src/utils/units.ts
@@ -48,7 +48,8 @@ export interface UnitConfig {
*/
export const energy2WavelengthConverter = (energy: math.Unit): math.Unit => {
const result = math.divide(math.multiply(PLANCK, CSPEED), energy.toSI());
- if (typeof result == "number") {
+
+ if (typeof result == "number" || !("units" in result)) {
throw TypeError("units for constants h and c are wrong");
}
return result;
@@ -63,7 +64,7 @@ export const wavelength2EnergyConverter = (
wavelength: math.Unit,
): math.Unit => {
const result = math.divide(math.multiply(PLANCK, CSPEED), wavelength.toSI());
- if (typeof result == "number") {
+ if (typeof result == "number" || !("units" in result)) {
throw TypeError("units for constants h and c are wrong");
}
return result;