-
Notifications
You must be signed in to change notification settings - Fork 3
Reflectometry rewrite #61
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
Conversation
…f detector_id x nevets
…w_reflectometry_data
src/ess/reflectometry/conversions.py
Outdated
Generate a coordinate transformation graph for reflectometry. | ||
""" | ||
graph = {**conversions.beamline(scatter=True), **conversions.elastic("tof")} | ||
graph["two_theta"] = reflectometry_theta |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also produce something called 'theta'
alongside this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it seems we can add something that is called theta
which is just a renaming of two_theta
by doing
graph["theta"] = "two_theta"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure we need/want a double meaning of theta
? This seems like it will nearly with certainty lead to bugs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want a dimension called theta
in my final dataset, which is equal to a half of two_theta
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then @nvaytet must have misunderstood you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so. For now, this is fine, I will open an issue for this to be included.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I am very wary of using theta because I have things going wrong with that in the past. If think reflectometry may be an exception, since a mixup with \theta_{spherical}
is not likely (unlike other techniques, which define z
along incident_beam
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added suggestions based on the nomenclature used in the Amor paper (fig 5 https://doi.org/10.1016/j.nima.2016.03.007).
src/ess/reflectometry/conversions.py
Outdated
# Note: make use of in-place operations for better performance | ||
drop *= grav * (m_n**2 / (2 * h**2)) | ||
drop += y | ||
return sc.asin(sc.abs(drop) / L2) - sc.to_unit(sample_rotation, 'rad') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return sc.asin(sc.abs(drop) / L2) - sc.to_unit(sample_rotation, 'rad') | |
out = sc.abs(drop, out=drop) | |
out /= L2 | |
out = sc.asin(out, out=out) | |
out -=sc.to_unit(sample_rotation, 'rad') | |
return out |
does no extra allocation, vs. FOUR large allocations, I think?
src/ess/reflectometry/conversions.py
Outdated
|
||
|
||
def reflectometry_q(wavelength: sc.Variable, theta: sc.Variable) -> sc.Variable: | ||
""" | ||
Compute the Q vector from the theta angle computed as the difference | ||
between gamma and omega. | ||
Note that this is different from the 'normal' Q defined in scippneutron where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is different from the 'normal' Q defined in scippneutron where | |
Note that this is identical to the 'normal' Q defined in scippneutron where |
...except that the input is given as theta instead of two_theta?
src/ess/v20/imaging/beamline.py
Outdated
kind=ChopperKind.FRAME_OVERLAP) | ||
} | ||
beamline["chopper_wfm_1"] = sc.scalar( | ||
sc.Dataset( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above, a chopper "constructor" (even if it returns a dataset) would probably be useful?
…e dense or the event coordinates
src/ess/choppers/make_chopper.py
Outdated
if not np.all(np.diff(utils.cutout_angles_begin(chopper).values) > 0): | ||
raise ValueError("Chopper begin cutout angles are not monotonic.") | ||
if not np.all(np.diff(utils.cutout_angles_end(chopper).values) > 0): | ||
raise ValueError("Chopper end cutout angles are not monotonic.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this use https://scipp.github.io/generated/functions/scipp.issorted.html?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
src/ess/choppers/make_chopper.py
Outdated
@@ -52,9 +52,9 @@ def make_chopper(frequency: sc.Variable, | |||
widths = utils.cutout_angles_width(chopper) | |||
if (sc.min(widths) < sc.scalar(0.0, unit=widths.unit)).value: | |||
raise ValueError("Negative window width found in chopper cutout angles.") | |||
if not np.all(np.diff(utils.cutout_angles_begin(chopper).values) > 0): | |||
if not sc.issorted(utils.cutout_angles_begin(chopper), dim=widths.dim).value: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://scipp.github.io/release/0.8.4/generated/functions/scipp.allsorted.html is your friend, forget that we have it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, and just to make sure: do we also have a function that doesn't require the dim
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we do, we have always avoided that (even though there are a couple of exceptions).
This is a major re-write of the reflectometry code. This aims to be a first step in the rewrite, where some functionality has been removed/disabled (see illumination correction fx) for simplicity, and will be added back in as part of follow-up PRs.
The idea is to write the reflectometry module in a more functional way, rather than an object-oriented approach.
This way, we are passing Scipp data arrays and variables around, instead of custom classes, which makes functions more re-useable/portable, as well as more in-line with the rest of the
ess
codebase.In addition, the gravity correction calculation has been replaced by a custom conversion graph that is then supplied to
transform_coords
to perform the calculation of thetwo_theta
scattering angle and theQ
vector.The illumination correction has been removed from the reduction workflow (for now), but not from the codebase.
Many tests have been deleted, trying to keep relevant tests for the functions (the transform_coords is being tested in scipp and scippneutron, so we don't need to test again all aspects of it here). Some of these tests will come back in future PRs, when we add the full functionality back in.
A basic reduction notebook, based on the ones from the
ess-notebooks
repo has been added, and this should in the future become the reference reduction workflow, once we add all the missing bits.