diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7ab22ea --- /dev/null +++ b/flake.lock @@ -0,0 +1,57 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 0, + "narHash": "sha256-zSK269t+nFqDHYgowCCMuzwQOPyHswPTJDfk0TPHdwg=", + "path": "/nix/store/vrs69397kc15qqdrfn6fwd6xnrjp4f31-source", + "type": "path" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "utils": "utils" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..4e99ae3 --- /dev/null +++ b/flake.nix @@ -0,0 +1,63 @@ +{ + description = "Python environment using micromamba"; + + inputs = { + utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + utils, + ... + }: + utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + }; + webct = pkgs.buildFHSUserEnv { + name = "webct"; + targetPkgs = pkgs: with pkgs; [ + micromamba + just + fish + vscode + + # gvxr + libGL + libGLU + xorg.libX11 + + # open3d (mesh decimation) + libudev-zero + + # frontend + nodejs_22 + ]; + # runScript='' + extraBuildCommands = '' + # link micromamba to 'conda' in .mamba + # ln -s ${pkgs.micromamba}/bin/micromamba conda + ''; + # https://nixos.org/manual/nixpkgs/unstable/ + profile = '' + export PATH=${pkgs.vscode.fhs}/bin:".":$PATH + export MAMBA_ROOT_PREFIX=./.mamba + eval "$(micromamba shell hook --shell=posix)" + + if [ ! -d $MAMBA_ROOT_PREFIX ]; then + micromamba create -f environment.yml -y + fi + micromamba activate webct + ''; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + webct + ]; + shellHook = ''webct''; + }; + }); +} diff --git a/webct/blueprints/capture/static/js/capture.ts b/webct/blueprints/capture/static/js/capture.ts index 9d1f67f..445b101 100644 --- a/webct/blueprints/capture/static/js/capture.ts +++ b/webct/blueprints/capture/static/js/capture.ts @@ -24,6 +24,10 @@ let DetectorPosXElement: SlInput; let DetectorPosYElement: SlInput; let DetectorPosZElement: SlInput; +let SamplePosElement: SlRange; +let SampleSDDElement: HTMLParagraphElement; +let SampleSODElement: HTMLParagraphElement; +let SampleODDElement: HTMLParagraphElement; let SampleRotateXElement: SlInput; let SampleRotateYElement: SlInput; let SampleRotateZElement: SlInput; @@ -64,6 +68,11 @@ export function setupCapture(): boolean { const detector_posy_element = document.getElementById("inputDetectorPosY"); const detector_posz_element = document.getElementById("inputDetectorPosZ"); + const sample_position_element = document.getElementById("rangeSamplePosition"); + const sample_position_sdd = document.getElementById("textSDD") + const sample_position_sod = document.getElementById("textSOD") + const sample_position_odd = document.getElementById("textODD") + const sample_rotatex_element = document.getElementById("inputSampleRotateX"); const sample_rotatey_element = document.getElementById("inputSampleRotateY"); const sample_rotatez_element = document.getElementById("inputSampleRotateZ"); @@ -78,6 +87,10 @@ export function setupCapture(): boolean { beam_posx_element == null || beam_posy_element == null || beam_posz_element == null || + sample_position_element == null || + sample_position_sdd == null || + sample_position_sod == null || + sample_position_odd == null || sample_rotatex_element == null || sample_rotatey_element == null || sample_rotatez_element == null || @@ -99,9 +112,14 @@ export function setupCapture(): boolean { console.log(detector_posy_element); console.log(detector_posz_element); + console.log(sample_position_element); + console.log(sample_position_sdd); + console.log(sample_position_sod); + console.log(sample_position_odd); console.log(sample_rotatex_element); console.log(sample_rotatey_element); console.log(sample_rotatez_element); + console.log(sample_rotate_clock_45_element); console.log(sample_rotate_counter_clock_45_element); console.log(range_nyquist); @@ -123,6 +141,10 @@ export function setupCapture(): boolean { DetectorPosYElement = detector_posy_element as SlInput; DetectorPosZElement = detector_posz_element as SlInput; + SamplePosElement = sample_position_element as SlRange; + SampleSDDElement = sample_position_sdd as HTMLParagraphElement; + SampleSODElement = sample_position_sod as HTMLParagraphElement; + SampleODDElement = sample_position_odd as HTMLParagraphElement; SampleRotateXElement = sample_rotatex_element as SlInput; SampleRotateYElement = sample_rotatey_element as SlInput; SampleRotateZElement = sample_rotatez_element as SlInput; @@ -142,6 +164,28 @@ export function setupCapture(): boolean { }); }); + SamplePosElement.addEventListener("sl-change", () => { + let [sod, odd, sdd] = updateSamplePositionBar(); + + BeamPosYElement.value = (sod * -1).toFixed(2) + DetectorPosYElement.value = odd.toFixed(2) + }); + + BeamPosYElement.addEventListener("sl-change", () => { + let sod = parseFloat(BeamPosYElement.value) * -1 + let odd = parseFloat(DetectorPosYElement.value) + let sdd = sod + odd + SamplePosElement.value = (sod / sdd) * 100 + updateSamplePositionBar(); + }); + DetectorPosYElement.addEventListener("sl-change", () => { + let sod = parseFloat(BeamPosYElement.value) * -1 + let odd = parseFloat(DetectorPosYElement.value) + let sdd = sod + odd + SamplePosElement.value = (sod / sdd) * 100 + updateSamplePositionBar(); + }); + NyquistRange = range_nyquist as SlRange; NyquistRange.addEventListener("sl-change", () => { TotalProjectionsElement.value = Math.floor((Math.PI / 2.0 * (parseInt(PaneWidthElement.value) / (parseFloat(PanePixelSizeElement.value) / 1000))) * (NyquistRange.value as number / 100)) + ""; @@ -191,6 +235,20 @@ export function validateCapture(): boolean { // =================== Display and UI =================== // // ====================================================== // +function updateSamplePositionBar():[number, number, number] { + // Assuming sample position only moves in the Y-coordinate, not taking into account axis offsets. + let sod = parseFloat(BeamPosYElement.value) * -1 + let odd = parseFloat(DetectorPosYElement.value) + let sdd = sod + odd + + sod = sdd * (SamplePosElement.value / 100) + odd = sdd - sod + SampleODDElement.textContent = odd.toFixed(2) + "mm" + SampleSODElement.textContent = sod.toFixed(2) + "mm" + SampleSDDElement.textContent = sdd.toFixed(2) + "mm" + return [sod, odd, sdd] +} + function SetOverlaySize(width: number, height: number): void { for (let index = 0; index < PreviewOverlays.length; index++) { const overlay = PreviewOverlays[index]; @@ -405,4 +463,9 @@ export function setCaptureParams(properties:CaptureProperties) { SampleRotateYElement.value = properties.sampleRotation[1] + ""; SampleRotateZElement.value = properties.sampleRotation[2] + ""; + let pct = ((properties.beamPosition[1] * -1) / ((properties.beamPosition[1]* -1) + properties.detectorPosition[1])) * 100 + console.log(properties); + console.log(pct); + SamplePosElement.value = pct + updateSamplePositionBar(); } diff --git a/webct/blueprints/capture/static/scss/capture.scss b/webct/blueprints/capture/static/scss/capture.scss index e87c896..5d8647d 100644 --- a/webct/blueprints/capture/static/scss/capture.scss +++ b/webct/blueprints/capture/static/scss/capture.scss @@ -82,3 +82,35 @@ sl-range.linked { sl-range::part(tooltip) { z-index: var(--sl-z-index-tooltip); } + +#rangeSamplePosition { + margin: 0; +} + +#gridSDD { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + margin: 0; +} + +#gridSDD > p { + text-align: center; + margin: 0; +} + +#gridSOD { + display: grid; + grid-template-columns: 1fr max-content 1fr; + margin: 0; +} + +#gridSOD > p { + text-align: center; + margin: 0; + margin-bottom: 1rem; +} + +#textSDD, #textSOD, #textODD { + color: var(--sl-color-neutral-500); + font-size: var(--sl-font-size-x-small); +} diff --git a/webct/blueprints/capture/templates/tab.capture.html.j2 b/webct/blueprints/capture/templates/tab.capture.html.j2 index 145e4bb..5b51e01 100644 --- a/webct/blueprints/capture/templates/tab.capture.html.j2 +++ b/webct/blueprints/capture/templates/tab.capture.html.j2 @@ -45,6 +45,18 @@
Source
+500mm
+Detector
+400mm
+Sample
+100mm
+Beam source to sample