Skip to content

Commit

Permalink
workinng on getting proper q ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
tizayi committed Sep 25, 2023
1 parent 60d8d74 commit ab63b15
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 82 deletions.
6 changes: 3 additions & 3 deletions src/calculations/qrange.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Detector,
} from "../utils/types";

test("Test getting q from pixel position ", () => {
test("Test computing q ranges", () => {
const detector: Detector = {
resolution: {
height: 1679,
Expand All @@ -19,7 +19,7 @@ test("Test getting q from pixel position ", () => {
},
};
const beamstop: Beamstop = {
centre: { x: 738, y: 100 },
centre: { x: 738, y: 840 },
diameter: 4,
clearance: 10,
};
Expand All @@ -30,7 +30,7 @@ test("Test getting q from pixel position ", () => {
maxWavelength: 0.335,
minCameraLength: 0,
maxCameraLength: 4,
wavelength: 2e-2,
wavelength: 9e-2,
};
const cameraTube: CircularDevice = {
centre: { x: 738, y: 840 },
Expand Down
77 changes: 48 additions & 29 deletions src/calculations/qrange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,72 @@ import {
CircularDevice,
Detector,
} from "../utils/types";
import { Vector3, Vector4 } from "three";
import { Vector2, Vector3, Vector4 } from "three";
import { Ray } from "../calculations/ray";
import NumericRange from "./numericRange";
/**
* Compute the viable and full qranges
* @param detector
* @param beamstop
* @param cameraTube
* @param beamProperties
* @returns
* Compute the viable and full qranges
* @param detector
* @param beamstop
* @param cameraTube
* @param beamProperties
* @returns
*/
export function computeQrange(
detector: Detector,
beamstop: Beamstop,
cameraTube: CircularDevice,
beamProperties: BeamlineConfig,
) {
const initialPosition = new Vector3(
beamstop.clearance ??
0 * Math.cos(beamProperties.angle ?? 0) + (beamstop.centre.y ?? 0),
beamstop.clearance ??
0 * Math.sin(beamProperties.angle ?? 0) + (beamstop.centre.y ?? 0),
): {
ptMin: Vector2;
ptMax: Vector2;
visibleQRange: NumericRange;
fullQRange: NumericRange;
} | null {
// convert pixel values to mm
const clearanceWidthMM = (beamstop.clearance ?? 0) * detector.pixelSize.width;
const clearaceHeightMM =
(beamstop.clearance ?? 0) * detector.pixelSize.height;

const beamcentreXMM = (beamstop.centre.x ?? 0) * detector.pixelSize.width;
const beamcentreYMM = (beamstop.centre.y ?? 0) * detector.pixelSize.height;

const detectorHeightMM =
detector.resolution.height * detector.pixelSize.height;
const detectorWidthMM = detector.resolution.width * detector.pixelSize.width;

const cameraTubeCentreXMM =
(cameraTube.centre.x ?? 0) * detector.pixelSize.width;
const cemeraTubeCentreYMM =
(cameraTube.centre.y ?? 0) * detector.pixelSize.height;

// intial position is wrong
const initialPosition = new Vector2(
clearanceWidthMM * Math.cos(beamProperties.angle ?? 0) + beamcentreXMM,
clearaceHeightMM * Math.sin(beamProperties.angle ?? 0) + beamcentreYMM,
);

const ray = new Ray(
new Vector3(
new Vector2(
Math.cos(beamProperties.angle ?? 0),
Math.sin(beamProperties.angle ?? 0),
),
initialPosition,
);
let t1 = ray.getRectangleIntersectionParameterRange(
new Vector3(0, detector.resolution.height),
detector.resolution.width,
detector.resolution.height,
new Vector2(0, detectorHeightMM),
detectorWidthMM,
detectorHeightMM,
);

console.log(t1)

if (t1 != null && cameraTube != null && cameraTube.diameter != 0) {
t1 = t1.intersect(
ray.getCircleIntersectionParameterRange(
(cameraTube.diameter ?? 0) / 2,
new Vector3(cameraTube.centre.x ?? 0, cameraTube.centre.y ?? 0),
new Vector2(cameraTubeCentreXMM, cemeraTubeCentreYMM),
),
);
}
console.log(t1);
if (
t1 === null ||
beamProperties.wavelength == null ||
Expand All @@ -69,8 +88,8 @@ export function computeQrange(
const detProps: DetectorProperties = {
...detector,
origin: new Vector3(
beamstop.centre.x ?? 0,
beamstop.centre.y ?? 0,
beamcentreXMM,
beamcentreYMM,
beamProperties.cameraLength * 1e-3,
),
beamVector: new Vector3(0, 0, 1),
Expand All @@ -85,11 +104,11 @@ export function computeQrange(
const qspace = new QSpace(detProps, diffCrystEnv, 2 * Math.PI);

// get visible range
const visibleQmin = qspace.qFromPixelPosition(
const visibleQMin = qspace.qFromPixelPosition(
ptMin.x / detector.pixelSize.width,
ptMin.y / detector.pixelSize.height,
);
const visibleQmax = qspace.qFromPixelPosition(
const visibleQMax = qspace.qFromPixelPosition(
ptMax.x / detector.pixelSize.width,
ptMax.y / detector.pixelSize.height,
);
Expand All @@ -115,9 +134,9 @@ export function computeQrange(
);

return {
visibleQmin: visibleQmin,
visibleQmax: visibleQmax,
fullQMax: fullQMax,
fullQMin: fullQMin,
ptMin: ptMin,
ptMax: ptMax,
visibleQRange: new NumericRange(visibleQMin.length(), visibleQMax.length()),
fullQRange: new NumericRange(fullQMin.length(), fullQMax.length()),
};
}
17 changes: 12 additions & 5 deletions src/calculations/ray.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { expect, test } from "vitest";
import { Ray } from "./ray";
import { Vector3 } from "three";
import { Vector2 } from "three";

test("Getting a point from a ray", () => {
const ray1 = new Ray(new Vector3(1, 1), new Vector3(1, 1));
const vector1 = ray1.getPoint(5);
const vector2 = new Vector3(6, 6);
expect(vector1.equals(vector2));
const ray1 = new Ray(new Vector2(1, 1), new Vector2(1, 1));
const vector_1 = ray1.getPoint(5);
const vector_2 = new Vector2(6, 6);
expect(vector_1.equals(vector_2));
});

test("Test get parameter range", () => {
const ray1 = new Ray(new Vector2(1, 1), new Vector2(1, 1));
const vector_1 = ray1.getPoint(5);
const vector_2 = new Vector2(6, 6);
expect(vector_1.equals(vector_2));
});
31 changes: 15 additions & 16 deletions src/calculations/ray.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Vector3 } from "three";
import { Vector2 } from "three";
import NumericRange from "./numericRange";

export class Ray {
direction: Vector3;
initial_point: Vector3;
constructor(direction: Vector3, initial_point: Vector3) {
direction: Vector2;
initial_point: Vector2;
constructor(direction: Vector2, initial_point: Vector2) {
if (direction.length() == 0)
throw TypeError(
"The direction vector of a ray cannot be the zero vector.",
Expand All @@ -13,18 +13,19 @@ export class Ray {
this.initial_point = initial_point;
}

getPoint(scalar: number): Vector3 {
const result = new Vector3(this.direction.x, this.direction.y);
getPoint(scalar: number): Vector2 {
const result = new Vector2(this.direction.x, this.direction.y);
result.multiplyScalar(scalar);
result.add(this.initial_point);
return result;
}

getPointAtDistance(distance: number): Vector3 {
getPointAtDistance(distance: number): Vector2 {
return this.getPoint(distance / this.direction.length());
}

getParameterRange(t1: number, t2: number): NumericRange {
// look at this again
let tMin = Math.min(t1, t2);
const tMax = Math.max(t1, t2);

Expand All @@ -48,7 +49,7 @@ export class Ray {
coeffOfx2 * Math.pow(this.direction.x, 2) +
coeffOfxy * this.direction.x * this.direction.y +
coeffOfy2 * Math.pow(this.direction.y, 2);

const b =
2 * coeffOfx2 * this.direction.x * this.initial_point.x +
coeffOfxy *
Expand All @@ -65,10 +66,9 @@ export class Ray {
coeffOfx * this.initial_point.x +
coeffOfy * this.initial_point.y +
constant;

console.log("stuff")

const discriminant = Math.pow(b, 2) - 4 * a * c;
console.log(discriminant)

if (discriminant < 0) return null;
if (a == 0) {
if (b == 0)
Expand All @@ -79,13 +79,14 @@ export class Ray {
t1 = (0.5 * (-b - Math.sqrt(discriminant))) / a;
t2 = (0.5 * (-b + Math.sqrt(discriminant))) / a;
}

return this.getParameterRange(t1, t2);
}

private getEllipseIntersectionParameterRange(
a: number,
b: number,
centre: Vector3,
centre: Vector2,
) {
const coeffOfx2 = 1 / Math.pow(a, 2);
const coeffOfy2 = 1 / Math.pow(b, 2);
Expand All @@ -106,17 +107,16 @@ export class Ray {
);
}

public getCircleIntersectionParameterRange(radius: number, centre: Vector3) {
public getCircleIntersectionParameterRange(radius: number, centre: Vector2) {
return this.getEllipseIntersectionParameterRange(radius, radius, centre);
}

public getRectangleIntersectionParameterRange(
topLeftCorner: Vector3,
topLeftCorner: Vector2,
width: number,
height: number,
): NumericRange | null {
let result: NumericRange | null;

const xmax = topLeftCorner.x + width;
const xmin = topLeftCorner.x;
const ymax = topLeftCorner.y;
Expand All @@ -137,7 +137,6 @@ export class Ray {
return null;
return this.getParameterRange(result.min, result.max);
}

result = result.intersect(
new NumericRange(
(ymin - this.initial_point.y) / this.direction.y,
Expand Down
41 changes: 12 additions & 29 deletions src/plot/centrePlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ import {
SvgRect,
SvgLine,
} from "@h5web/lib";
import { Vector3 } from "three";
import { Vector2, Vector3 } from "three";
import { useBeamstopStore } from "../data-entry/beamstopStore";
import { useDetectorStore } from "../data-entry/detectorStore";
import { useCameraTubeStore } from "../data-entry/cameraTubeStore";
import { getDomains } from "./plotUtils";
import { PlotAxes, usePlotStore } from "./plotStore";
import { Beamstop, CircularDevice, Detector } from "../utils/types";
import { computeQrange } from "../calculations/qrange";
import { useBeamlineConfigStore } from "../data-entry/beamlineconfigStore";

export default function CentrePlot(): JSX.Element {
const plotConfig = usePlotStore();
const bealineConfig = useBeamlineConfigStore();
const detector = useDetectorStore((state): Detector => {
if (plotConfig.plotAxes === PlotAxes.milimeter) {
return {
Expand Down Expand Up @@ -70,32 +73,12 @@ export default function CentrePlot(): JSX.Element {
// issue here needs working on
const domains = getDomains(detector, cameraTube);

const getQRange = (
detectorHeight: number,
cameraTube: CircularDevice,
beamstop: Beamstop,
): { visableRange: number; nonVisableRange: number } => {
const cameraTubeBottom =
Math.sqrt(
Math.pow(cameraTube.diameter / 2, 2) -
Math.pow((beamstop.centre.x ?? 0) - (cameraTube.centre.x ?? 0), 2),
) + (cameraTube.centre.y ?? 0);
const shorterEdge = Math.min(detectorHeight, cameraTubeBottom);
const clearance =
(beamstop.centre.y ?? 0) +
(beamstop.clearance ?? 0) +
beamstop.diameter / 2;
if (clearance > shorterEdge) {
return {
visableRange: beamstop.centre.y ?? 0,
nonVisableRange: beamstop.centre.y ?? 0,
};
}
return { visableRange: shorterEdge, nonVisableRange: clearance };
};

const qrange = getQRange(detector.resolution.height, cameraTube, beamstop);

const { ptMax, ptMin } = computeQrange(
detector,
beamstop,
cameraTube,
bealineConfig,
) ?? { ptMax: new Vector2(0, 0), ptMin: new Vector2(0, 0) };
return (
<Box>
<Card>
Expand Down Expand Up @@ -144,8 +127,8 @@ export default function CentrePlot(): JSX.Element {
detector.resolution.width,
detector.resolution.height,
),
new Vector3(beamstop.centre.x ?? 0, qrange.visableRange),
new Vector3(beamstop.centre.x ?? 0, qrange.nonVisableRange),
new Vector3(ptMin.x, ptMin.y),
new Vector3(ptMax.x, ptMax.y),
]}
>
{(
Expand Down

0 comments on commit ab63b15

Please sign in to comment.