Comments (2)
In particular, it seems that if a scipy optimization fails with an error, the function does not return and all the buttons remain greyed out
from qt3-utils.
Suggested changes
https://github.com/qt3uw/qt3-utils/blob/main/src/qt3utils/datagenerators/piezoscanner.py#L177-L190
change to:
optimal_position = axis_vals[np.argmax(count_rates)]
coeff = None
params = [np.max(count_rates), optimal_position, 1.0, np.min(count_rates)]
bounds = (len(params)*tuple((0,)), len(params)*tuple((np.inf,)))
try:
coeff, var_matrix = scipy.optimize.curve_fit(gauss, axis_vals, count_rates, p0=params, bounds=bounds)
optimal_position = coeff[1]
# ensure that the optimal position is within the scan range
optimal_position = np.max([min_val, optimal_position])
optimal_position = np.min([max_val, optimal_position])
except (ValueError, RuntimeError, OptimizeWarning) as e:
logger.warning(e) #this sends warning to logger
raise(e) # optionally, we could throw the error again after logging, and require that the caller handles the Exception
finally:
return count_rates, axis_vals, optimal_position, coeff
https://github.com/qt3uw/qt3-utils/blob/main/src/applications/piezoscan.py#L489-L507
change to
try:
data, axis_vals, opt_pos, coeff = self.counter_scanner.optimize_position(axis,
central,
range,
step_size)
except nidaqmx.errors.DaqError as e:
logger.error(e)
logger.error('NIDAQ Error. Check for other applications using resources. If not, you may need to restart the application.')
except (ValueError, RuntimeError, OptimizeWarning) as e:
logger.error(e)
finally:
self.optimized_position[axis] = opt_pos
self.counter_scanner.stage_controller.go_to_position(**{axis:opt_pos})
self.view.show_optimization_plot(f'Optimize {axis}',
central,
self.optimized_position[axis],
axis_vals,
data,
coeff)
self.view.sidepanel.update_go_to_position(**{axis:self.optimized_position[axis]})
self.view.sidepanel.startButton['state'] = 'normal'
self.view.sidepanel.stopButton['state'] = 'normal'
self.view.sidepanel.go_to_z_button['state'] = 'normal'
self.view.sidepanel.gotoButton['state'] = 'normal'
self.view.sidepanel.saveScanButton['state'] = 'normal'
self.view.sidepanel.popOutScanButton['state'] = 'normal'
self.view.sidepanel.optimize_x_button['state'] = 'normal'
self.view.sidepanel.optimize_y_button['state'] = 'normal'
self.view.sidepanel.optimize_z_button['state'] = 'normal'
Also, could use from tkinter import messagebox
to display error in window instead of on console. (Thanks to @cmordi for discovering that tool in tkinter..)
except nidaqmx.errors.DaqError as e:
error_msg = f"{e}\n NIDAQ Error. Check for other applications using resources. If not, you may need to restart the application."
messagebox.showerror("Error", error_msg)
except Exception as e:
messagebox.showerror("Error", e)
With the solution above, the piezo actuator will be moved to a new optimal position even if the scipy optimize function throws. The new optimal position will be the position with the maximum count rates. This, of course, could be changed. If it is desired to remain in the original position when scipy fails, then perhaps
change
https://github.com/qt3uw/qt3-utils/blob/main/src/qt3utils/datagenerators/piezoscanner.py#L162-L190
to
def optimize_position(self, axis, center_position, width = 2, step_size = 0.25, return_to_initial_on_failure = True):
""" (docstring omitted for brevity)
"""
min_val = center_position - width
max_val = center_position + width
if self.stage_controller:
min_val = np.max([min_val, self.stage_controller.minimum_allowed_position])
max_val = np.min([max_val, self.stage_controller.maximum_allowed_position])
else:
min_val = np.max([min_val, 0.0])
max_val = np.min([max_val, 80.0])
initial_position = self.stage_controller.get_current_position()
initial_position = {'x': initial_position[0], 'y': initial_position[1], 'z': initial_position[2]}
self.start()
raw_counts = self.scan_axis(axis, min_val, max_val, step_size)
self.stop()
axis_vals = np.arange(min_val, max_val, step_size)
count_rates = [self.sample_count_rate(count) for count in raw_counts]
optimal_position = axis_vals[np.argmax(count_rates)]
coeff = None
params = [np.max(count_rates), optimal_position, 1.0, np.min(count_rates)]
bounds = (len(params)*tuple((0,)), len(params)*tuple((np.inf,)))
try:
coeff, var_matrix = scipy.optimize.curve_fit(gauss, axis_vals, count_rates, p0=params, bounds=bounds)
optimal_position = coeff[1]
# ensure that the optimal position is within the scan range
optimal_position = np.max([min_val, optimal_position])
optimal_position = np.min([max_val, optimal_position])
except (ValueError, RuntimeError, OptimizeWarning) as e:
if return_to_initial_on_failure:
optimal_position = initial_position[axis]
logger.warning(e) #this sends warning to logger
raise(e) # optionally, we could throw the error again after logging, and require that the caller handles the Exception
finally:
return count_rates, axis_vals, optimal_position, coeff
and then call
return_to_initial = True # or False? could be configured as a GUI check box to control behavior
data, axis_vals, opt_pos, coeff = self.counter_scanner.optimize_position(axis,
central,
range,
step_size,
return_to_initial)
from qt3-utils.
Related Issues (20)
- Convert usage of piezo controller from nipiezojenapy to controller built into qt3-utils
- Add marker for current position for confocal scans
- Add Abstract Interface classes for qt3scope and qt3scan HOT 2
- Opening data / settings from file
- GUI functionality broken with Mac OS Sonoma HOT 1
- update bounds on optimization fitting in piezoscanner HOT 2
- small fix to comments in QT3ScanConfocalApplicationController HOT 1
- Make qt3scope more robust for experiments
- Does the structure of the Hyperspectral make sense in the context of the goal we are trying to achieve
- Add Spectrometer to QT3Scan
- Add DPG11 Pulser and Example Notebook
- Add Hyperspectral Scan capability directly in datagenerator
- qt3scan - allow for raster_line_pause setting in position controller object
- qt3scan - sample_count_rate function
- Hyperspectral scan: expanding from LF use to ANY spectrometer HOT 1
- Hyperspectral scan: nice-to-have features HOT 4
- X-Min and X-Max issues HOT 1
- Hyperspectral scan: Adding Andor spectrometer
- Lightfield Wavelengths
- Minor logic errors on qt3scan
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from qt3-utils.