Skip to content

Provider for qbins #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/user-guide/amor/amor-reduction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"metadata": {},
"outputs": [],
"source": [
"%matplotlib widget\n",
"import warnings\n",
"import scipp as sc\n",
"from ess import amor\n",
Expand Down Expand Up @@ -60,7 +61,6 @@
"workflow[ChopperPhase[ReferenceRun]] = sc.scalar(-7.5, unit='deg')\n",
"workflow[ChopperPhase[SampleRun]] = sc.scalar(-7.5, unit='deg')\n",
"\n",
"workflow[QBins] = sc.geomspace(dim='Q', start=0.005, stop=0.3, num=391, unit='1/angstrom')\n",
"workflow[WavelengthBins] = sc.geomspace('wavelength', 2.8, 12.5, 2001, unit='angstrom')\n",
"\n",
"# The YIndexLimits and ZIndexLimits define ranges on the detector where\n",
Expand Down Expand Up @@ -235,7 +235,7 @@
"outputs": [],
"source": [
"from ess.reflectometry.tools import combine_curves\n",
"combined = combine_curves(scaled_reflectivity_curves, workflow.compute(QBins))\n",
"combined = combine_curves(scaled_reflectivity_curves, sc.geomspace('Q', 0.005, 0.4, 499, unit='1/angstrom'))\n",
"combined.plot(norm='log')"
]
},
Expand Down Expand Up @@ -336,7 +336,7 @@
"q_theta_figure(\n",
" [res[ReflectivityOverZW] for res in diagnostics.values()],\n",
" theta_bins=[res[ThetaBins[SampleRun]] for res in diagnostics.values()],\n",
" q_bins=workflow.compute(QBins)\n",
" q_bins=sc.geomspace('Q', 0.005, 0.4, 499, unit='1/angstrom')\n",
")"
]
},
Expand Down Expand Up @@ -527,7 +527,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.14"
"version": "3.10.18"
}
},
"nbformat": 4,
Expand Down
39 changes: 37 additions & 2 deletions src/ess/amor/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
import scipp as sc

from ..reflectometry.types import DetectorRotation, RunType, SampleRotation, ThetaBins
from ..reflectometry.conversions import reflectometry_q
from ..reflectometry.types import (
BeamDivergenceLimits,
DetectorRotation,
QBins,
RunType,
SampleRotation,
SampleRun,
ThetaBins,
WavelengthBins,
)
from .geometry import Detector


Expand Down Expand Up @@ -55,4 +65,29 @@ def theta_grid(
return grid


providers = (theta_grid,)
def qgrid(
detector_rotation: DetectorRotation[SampleRun],
sample_rotation: SampleRotation[SampleRun],
wbins: WavelengthBins,
bdlims: BeamDivergenceLimits,
) -> QBins:
'''Generates a suitable Q-binnning from
the limits on wavelength and divergence angle.'''
theta_min = (
bdlims[0].to(unit='rad', copy=False)
+ detector_rotation.to(unit='rad', dtype='float64')
- sample_rotation.to(unit='rad', dtype='float64')
)
theta_max = (
bdlims[-1].to(unit='rad', copy=False)
+ detector_rotation.to(unit='rad', dtype='float64')
- sample_rotation.to(unit='rad', dtype='float64')
)
wmin, wmax = wbins[0], wbins[-1]
qmin = reflectometry_q(wavelength=wmax, theta=theta_min)
qmax = reflectometry_q(wavelength=wmin, theta=theta_max)
qmin = max(qmin, sc.scalar(1e-3, unit='1/angstrom'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for this particular hard maximum? Should be documented in the docstring at least.

return QBins(sc.geomspace('Q', qmin, qmax, 499))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 499? Should this be an input param?



providers = (theta_grid, qgrid)
48 changes: 48 additions & 0 deletions tests/amor/utils_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024 Scipp contributors (https://github.com/scipp)
# flake8: noqa: F403, F405

import scipp as sc
import scipp.constants
import scipp.testing

from ess.amor.utils import qgrid


def test_qgrid_provider():
grid = qgrid(
detector_rotation=sc.scalar(2, unit='deg'),
sample_rotation=sc.scalar(0.9, unit='deg'),
wbins=sc.linspace('wavelength', 3, 12, 10, unit='angstrom'),
bdlims=(sc.scalar(-0.75, unit='deg'), sc.scalar(0.75, unit='deg')),
)
sc.testing.assert_allclose(
grid[0],
4
* sc.constants.pi
* sc.sin(
sc.scalar(-0.75, unit='deg').to(unit='rad')
+ sc.scalar(1.1, unit='deg').to(unit='rad')
)
/ sc.scalar(12, unit='angstrom'),
)
sc.testing.assert_allclose(
grid[-1],
4
* sc.constants.pi
* sc.sin(
sc.scalar(0.75, unit='deg').to(unit='rad')
+ sc.scalar(1.1, unit='deg').to(unit='rad')
)
/ sc.scalar(3, unit='angstrom'),
)


def test_qgrid_provider_minimum_q():
grid = qgrid(
detector_rotation=sc.scalar(1.2, unit='deg'),
sample_rotation=sc.scalar(0.7, unit='deg'),
wbins=sc.linspace('wavelength', 3, 12, 10, unit='angstrom'),
bdlims=(sc.scalar(-0.75, unit='deg'), sc.scalar(0.75, unit='deg')),
)
sc.testing.assert_allclose(grid[0], sc.scalar(0.001, unit='1/angstrom'))
Loading