-
Notifications
You must be signed in to change notification settings - Fork 12
Create hard-x-ray undulator for i09 branches #1531
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
Villtord
wants to merge
43
commits into
main
Choose a base branch
from
add_undulator_i09
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+422
−54
Open
Changes from all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
f157912
create hard-x-ray undulator and add to i09
5e5e504
move comments to a parametere
d44acc3
add "comments" parameter to lookuptable in hard undulator
ab7491c
extract update lookup table cache method
803e4ca
few comments added
9c9b317
typo fix
448059a
add reading test
6d52c54
add more tests
99a05a6
more tests
127dd9c
tests
735debd
remove lut path
c954f09
more tests!!!
375dec2
Merge branch 'main' into add_undulator_i09
Villtord a7f11ce
update docs
5d5438a
remove order from set method - it is not how currently beamline use it
67f32eb
fix cached lookup value
0c6f60b
update tests
05124dd
set method docs update
595b8ad
make gap calculation function callable parameter
1d5a9e7
Merge branch 'main' into add_undulator_i09
Villtord 4debd54
review: order extracted to a separate class
2efc846
replace column numbers with constants
698c071
amend docs
8aa55da
change names of parameters in calculation gap function
9a507d1
amend test string
2a687b2
add valueerror message with valid orders
3c1f13a
restructure tests, add docs
6ac71f3
amend comment
3988d25
Sorted out theory of gap calculation
651878d
Merge branch 'main' into add_undulator_i09
Villtord e52c1fe
Refactor undulator class, make hardUndulator only set gap in mm
4da6cad
Merge branch 'main' into add_undulator_i09
Villtord 54cef04
fix tests, amend docstrings
6771325
update tests and docs
3f26e35
move _set_gap to a base undulator class
fe6823f
Remove order from hard undulator
ea93944
add test move to same gap
ebd3c2e
Merge branch 'main' into add_undulator_i09
Villtord 4773595
Remove hard undulator class and use base undulator instead
d2903e6
fix test
7448198
Merge branch 'main' into add_undulator_i09
Villtord 8c24690
amend test after rebase
41e1645
Merge branch 'add_undulator_i09' of ssh://github.com/DiamondLightSour…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from dodal.devices.i09_1_shared.hard_undulator_functions import ( | ||
calculate_gap_hu, | ||
get_hu_lut_as_dict, | ||
) | ||
|
||
__all__ = ["calculate_gap_hu", "get_hu_lut_as_dict"] |
109 changes: 109 additions & 0 deletions
109
src/dodal/devices/i09_1_shared/hard_undulator_functions.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import numpy as np | ||
|
||
from dodal.devices.util.lookup_tables import energy_distance_table | ||
from dodal.log import LOGGER | ||
|
||
LUT_COMMENTS = ["#"] | ||
HU_SKIP_ROWS = 3 | ||
|
||
# Physics constants | ||
ELECTRON_REST_ENERGY_MEV = 0.510999 | ||
|
||
# Columns in the lookup table | ||
RING_ENERGY_COLUMN = 1 | ||
MAGNET_FIELD_COLUMN = 2 | ||
MIN_ENERGY_COLUMN = 3 | ||
MAX_ENERGY_COLUMN = 4 | ||
GAP_OFFSET_COLUMN = 7 | ||
|
||
|
||
async def get_hu_lut_as_dict(lut_path: str) -> dict: | ||
lut_dict: dict = {} | ||
_lookup_table: np.ndarray = await energy_distance_table( | ||
lut_path, | ||
comments=LUT_COMMENTS, | ||
skiprows=HU_SKIP_ROWS, | ||
) | ||
for i in range(_lookup_table.shape[0]): | ||
lut_dict[_lookup_table[i][0]] = _lookup_table[i] | ||
LOGGER.debug(f"Loaded lookup table:\n {lut_dict}") | ||
return lut_dict | ||
|
||
|
||
def calculate_gap_hu( | ||
photon_energy_kev: float, | ||
look_up_table: dict[int, "np.ndarray"], | ||
order: int = 1, | ||
gap_offset: float = 0.0, | ||
undulator_period_mm: int = 27, | ||
) -> float: | ||
""" | ||
Calculate the undulator gap required to produce a given energy at a given harmonic order. | ||
This algorithm was provided by the I09 beamline scientists, and is based on the physics of undulator radiation. | ||
https://cxro.lbl.gov//PDF/X-Ray-Data-Booklet.pdf | ||
|
||
Args: | ||
photon_energy_kev (float): Requested photon energy in keV. | ||
look_up_table (dict[int, np.ndarray]): Lookup table containing undulator and beamline parameters for each harmonic order. | ||
order (int, optional): Harmonic order for which to calculate the gap. Defaults to 1. | ||
gap_offset (float, optional): Additional gap offset to apply (in mm). Defaults to 0.0. | ||
undulator_period_mm (int, optional): Undulator period in mm. Defaults to 27. | ||
|
||
Returns: | ||
float: Calculated undulator gap in millimeters. | ||
""" | ||
magnet_blocks_per_period = 4 | ||
magnet_block_height_mm = 16 | ||
|
||
if order not in look_up_table.keys(): | ||
raise ValueError(f"Order parameter {order} not found in lookup table") | ||
|
||
gamma = 1000 * look_up_table[order][RING_ENERGY_COLUMN] / ELECTRON_REST_ENERGY_MEV | ||
|
||
# Constructive interference of radiation emitted at different poles | ||
# lamda = (lambda_u/2*gamma^2)*(1+K^2/2 + gamma^2*theta^2)/n for n=1,2,3... | ||
# theta is the observation angle, assumed to be 0 here. | ||
# Rearranging for K (the undulator parameter, related to magnetic field and gap) | ||
# gives K^2 = 2*((2*n*gamma^2*lamda/lambda_u)-1) | ||
|
||
undulator_parameter_sqr = ( | ||
4.959368e-6 | ||
* (order * gamma * gamma / (undulator_period_mm * photon_energy_kev)) | ||
- 2 | ||
) | ||
if undulator_parameter_sqr < 0: | ||
raise ValueError("diffraction parameter squared must be positive!") | ||
undulator_parameter = np.sqrt(undulator_parameter_sqr) | ||
|
||
# Undulator_parameter K is also defined as K = 0.934*B0[T]*lambda_u[cm], | ||
# where B0[T] is a peak magnetic field that must depend on gap, | ||
# but in our LUT it is does not depend on gap, so it's a factor, | ||
# leading to K = 0.934*B0[T]*lambda_u[cm]*exp(-pi*gap/lambda_u) or | ||
# K = undulator_parameter_max*exp(-pi*gap/lambda_u) | ||
# Calculating undulator_parameter_max gives: | ||
undulator_parameter_max = ( | ||
( | ||
2 | ||
* 0.0934 | ||
* undulator_period_mm | ||
* look_up_table[order][MAGNET_FIELD_COLUMN] | ||
* magnet_blocks_per_period | ||
/ np.pi | ||
) | ||
* np.sin(np.pi / magnet_blocks_per_period) | ||
* (1 - np.exp(-2 * np.pi * magnet_block_height_mm / undulator_period_mm)) | ||
) | ||
|
||
# Finnaly, rearranging the equation: | ||
# undulator_parameter = undulator_parameter_max*exp(-pi*gap/lambda_u) for gap gives: | ||
gap = ( | ||
(undulator_period_mm / np.pi) | ||
* np.log(undulator_parameter_max / undulator_parameter) | ||
+ look_up_table[order][GAP_OFFSET_COLUMN] | ||
+ gap_offset | ||
) | ||
LOGGER.debug( | ||
f"Calculated gap is {gap}mm for energy {photon_energy_kev}keV at order {order}" | ||
) | ||
|
||
return gap |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.