Skip to content

Conversation

@EmsArnold
Copy link
Contributor

Closes #1498

Wraps bluesky plans (scan, rel_scan, grid_scan, rel_grid_scan) and plan stubs (rd, stop) for use in blueapi. Intended as a replacement for gda-style start stop step scans until spec_scan is stable and supports start stop step rather than start stop num.

Instructions to reviewer on how to test:

  1. Do thing x
  2. Confirm thing y happens

Checks for reviewer

  • Would the PR title make sense to a scientist on a set of release notes

@codecov
Copy link

codecov bot commented Nov 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.09%. Comparing base (2e4d3b1) to head (9588c99).
⚠️ Report is 12 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1702      +/-   ##
==========================================
+ Coverage   98.91%   99.09%   +0.18%     
==========================================
  Files         271      275       +4     
  Lines        9922    10168     +246     
==========================================
+ Hits         9814    10076     +262     
+ Misses        108       92      -16     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@EmsArnold
Copy link
Contributor Author

As discussed in the Athena drop-in today, this PR wraps some Bluesky plans which would allow 1D - ND scans. In view of the current differences in scan names between GDA and Bluesky, we should carefully consider the naming of these scans to reduce confusion for all users in the future. A non-exhaustive list is given below of what is currently achievable in GDA (through traditional and mapping scans), as well as what is achievable in Bluesky. I appreciate that some of the Bluesky scans will be covered by spec_scan in the future.

I've included suggested names for use in the future, but suggestions for different names (and any corrections to current scans) are very welcome.

Plan Description GDA Bluesky Dodal
Trigger and Read staticscan count count
1D Scan (log) -- log_scan
ND Scan (step) concurrent movement scan -- step_scan
ND / 2D Scan (num) concurrent movement pscan / mscan scan num_scan
ND Scan (list) concurrent movement -- list_scan list_scan
ND Scan (step) scan or gscan -- step_grid_scan
ND / 2D Scan (num) -- / mscan grid_scan num_grid_scan
ND Scan (list) -- list_grid_scan list_grid_scan
Relative 1D Scan (log) -- rel_log_scan
Relative ND scan (step) concurrent rscan? -- step_rscan
Relative ND / 2D scan (num) concurrent -- / mscan rel_scan num_rscan
Relative ND scan (list) concurrent -- rel_list_scan list_rscan
Relative ND scan (step) rscan -- step_grid_rscan
Relative ND / 2D scan (num) -- / mscan rel_grid_scan num_grid_rscan
Relative ND scan (list) -- rel_list_grid_scan list_grid_rscan
Centered 2D scan (step, num) mscan --
Centered ND scan (step) cscan --
Collect at specified time interval timescan /tscan count count
Scan at a constant velocity cvscan
Spiral mscan spiral
Fermat Spiral -- spiral_fermat
Absolute Square Spiral spiral_square
Lissajous mscan --
Relative Spiral -- rel_spiral
Relative Fermat Spiral -- rel_spiral_fermat
Relative Absolute Square Spiral -- rel_spiral_square
Adaptive -- adaptive_scan
Relative Adaptive -- rel_adaptive_scan

@RJCD-Diamond
Copy link
Contributor

RJCD-Diamond commented Nov 13, 2025

Re Collect at specified time interval it is =/= count. Count will count with whatever time is in the acquire time. They explain why they can't specify a time for this in the bluesky docs. Ie different types of detector have different mechanisms of defining how long to count for. However, most of our detectors are StandardDetectors and going forward they should all be. Which means we can actually do this. It would look like:

@bpp.run_decorator()
def timescan(detectors: list[StandardDetector], duration: float | int ):

    trigger_info= TriggerInfo(livetime=float(duration) )

    for det in detectors:
        yield from bps.prepare(det, trigger_info)

    yield from bps.trigger_and_read(detectors)

With regards to the other naming conventions, I think if gda doesn't have an equivalent, go with the bluesky naming. If the bluesky one is exactly the same as the gda, go with the gda/bluesky one. If there is a clash make up something new that is explicit. If gda has it, but vanilla bluesky, maybe go with it, although some of the gda names aren't explicit so maybe this is a time to come up with better names.

If you get those tests working, I'll take another look

@EmsArnold
Copy link
Contributor Author

Collect at specified time interval it is =/= count

My understanding from the GDA docs was that pause time in timescan/tscan was equivalent to delay in count, but yes I suppose with count you can't specify the time to collect for.

I think there's enough clashing on scan, and enough inconsistencies in the other names that we would be better served by a more logical and explicit naming system. I'd lean more towards making it easy to learn (keeping in mind the number of new users we get every day) rather than honouring the historical names (for the sake of staff and heavy users).

Copy link
Contributor

@RJCD-Diamond RJCD-Diamond left a comment

Choose a reason for hiding this comment

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

Looks good, approving. Would be good to test this out on a beamline too before merging

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create wrapped versions of all standard bluesky plan and step_scan version of scan

3 participants