Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
35cec97
added nx_server run script
RussBerg Oct 20, 2025
39811f3
remove commented code
RussBerg Oct 20, 2025
05f5d4e
pass polarization dict instead of letting it generate a default
RussBerg Oct 20, 2025
5883cb0
display result msg from nx_server in log
RussBerg Oct 21, 2025
aa8874d
set coarse_only flag for limit checking
RussBerg Oct 21, 2025
a3c389e
using np.full() instead of np.empty() to create and init array to nans
RussBerg Oct 21, 2025
b20f4af
using start positions for sample x/y points
RussBerg Oct 21, 2025
21f16bb
fix path to scan time estimation data
Oct 21, 2025
639a5b4
if pixmap is None report it to logger and skip
RussBerg Nov 3, 2025
ddc3bd7
show reduced nxstxm msg after nx_server data export
RussBerg Nov 3, 2025
81c001a
set coarse_only flag on call to check_scan_limits
RussBerg Nov 3, 2025
7b0ab56
cleanup, now calling run function for every supported and selected de…
RussBerg Nov 3, 2025
e2f4533
disable hardware scanning support
RussBerg Nov 3, 2025
c357a0a
cleanup, fix name for base scan class
RussBerg Nov 3, 2025
450024f
fix key error issue for saving generic scans
RussBerg Nov 3, 2025
14f0566
cleanup, include scan_types.SAMPLE_IMAGE in three_d_scans so data wil…
RussBerg Nov 6, 2025
a51f8ac
software controlled sample LxL and PxP scans implemented
RussBerg Nov 6, 2025
2ca61b0
more descriptive message
RussBerg Nov 6, 2025
8fe862f
added run nx_server script
RussBerg Nov 6, 2025
f611d6d
remove test btn
RussBerg Nov 10, 2025
4cc52a8
add path to record if hardware accell is used
RussBerg Nov 10, 2025
62296c8
retain the dict returned that contains next filenames and directories…
RussBerg Nov 10, 2025
de644ce
retain the dict returned that contains next filenames and directories…
RussBerg Nov 10, 2025
7bc331d
add lxl and pxp and stack for soft controlled sample image scans, all…
RussBerg Nov 10, 2025
28185be
add output error to console
RussBerg Nov 10, 2025
14edbb3
remove debugging
RussBerg Nov 14, 2025
18191ff
renamed
RussBerg Nov 14, 2025
f12bc73
support threaded moves to avoid stalling the Qt event loop
RussBerg Nov 14, 2025
d336a3e
enum module renamed to avoid shadow
RussBerg Nov 14, 2025
4b41418
implement calling callback if passed
RussBerg Nov 14, 2025
a569bdf
enum renamed
RussBerg Nov 14, 2025
40a0bd6
implemented focus scans and button setting, initial tests look good
RussBerg Nov 14, 2025
698f313
soft pxp and lxl implemented and initially tested, enhancements to co…
RussBerg Nov 14, 2025
b1e227b
exclude coarse X and Y from main device panel
RussBerg Nov 14, 2025
5dcee0a
latest
RussBerg Nov 14, 2025
645697c
from br 44
RussBerg Nov 14, 2025
a67df27
fix focus scan erroneous data interpolated from endpoints for pxp foc…
RussBerg Nov 14, 2025
4bcf02b
set correct number of events for scan
RussBerg Nov 14, 2025
7a19e2a
fixed issue with focus scan plot resize when horizontal selection too…
RussBerg Nov 17, 2025
0c9b641
fix handling of aborted scans
RussBerg Nov 19, 2025
c351749
added a soft limit for A0
RussBerg Nov 19, 2025
3459be6
added delta A0 support
RussBerg Nov 19, 2025
6d96391
refine focus class usage
RussBerg Nov 19, 2025
58a5697
skip fine scan range check
RussBerg Nov 19, 2025
86615f9
removed OSAPARAMS and ZPPARAMS from PRESETS section as they are handl…
RussBerg Nov 19, 2025
eb8ca95
Merge branch 'test' into 40-epics-focus-issues
RussBerg Nov 19, 2025
e59cb3c
Merge pull request #53 from Canadian-Light-Source/40-epics-focus-issues
RussBerg Nov 19, 2025
e81e45a
added sim devices so that the Epics BL_api PV's can be removed
RussBerg Nov 28, 2025
33aaed9
relocated sim devices
RussBerg Nov 28, 2025
4c89eb0
handling zpz position changes based on focussing mode in python inste…
RussBerg Nov 28, 2025
8402224
fix class name
RussBerg Nov 28, 2025
41310de
added energy device to control auto focussing, removed reliance on ep…
RussBerg Dec 2, 2025
1c787e7
zonplate A1 values now positive, were negative as a convienience in c…
RussBerg Dec 2, 2025
27f63b6
if data acquired with hardware accel data will be a single event of a…
RussBerg Dec 2, 2025
d09e58d
move to single application defaults .json file
RussBerg Dec 2, 2025
f51fbda
move to single application defaults .json file
RussBerg Dec 2, 2025
58cac59
cleanup, standardize on _emit_move
RussBerg Dec 2, 2025
77d6587
remove Sim devices from device_loader but retain device classes for p…
RussBerg Dec 2, 2025
cf3e860
prevent scan from emitting signal to switch scan plugin and load para…
RussBerg Dec 2, 2025
f295b14
fix font size for multiregion widget and polarization table view
RussBerg Dec 2, 2025
0b5e5bd
fix font size and table header widths
RussBerg Dec 2, 2025
da5eca8
remove ring current
RussBerg Dec 2, 2025
d41cf62
sort stack dirs and files in descending order
RussBerg Dec 3, 2025
6f2724b
refactor to caproto_dev to avoid module name collision
RussBerg Dec 3, 2025
6d19fed
switch to using new energy device
RussBerg Dec 3, 2025
688a017
update get_next_file_num_in_seq
RussBerg Dec 3, 2025
a321a5a
fix stack and pxp stack file saving
RussBerg Dec 3, 2025
bdf2a2a
increase filename font size
RussBerg Dec 3, 2025
acc6b78
if energy is 0.0 at initilialization then it is likely a noHardware s…
RussBerg Dec 4, 2025
765f62a
needed to move Qt signals to a separate class to work with BlueSky
RussBerg Dec 4, 2025
a8734e1
latest vals used
RussBerg Dec 4, 2025
6e7ea54
latest vals used
RussBerg Dec 4, 2025
63d1038
dont assume that combobox has callback attribute
RussBerg Dec 8, 2025
02d1e3c
name the labels and address font size instylesheet
RussBerg Dec 8, 2025
b3a7967
improve UI performance loading stacks
RussBerg Dec 9, 2025
b4a5baa
cleanup
RussBerg Dec 10, 2025
c92deab
more helpful msg when scan velo to high, center msg dialog on screen
RussBerg Dec 10, 2025
7e7c7c0
merged coarseImageScan and FineImage scans into Sample Image scan
RussBerg Dec 10, 2025
6935b5b
merged coarseImageScan and FineImage scans into Sample Image scan
RussBerg Dec 10, 2025
b74e46d
fix path to scan_time dir
RussBerg Dec 10, 2025
4f056d1
fixed filter str for open file dialog
RussBerg Dec 10, 2025
254134f
improved speed of loading large stacks
RussBerg Dec 10, 2025
0ed4d4c
missed this for sample image scan merge
RussBerg Dec 10, 2025
b31ac69
improved messaging and removed warnings that were not needed
RussBerg Dec 10, 2025
f7b13a1
improved messaging and removed warnings that were not needed
RussBerg Dec 10, 2025
1ad2935
removed uneeded version files, fix version function to pull single ve…
RussBerg Dec 10, 2025
fe00008
removed uneeded version files, fix version function to pull single ve…
RussBerg Dec 10, 2025
66345f5
removed uneeded files
RussBerg Dec 10, 2025
9f2a705
cleanup
RussBerg Dec 10, 2025
e075502
update to correct name for A1 device
RussBerg Dec 10, 2025
1721812
update to correct name for A1 device
RussBerg Dec 10, 2025
f35df07
disable details btn as per Jians request
RussBerg Dec 10, 2025
ee1d4ed
improve directory navigation
RussBerg Dec 10, 2025
3c08a44
disable details btn as per Jians request
RussBerg Dec 10, 2025
d9f1a19
refactor button name to load a directory
RussBerg Dec 15, 2025
4176d96
refactor button name to load a directory
RussBerg Dec 15, 2025
ae6de59
finished off defocus beam implmentation, needs testing
RussBerg Dec 15, 2025
5fd1c3a
finished off defocus beam implmentation, needs testing
RussBerg Dec 15, 2025
77ddb1e
fix pre scan range checking to full coarse range
RussBerg Dec 15, 2025
b0dbebf
uncomment to enable again
RussBerg Dec 15, 2025
3c2aa36
cleanup and fix names in primary data stream for positioner scan
RussBerg Dec 18, 2025
be8ef8d
remove unused bmps
RussBerg Dec 23, 2025
2e17af6
added create_polygon, cleanup
RussBerg Dec 23, 2025
73cbc17
fix coarse PxP scan
RussBerg Dec 23, 2025
faa6d9d
cleanup
RussBerg Dec 23, 2025
a33d5a8
osa and sample holders specified now in bl_config
RussBerg Dec 23, 2025
1375091
cleanup
RussBerg Dec 23, 2025
460552d
fix rollback mistake
RussBerg Dec 23, 2025
f21b8bb
added beamline config reader
RussBerg Dec 23, 2025
9500d0b
settings file to mainatin shape positions
RussBerg Dec 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ cls/data_io/suitcase_nxstxm_TODEL/

cls/scan_engine/bluesky/tests/tst_output/

version.json
**/version.json

/sphinx/_build/
/sphinx/_build/

Expand Down
2 changes: 1 addition & 1 deletion bcm/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@

# set the backend that should be used

BACKEND='zmq'
BACKEND='epics'
7 changes: 7 additions & 0 deletions bcm/devices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ def print_flds(slf, _attrs, _attr_lst=None):
f.close()


# make sure sim devices are available
from bcm.devices.sim.sim_base_device import BaseSimDevice
from bcm.devices.sim.sim_base_object import BaseSimObject
from bcm.devices.sim.sim_binary_out import SimBo
from bcm.devices.sim.sim_multi_bit_binary_out import SimMbbo
from bcm.devices.sim.energy_dev import EnergyDevice

if USE_EPICS:
from .epics.base import BaseDevice
from .epics.aio import basedevice as basedevice
Expand Down
20 changes: 10 additions & 10 deletions bcm/devices/ophyd/e712_wavegen/e712.ini
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
{
"dwell": 10.0,
"fpath": "e712.ini",
"dwell": 1.0000000474974513,
"fpath": "/mnt/srv-unix-home/sm-user/git_sandbox/branches/40/pyStxm/bcm/devices/ophyd/e712_wavegen/e712.ini",
"line_accrange": 1.5,
"line_return_time": 0.2,
"line_return_time": 0.5,
"line_start_delay": 0.03,
"line_step_time": 0.005,
"line_trig_time": 0.03,
"line_updown_time": 0.005,
"max_rcv_bytes": 16384.0,
"max_sock_timeout": 1.0,
"mode": 1,
"numX": 25,
"numY": 25,
"mode": 0,
"numX": 100,
"numY": 100,
"pnt_start_delay": 0.0,
"pnt_step_time": 0.001,
"pnt_updown_time": 0.001,
"startX": -5.0,
"startY": -5.0,
"stopX": 5.0,
"stopY": 5.0
"startX": 1507.2386474609375,
"startY": -1274.4219970703125,
"stopX": 1517.2386474609375,
"stopY": -1264.4219970703125
}
165 changes: 19 additions & 146 deletions bcm/devices/ophyd/motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ class MotorQt(EpicsMotor, QObject):
raw_val = Cpt(EpicsSignal, ".RVAL", kind="omitted")
foff = Cpt(EpicsSignal, ".FOFF", kind="omitted")

_emit_move = pyqtSignal(float, bool) # a signal to call move from a sig handler in a thread safe way

# the following is here for compatability with e712_sample_motor

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -209,6 +211,18 @@ def __init__(self, *args, **kwargs):

self.add_callback('user_readback', self._on_pv_changed)

self._emit_move.connect(self.move)

def call_emit_move(self, position, wait=True, kwargs={}):
"""
a thread safe way to call move from a signal handler
:param position:
:param wait:
:param kwargs:
:return:
"""
self._emit_move.emit(position, wait)

def is_connected(self):
"""

Expand Down Expand Up @@ -556,141 +570,6 @@ def within_limits(self, val):
return (val <= self.get(hl_name) and val >= self.get(ll_name))

# def move(self, position=None, relative=False, wait=False, timeout=300.0,
# dial=False, step=False, raw=False,
# ignore_limits=False, confirm_move=False):
# """
# arguments:
# ==========
# val value to move to (float) [Must be provided]
# relative move relative to current position (T/F) [F]
# wait whether to wait for move to complete (T/F) [F]
# dial use dial coordinates (T/F) [F]
# raw use raw coordinates (T/F) [F]
# step use raw coordinates (backward compat)(T/F) [F]
# ignore_limits try move without regard to limits (T/F) [F]
# confirm_move try to confirm that move has begun (T/F) [F]
# timeout max time for move to complete (in seconds) [300]
#
# return values:
# -13 : invalid value (cannot convert to float). Move not attempted.
# -12 : target value outside soft limits. Move not attempted.
# -11 : drive PV is not connected: Move not attempted.
# -8 : move started, but timed-out.
# -7 : move started, timed-out, but appears done.
# -5 : move started, unexpected return value from PV.put()
# -4 : move-with-wait finished, soft limit violation seen
# -3 : move-with-wait finished, hard limit violation seen
# 0 : move-with-wait finish OK.
# 0 : move-without-wait executed, not cpmfirmed
# 1 : move-without-wait executed, move confirmed
# 3 : move-without-wait finished, hard limit violation seen
# 4 : move-without-wait finished, soft limit violation seen
# """
# if self.within_limits(position):
# super().move(position, wait=wait)#, wait=wait, timeout=timeout,
# # dial=dial, step=step, raw=raw,
# # ignore_limits=ignore_limits, confirm_move=confirm_move)
# return 0
# else:
# _logger.error(f"{self.name}: Move to [{position}] would violate the limits")
# return -12


#
# def move(self, val=None, relative=False, wait=False, timeout=300.0,
# dial=False, step=False, raw=False,
# ignore_limits=False, confirm_move=False):
# """ moves motor drive to position
#
# arguments:
# ==========
# val value to move to (float) [Must be provided]
# relative move relative to current position (T/F) [F]
# wait whether to wait for move to complete (T/F) [F]
# dial use dial coordinates (T/F) [F]
# raw use raw coordinates (T/F) [F]
# step use raw coordinates (backward compat)(T/F) [F]
# ignore_limits try move without regard to limits (T/F) [F]
# confirm_move try to confirm that move has begun (T/F) [F]
# timeout max time for move to complete (in seconds) [300]
#
# return values:
# -13 : invalid value (cannot convert to float). Move not attempted.
# -12 : target value outside soft limits. Move not attempted.
# -11 : drive PV is not connected: Move not attempted.
# -8 : move started, but timed-out.
# -7 : move started, timed-out, but appears done.
# -5 : move started, unexpected return value from PV.put()
# -4 : move-with-wait finished, soft limit violation seen
# -3 : move-with-wait finished, hard limit violation seen
# 0 : move-with-wait finish OK.
# 0 : move-without-wait executed, not cpmfirmed
# 1 : move-without-wait executed, move confirmed
# 3 : move-without-wait finished, hard limit violation seen
# 4 : move-without-wait finished, soft limit violation seen
#
# """
# step = step or raw
#
# NONFLOAT, OUTSIDE_LIMITS, UNCONNECTED = -13, -12, -11
# TIMEOUT, TIMEOUT_BUTDONE = -8, -7
# UNKNOWN_ERROR = -5
# DONEW_SOFTLIM, DONEW_HARDLIM = -4, -3
# DONE_OK = 0
# MOVE_BEGUN, MOVE_BEGUN_CONFIRMED = 0, 1
# NOWAIT_SOFTLIM, NOWAIT_HARDLIM = 4, 3
# try:
# val = float(val)
# except TypeError:
# return NONFLOAT
#
# drv, rbv = ('setpoint', 'readback')
#
# if relative:
# val += self.get(drv)
#
# # Check for limit violations
# if not ignore_limits and not step:
# if not self.within_limits(val):
# return OUTSIDE_LIMITS
#
# if (self._collision_support):
# stat = self.put('check_tr.A', val, wait=wait, timeout=timeout)
# else:
# stat = self.put(drv, val, wait=wait, timeout=timeout)
#
# if stat is None:
# return UNCONNECTED
#
# if wait and stat == -1: # move started, exceeded timeout
# if self.get('DMOV') == 0:
# return TIMEOUT
# return TIMEOUT_BUTDONE
# if 1 == stat:
# if wait: # ... and finished OK
# if 1 == self.get('soft_limit'):
# return DONEW_SOFTLIM
# elif 1 == self.get('high_limit_set') or 1 == self.get('low_limit_set'):
# return DONEW_HARDLIM
# return DONE_OK
# else:
# if 1 == self.get('soft_limit') or confirm_move:
# ca.poll(evt=1.e-2)
# moving = False
# if confirm_move:
# t0 = time.time()
# while self.get('MOVN') == 0:
# ca.poll(evt=1.e-3)
# if time.time() - t0 > 0.25: break
# if 1 == self.get('MOVN'):
# return MOVE_BEGUN_CONFIRMED
# elif 1 == self.get('soft_limit'):
# return NOWAIT_SOFTLIM
# elif 1 == self.get('high_limit_set') or 1 == self.get('low_limit_set'):
# return NOWAIT_HARDLIM
# else:
# return MOVE_BEGUN
# return UNKNOWN_ERROR
#
def confirm_stopped(self):
t = 0
Expand Down Expand Up @@ -730,14 +609,7 @@ def wait_for_stopped_and_zero(self):
self.set_position(0.0)
# print '%s setting zero' % self.signal_name

# def move_and_set_position(self, pos, setpos):
# self.move(pos)
# # print 'waiting for %s to stop' % self.signal_name
# self.confirm_stopped()
# # print '%s has now stopped' % self.signal_name
# self.set_position(setpos)
# # print '%s setting zero' % self.signal_name
#



class MotorLimitException(Exception):
Expand All @@ -762,7 +634,8 @@ def __str__(self):
return str(self.msg)


class EnergyMotor(EpicsMotor):
# class EnergyMotor(EpicsMotor):
class EnergyMotor(MotorQt):
"""just a convienience class so that PVs can be configured in the beamline configuration file
and used as if they were other devices, making the rest of the code cleaner
"""
Expand Down Expand Up @@ -849,8 +722,8 @@ def __init__(self, *args, **kwargs):
# app = QtWidgets.QApplication(sys.argv)

# m = Motor_Qt('SIM_IOC:m704', name='m704', pos_set=1, collision_support=False, report_fields= True )
zpz = MotorQt("SIM_IOC:m704", name="zpz_mtr")
zp1 = Zoneplate("MYZONER", "zp1", zpz, -4.839514, 100, 45, 60)
#zpz = MotorQt("SIM_IOC:m704", name="zpz_mtr")
zp1 = Zoneplate("MYZONER", "zp1", "a1", -4.839514, 100, 45, 60)
zp2 = Zoneplate("MYZONER", "zp2", zpz, -6.791682, 240, 90, 35)
zp3 = Zoneplate("MYZONER", "zp3", zpz, -7.76662, 240, 90, 40)
zp4 = Zoneplate("MYZONER", "zp4", zpz, -4.524239, 140, 60, 40)
Expand Down
2 changes: 1 addition & 1 deletion bcm/devices/ophyd/stxm_sample_mtr.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ def do_interferometer_check(self):

d_rng = math.fabs(cfbk - ffbk)
if d_rng > self.min_interfer_reset_range:
print(f"do_interferometer_check: (delta range) {d_rng} > {self.min_interfer_reset_range}(MIN_INTERFER_RESET_RANGE_UM) range too large Resetting interferometer")
print(f"do_interferometer_check: (delta range coarse to fine fbk) {d_rng} > {self.min_interfer_reset_range}(MIN_INTERFER_RESET_RANGE_UM) range too large Resetting interferometer")
self.reset_interferometers()

#if we did a reset, loop here until the feedbacks match
Expand Down
Loading