Skip to content

Commit

Permalink
Edge align Function created (#943)
Browse files Browse the repository at this point in the history
* Added edge_align plan for beam edge alignment

* Need to find a better way to check signal quality.

* Formatted using ruff

* small formatting changes

* removed unused stats import

* removed another unused import

* Added a check function that yields correct results

* intermediate commit saving progress

* finished try/except when bad signal is detected

* Fixed formatting

* Added scipy to environment.yaml & requirements.txt

* CI #909 switch to 'ruff'

* DOC #909 update release notes

* MNT #909 revise per 'ruff check'

* CI #909 update

* Bump davidslusser/actions_python_ruff from 1.0.0 to 1.0.1

Bumps [davidslusser/actions_python_ruff](https://github.com/davidslusser/actions_python_ruff) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/davidslusser/actions_python_ruff/releases)
- [Commits](davidslusser/actions_python_ruff@v1.0.0...v1.0.1)

---
updated-dependencies:
- dependency-name: davidslusser/actions_python_ruff
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>

* MNT #872 hoist from MPE devices

* TST #872 adjust for new hoist

* MNT #872

* MNT #872 refactor

* MNT #872 hoist utils

* DOC #912

* ENV #938 bump the minimum requirement

* DOC #932 update relase notes

* DOC #938 contribution from @sveseli

* MNT #914 setup.py --> pyproject.toml

* DOC #921 copyright year

* MNT #914

* Added edge_align function for beam edge alignment

* added scipy to pyproject.toml

* CI #909 switch to 'ruff'

* DOC badge

* DOC badge

* DOC #940 example scans with sscan record

* DOC #940 it's only a word ...

* DOC #940

* DOC #940 it's a demo, actually

* DOC #940

* DOC #940 convert the blocking call to st.wait()

* DOC #940 per review

* DOC #940 per review

* DOC #940 proofreading

* DOC #940 per review, remove the section with the polling loop

* DOC #940 new title

* DOC #940 more proofing

* DOC #940 clarify the default sscan record array size of 1,000

* DOC #940 refactor to polling loop. Show the recommended style in a details section.

* DOC #940

* Added put_complete=True to sensitivity value and unit for the SRS-570 Pre-amp.

* Added a test for the sensitivity_unit put_complete, and removed the put_complete from sensitivity_value.

* CI #955 move requirements file

* MNT #955 sphinx config

* DOC #955 re-arrange

* DOC #955 apply to lower-level pages

* DOC #955 add docs upload

* CI #955

* CI #955

* CI #955 wip

* CI #955

* CI #955

* DOC #917 release note

* DOC #957 merge overview into home page

* DOC #955

* DOC #955

* DOC #955

* DOC #955

* Added edge_align function for beam edge alignment

* Added edge_align function for beam edge alignment

* Added edge_align function for beam edge alignment

* DOC #909 update release notes

* DOC #932 update relase notes

* Added edge_align function for beam edge alignment

* CI #909 switch to 'ruff'

* DOC #955

* Fixed merge issue

* fixed unused import

* change for tests to pass

* Formatting changes

* Fixed repeated section

* Small formatting changes

* Small syntax change

* Added toolz & scipy to conf.py

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Codrea <[email protected]>
Co-authored-by: Pete R Jemian <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pete R Jemian <[email protected]>
Co-authored-by: Mark Wolfman <[email protected]>
  • Loading branch information
6 people authored Apr 12, 2024
1 parent 5301e19 commit af11141
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 3 deletions.
81 changes: 81 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Exclude a variety of commonly ignored directories.
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
".pyenv",
".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
".vscode",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
]

# Same as Black.
line-length = 115
indent-width = 4

# Assume Python 3.8
target-version = "py38"

[lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
# McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "F"]
ignore = ["E402", "E741", "F405"]

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[lint.per-file-ignores]
"__init__.py" = ["F401", "F403"]
"**/{tests,docs,tools}/*" = ["E402"]

[format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

# Enable auto-formatting of code examples in docstrings. Markdown,
# reStructuredText code/literal blocks and doctests are all supported.
#
# This is currently disabled by default, but it is planned for this
# to be opt-out in the future.
docstring-code-format = false

# Set the line length limit used when formatting code snippets in
# docstrings.
#
# This only has an effect when the `docstring-code-format` setting is
# enabled.
docstring-code-line-length = "dynamic"
7 changes: 4 additions & 3 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ describe future plans.
release expected by 2024-04-12

New Features
------------
------------

* Add new plan for edge alignment called edge_align
* Added a mesh grid scan plan that will collect until number of collection points is met

* Added a mesh grid scan plan that will collect until number of collection points is met

Fixes
-----

Expand Down
1 change: 1 addition & 0 deletions apstools/plans/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from .alignment import TuneResults
from .alignment import lineup
from .alignment import lineup2
from .alignment import edge_align
from .alignment import tune_axes
from .command_list import CommandFileReadError
from .command_list import command_list_as_table
Expand Down
112 changes: 112 additions & 0 deletions apstools/plans/alignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

import numpy as np
import pyRestTable
from scipy.optimize import curve_fit
from scipy.special import erf

from bluesky import plan_stubs as bps
from bluesky import plans as bp
from bluesky import preprocessors as bpp
Expand Down Expand Up @@ -213,6 +216,115 @@ def peak_analysis():
scaler.stage_sigs = old_sigs


def edge_align(detectors, mover, start, end, points, cat=None, md={}):
"""
Align to the edge given mover & detector data, relative to absolute position.
This plan can be used in the queueserver, Jupyter notebooks, and IPython
consoles.
PARAMETERS
----------
detectors *Readable* or [*Readable*]:
Detector object or list of detector objects (each is a Device or
Signal).
mover *Movable*:
Mover object, such as motor or other positioner.
start *float*:
Starting point for the scan. This is an absolute motor location.
end *float*:
Ending point for the scan. This is an absolute motor location.
points *int*:
Number of points in the scan.
cat *databroker.temp().v2*:
Catalog where bluesky data is saved and can be retrieved from.
md *dict*:
User-supplied metadata for this scan.
"""

def guess_erf_params(x_data, y_data):
"""
Provide an initial guess for the parameters of an error function.
Parameters
----------
x_data : A numpy array of the values on the x_axis
y_data : A numpy array of the values on the y_axis
Returns
-------
guess : dict
A dictionary containing the guessed parameters 'low_y_data', 'high_y_data', 'width', and 'midpoint'.
"""

# Sort data to make finding the mid-point easier and to assist in other estimations
y_data_sorted = np.sort(y_data)
x_data_sorted = np.sort(x_data)

# Estimate low and high as the first and last elements (assuming sorted data)
low_y_data = np.min(y_data_sorted)
high_y_data = np.max(y_data_sorted)

low_x_data = np.min(x_data_sorted)
high_x_data = np.max(x_data_sorted)

# Estimate wid as a fraction of the range. This is very arbitrary and might need tuning!
width = (
high_x_data - low_x_data
) / 10 # This is a guess and might need adjustment based on your data's characteristics

# Estimate the midpoint of the x values
midpoint = x_data[int(len(x_data) / 2)]

return [low_y_data, high_y_data, width, midpoint]

def erf_model(x, low, high, width, midpoint):
"""
Create error function for fitting and simulation
Parameters
----------
x : input upon which error function is evaluated
low : min value of error function
high : max value of error function
width : "spread" of error function transition region
midpoint: location of error function's "center"
"""
return (high - low) * 0.5 * (1 - erf((x - midpoint) / width)) + low

if not isinstance(detectors, (tuple, list)):
detectors = [detectors]

_md = dict(purpose="edge_align")
_md.update(md or {})

uid = yield from bp.scan(detectors, mover, start, end, points, md=_md)
cat = cat or utils.getCatalog()
run = cat[uid] # return uids
ds = run.primary.read()

x = ds["mover"]
y = ds["noisy"]

try:
initial_guess = guess_erf_params(x, y)
popt, pcov = curve_fit(erf_model, x, y, p0=initial_guess)
if pcov[3, 3] != np.inf:
print("Significant signal change detected; motor moving to detected edge.")
yield from bps.mv(mover, popt[3])
else:
raise Exception
except Exception as reason:
print(f"reason: {reason}")
print("No significant signal change detected; motor movement skipped.")


def lineup2(
# fmt: off
detectors, mover, rel_start, rel_end, points,
Expand Down
1 change: 1 addition & 0 deletions docs/source/api/_plans.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Custom Scans

.. autosummary::

~apstools.plans.alignment.edge_align
~apstools.plans.alignment.lineup
~apstools.plans.alignment.lineup2
~apstools.plans.alignment.tune_axes
Expand Down
2 changes: 2 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@
psutil
pyRestTable
pysumreg
scipy
spec2nexus
toolz
xarray
""".split()
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dependencies:
- pysumreg
- qt =5
- readline !=8.1.2
- scipy
- setuptools-scm
- spec2nexus
- sphinx >=5
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ dependencies = [
"pyepics>=3.4.2",
"pyRestTable>=2020.0.8",
"pysumreg",
"scipy",
"spec2nexus>=2021.1.7",
"toolz>=0.12.1",
"xlrd",
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ psutil
pyepics>=3.4.2
pyRestTable
pysumreg
scipy
spec2nexus>=2021.1.7
xlrd

0 comments on commit af11141

Please sign in to comment.