From 27aab8bb14a4bf563d47b46a832ebd3065955901 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Sat, 22 Sep 2018 13:57:47 +1000 Subject: [PATCH 01/10] pep8 --- pocs/focuser/focuser.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index 9111df642..978198748 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -53,6 +53,7 @@ class AbstractFocuser(PanBase): autofocus_spline_smoothing (float, optional): smoothing parameter for the spline fitting to the autofocus data, 0.0 to 1.0, smaller values mean *less* smoothing, default 0.4 """ + def __init__(self, name='Generic Focuser', model='simulator', @@ -456,7 +457,8 @@ def _autofocus(self, for i, position in enumerate(focus_positions): thumbnail = np.ma.array(thumbnails[i], mask=master_mask) - metric[i] = focus_utils.focus_metric(thumbnail, merit_function, **merit_function_kwargs) + metric[i] = focus_utils.focus_metric( + thumbnail, merit_function, **merit_function_kwargs) fitted = False From a4cf0631223433be35f398e7c9ffdecca76115d7 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Sat, 22 Sep 2018 14:09:06 +1000 Subject: [PATCH 02/10] * Removing spline smoothing from focusing * Take darks after the coarse focus --- pocs/focuser/focuser.py | 76 +++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index 978198748..61b2012ea 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -50,8 +50,6 @@ class AbstractFocuser(PanBase): for the merit function. autofocus_mask_dilations (int, optional): Number of iterations of dilation to perform on the saturated pixel mask (determine size of masked regions), default 10 - autofocus_spline_smoothing (float, optional): smoothing parameter for the spline fitting to - the autofocus data, 0.0 to 1.0, smaller values mean *less* smoothing, default 0.4 """ def __init__(self, @@ -69,7 +67,6 @@ def __init__(self, autofocus_merit_function=None, autofocus_merit_function_kwargs=None, autofocus_mask_dilations=None, - autofocus_spline_smoothing=None, *args, **kwargs): super().__init__(*args, **kwargs) @@ -180,7 +177,6 @@ def autofocus(self, merit_function=None, merit_function_kwargs=None, mask_dilations=None, - spline_smoothing=None, coarse=False, plots=True, blocking=False, @@ -214,8 +210,6 @@ def autofocus(self, keyword arguments for the merit function. mask_dilations (int, optional): Number of iterations of dilation to perform on the saturated pixel mask (determine size of masked regions), default 10 - spline_smoothing (float, optional): smoothing parameter for the spline fitting to - the autofocus data, 0.0 to 1.0, smaller values mean *less* smoothing, default 0.4 coarse (bool, optional): Whether to begin with coarse focusing, default False. plots (bool, optional: Whether to write focus plots to images folder, default True. blocking (bool, optional): Whether to block until autofocus complete, default False. @@ -286,35 +280,6 @@ def autofocus(self, else: mask_dilations = 10 - if spline_smoothing is None: - if self.autofocus_spline_smoothing is not None: - spline_smoothing = self.autofocus_spline_smoothing - else: - spline_smoothing = 0.4 - - if take_dark: - image_dir = self.config['directories']['images'] - start_time = current_time(flatten=True) - file_path = "{}/{}/{}/{}/{}.{}".format(image_dir, - 'focus', - self._camera.uid, - start_time, - "dark", - self._camera.file_extension) - self.logger.debug('Taking dark frame {} on camera {}'.format(file_path, self._camera)) - try: - dark_thumb = self._camera.get_thumbnail(seconds, - file_path, - thumbnail_size, - keep_file=True, - dark=True) - # Mask 'saturated' with a low threshold to remove hot pixels - dark_thumb = focus_utils.mask_saturated(dark_thumb, threshold=0.3) - except TypeError: - self.logger.warning("Camera {} does not support dark frames!".format(self._camera)) - else: - dark_thumb = None - if coarse: coarse_event = Event() coarse_thread = Thread(target=self._autofocus, @@ -324,7 +289,7 @@ def autofocus(self, 'focus_step': focus_step, 'thumbnail_size': thumbnail_size, 'keep_files': keep_files, - 'dark_thumb': dark_thumb, + 'take_dark': take_dark, 'merit_function': merit_function, 'merit_function_kwargs': merit_function_kwargs, 'mask_dilations': mask_dilations, @@ -333,7 +298,8 @@ def autofocus(self, 'plots': plots, 'start_event': None, 'finished_event': coarse_event, - **kwargs}) + **kwargs} + ) coarse_thread.start() else: coarse_event = None @@ -346,7 +312,7 @@ def autofocus(self, 'focus_step': focus_step, 'thumbnail_size': thumbnail_size, 'keep_files': keep_files, - 'dark_thumb': dark_thumb, + 'take_dark': take_dark, 'merit_function': merit_function, 'merit_function_kwargs': merit_function_kwargs, 'mask_dilations': mask_dilations, @@ -402,6 +368,22 @@ def _autofocus(self, self._camera.uid, start_time) + if take_dark: + file_path = os.path.join(file_path_root, 'dark', self._camera.file_extension) + self.logger.debug('Taking dark frame {} on camera {}'.format(file_path, self._camera)) + try: + dark_thumb = self._camera.get_thumbnail(seconds, + file_path, + thumbnail_size, + keep_file=True, + dark=True) + # Mask 'saturated' with a low threshold to remove hot pixels + dark_thumb = focus_utils.mask_saturated(dark_thumb, threshold=0.3) + except TypeError: + self.logger.warning("Camera {} does not support dark frames!".format(self._camera)) + else: + dark_thumb = None + # Take an image before focusing, grab a thumbnail from the centre and add it to the plot file_path = "{}/{}_{}.{}".format(file_path_root, initial_focus, "initial", self._camera.file_extension) @@ -495,14 +477,20 @@ def _autofocus(self, fitted = True # Guard against fitting failures, force best focus to stay within sweep range - if best_focus < focus_positions[0]: - self.logger.warning("Fitting failure: best focus {} below sweep limit {}".format(best_focus, - focus_positions[0])) + min_focus = focus_positions[0] + max_focus = focus_positions[-1] + if best_focus < min_focus: + self.logger.warning("Fitting failure: best focus {} below sweep limit {}", + best_focus, + min_focus) + best_focus = focus_positions[1] - if best_focus > focus_positions[-1]: - self.logger.warning("Fitting failure: best focus {} above sweep limit {}".format(best_focus, - focus_positions[-1])) + if best_focus > max_focus: + self.logger.warning("Fitting failure: best focus {} above sweep limit {}", + best_focus, + max_focus) + best_focus = focus_positions[-2] else: From 31564da5ef6331f75840b882c95480443d443579 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Sat, 22 Sep 2018 14:45:00 +1000 Subject: [PATCH 03/10] Missed a line --- pocs/focuser/focuser.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index 61b2012ea..7cb7c3027 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -99,7 +99,6 @@ def __init__(self, self.autofocus_merit_function = autofocus_merit_function self.autofocus_merit_function_kwargs = autofocus_merit_function_kwargs self.autofocus_mask_dilations = autofocus_mask_dilations - self.autofocus_spline_smoothing = autofocus_spline_smoothing self._camera = camera From e1a21db83f48aeabce36d609a0c11bafeb9207f1 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Sat, 22 Sep 2018 15:40:05 +1000 Subject: [PATCH 04/10] Add the spline_smoothing to the focuser autofocus --- pocs/focuser/focuser.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index 7cb7c3027..990d2eb04 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -176,6 +176,7 @@ def autofocus(self, merit_function=None, merit_function_kwargs=None, mask_dilations=None, + spline_smoothing=None, coarse=False, plots=True, blocking=False, @@ -209,6 +210,8 @@ def autofocus(self, keyword arguments for the merit function. mask_dilations (int, optional): Number of iterations of dilation to perform on the saturated pixel mask (determine size of masked regions), default 10 + spline_smoothing (float, optional): smoothing parameter for the spline fitting to + the autofocus data, 0.0 to 1.0, smaller values mean *less* smoothing, default 0.4 coarse (bool, optional): Whether to begin with coarse focusing, default False. plots (bool, optional: Whether to write focus plots to images folder, default True. blocking (bool, optional): Whether to block until autofocus complete, default False. From 729903f760860ea5328e72ee8dd7bbe5880ac990 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Sat, 22 Sep 2018 19:30:37 +1000 Subject: [PATCH 05/10] * Fix import * Fix some dark_thumb changes * Use os.path.join --- pocs/focuser/focuser.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index 990d2eb04..a6e916f94 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -1,3 +1,4 @@ +import os import matplotlib.colors as colours import matplotlib.pyplot as plt @@ -159,11 +160,11 @@ def max_position(self): ################################################################################################## def move_to(self, position): - """ Move focusser to new encoder position """ + """ Move focuser to new encoder position """ raise NotImplementedError def move_by(self, increment): - """ Move focusser by a given amount """ + """ Move focuser by a given amount """ return self.move_to(self.position + increment) def autofocus(self, @@ -219,6 +220,7 @@ def autofocus(self, Returns: threading.Event: Event that will be set when autofocusing is complete """ + self.logger.debug('Starting autofocus') assert self._camera.is_connected, self.logger.error( "Camera must be connected for autofocus!") @@ -324,6 +326,7 @@ def autofocus(self, 'start_event': coarse_event, 'finished_event': fine_event, **kwargs}) + fine_thread.start() if blocking: @@ -337,7 +340,7 @@ def _autofocus(self, focus_step, thumbnail_size, keep_files, - dark_thumb, + take_dark, merit_function, merit_function_kwargs, coarse, @@ -348,6 +351,7 @@ def _autofocus(self, spline_smoothing, *args, **kwargs): + # If passed a start_event wait until Event is set before proceeding # (e.g. wait for coarse focus to finish before starting fine focus). if start_event: @@ -365,13 +369,15 @@ def _autofocus(self, # Set up paths for temporary focus files, and plots if requested. image_dir = self.config['directories']['images'] start_time = current_time(flatten=True) - file_path_root = "{}/{}/{}/{}".format(image_dir, - 'focus', - self._camera.uid, - start_time) + file_path_root = os.path.join(image_dir, + 'focus', + self._camera.uid, + start_time) + dark_thumb = None if take_dark: - file_path = os.path.join(file_path_root, 'dark', self._camera.file_extension) + file_path = os.path.join(file_path_root, '{}.{}'.format( + 'dark', self._camera.file_extension)) self.logger.debug('Taking dark frame {} on camera {}'.format(file_path, self._camera)) try: dark_thumb = self._camera.get_thumbnail(seconds, @@ -383,12 +389,11 @@ def _autofocus(self, dark_thumb = focus_utils.mask_saturated(dark_thumb, threshold=0.3) except TypeError: self.logger.warning("Camera {} does not support dark frames!".format(self._camera)) - else: - dark_thumb = None # Take an image before focusing, grab a thumbnail from the centre and add it to the plot - file_path = "{}/{}_{}.{}".format(file_path_root, initial_focus, - "initial", self._camera.file_extension) + file_path = os.path.join(file_path_root, "{}_{}.{}".format( + initial_focus, "initial", self._camera.file_extension)) + thumbnail = self._camera.get_thumbnail(seconds, file_path, thumbnail_size, keep_file=True) if plots: From f8a245408a667a5700e81b1622ce81fad1783265 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Sun, 23 Sep 2018 07:05:53 +1000 Subject: [PATCH 06/10] Tried to do a big cleanup here to make this method a little more manageable. Would like to split out the plotting and fitting into separate helper methods but am going to leave for now. * All plotting moved to one location. * Figure out `focus_type` string so no `if` logic for logging output. * More cleanup of paths. --- pocs/focuser/focuser.py | 121 ++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index a6e916f94..c6d58d919 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -351,20 +351,23 @@ def _autofocus(self, spline_smoothing, *args, **kwargs): + """Private helper method for calling autofocus in a Thread. + + See public `autofocus` for information about the parameters. + """ # If passed a start_event wait until Event is set before proceeding # (e.g. wait for coarse focus to finish before starting fine focus). if start_event: start_event.wait() - initial_focus = self.position + focus_type = 'fine' if coarse: - self.logger.debug( - "Beginning coarse autofocus of {} - initial position: {}", - self._camera, initial_focus) - else: - self.logger.debug( - "Beginning autofocus of {} - initial position: {}", self._camera, initial_focus) + focus_type = 'coarse' + + initial_focus = self.position + self.logger.debug("Beginning {} autofocus of {} - initial position: {}", + focus_type, self._camera, initial_focus) # Set up paths for temporary focus files, and plots if requested. image_dir = self.config['directories']['images'] @@ -376,12 +379,12 @@ def _autofocus(self, dark_thumb = None if take_dark: - file_path = os.path.join(file_path_root, '{}.{}'.format( - 'dark', self._camera.file_extension)) - self.logger.debug('Taking dark frame {} on camera {}'.format(file_path, self._camera)) + dark_path = os.path.join(file_path_root, + '{}.{}'.format('dark', self._camera.file_extension)) + self.logger.debug('Taking dark frame {} on camera {}'.format(dark_path, self._camera)) try: dark_thumb = self._camera.get_thumbnail(seconds, - file_path, + dark_path, thumbnail_size, keep_file=True, dark=True) @@ -391,24 +394,11 @@ def _autofocus(self, self.logger.warning("Camera {} does not support dark frames!".format(self._camera)) # Take an image before focusing, grab a thumbnail from the centre and add it to the plot - file_path = os.path.join(file_path_root, "{}_{}.{}".format( - initial_focus, "initial", self._camera.file_extension)) - - thumbnail = self._camera.get_thumbnail(seconds, file_path, thumbnail_size, keep_file=True) - - if plots: - thumbnail = focus_utils.mask_saturated(thumbnail) - if dark_thumb is not None: - thumbnail = thumbnail - dark_thumb - - fig = Figure() - FigureCanvas(fig) - fig.set_size_inches(9, 18) + initial_fn = "{}_{}.{}".format(initial_focus, "initial", self._camera.file_extension) + initial_path = os.path.join(file_path_root, initial_fn) - ax1 = fig.add_subplot(3, 1, 1) - im1 = ax1.imshow(thumbnail, interpolation='none', cmap=palette, norm=colours.LogNorm()) - fig.colorbar(im1) - ax1.set_title('Initial focus position: {}'.format(initial_focus)) + initial_thumbnail = self._camera.get_thumbnail( + seconds, initial_path, thumbnail_size, keep_file=True) # Set up encoder positions for autofocus sweep, truncating at focus travel # limits if required. @@ -423,17 +413,21 @@ def _autofocus(self, min(initial_focus + focus_range / 2, self.max_position) + 1, focus_step, dtype=np.int) n_positions = len(focus_positions) - thumbnails = np.zeros((n_positions, thumbnail_size, thumbnail_size), dtype=thumbnail.dtype) + + thumbnails = np.zeros((n_positions, thumbnail_size, thumbnail_size), + dtype=initial_thumbnail.dtype) masks = np.empty((n_positions, thumbnail_size, thumbnail_size), dtype=np.bool) metric = np.empty(n_positions) + # Take and store an exposure for each focus position. for i, position in enumerate(focus_positions): # Move focus, updating focus_positions with actual encoder position after move. focus_positions[i] = self.move_to(position) # Take exposure - file_path = "{}/{}_{}.{}".format(file_path_root, - focus_positions[i], i, self._camera.file_extension) + focus_fn = "{}_{:02d}.{}".format(focus_positions[i], i, self._camera.file_extension) + file_path = os.path.join(file_path_root, focus_fn) + thumbnail = self._camera.get_thumbnail( seconds, file_path, thumbnail_size, keep_file=keep_files) masks[i] = focus_utils.mask_saturated(thumbnail).mask @@ -444,8 +438,9 @@ def _autofocus(self, master_mask = masks.any(axis=0) master_mask = binary_dilation(master_mask, iterations=mask_dilations) - for i, position in enumerate(focus_positions): - thumbnail = np.ma.array(thumbnails[i], mask=master_mask) + # Apply the master mask and then get metrics for each frame. + for i, thumbnail in enumerate(thumbnails): + thumbnail = np.ma.array(thumbnail, mask=master_mask) metric[i] = focus_utils.focus_metric( thumbnail, merit_function, **merit_function_kwargs) @@ -504,7 +499,31 @@ def _autofocus(self, # Coarse focus, just use max value. best_focus = focus_positions[imax] + final_focus = self.move_to(best_focus) + + final_fn = "{}_{}.{}".format(final_focus, "final", self._camera.file_extension) + file_path = os.path.join(file_path_root, final_fn) + + final_thumbnail = self._camera.get_thumbnail( + seconds, file_path, thumbnail_size, keep_file=True) + if plots: + initial_thumbnail = focus_utils.mask_saturated(initial_thumbnail) + final_thumbnail = focus_utils.mask_saturated(final_thumbnail) + if dark_thumb is not None: + initial_thumbnail = initial_thumbnail - dark_thumb + final_thumbnail = final_thumbnail - dark_thumb + + fig = Figure() + FigureCanvas(fig) + fig.set_size_inches(9, 18) + + ax1 = fig.add_subplot(3, 1, 1) + im1 = ax1.imshow(initial_thumbnail, interpolation='none', + cmap=palette, norm=colours.LogNorm()) + fig.colorbar(im1) + ax1.set_title('Initial focus position: {}'.format(initial_focus)) + ax2 = fig.add_subplot(3, 1, 2) ax2.plot(focus_positions, metric, 'bo', label='{}'.format(merit_function)) if fitted: @@ -520,42 +539,26 @@ def _autofocus(self, label='Initial focus') ax2.vlines(best_focus, l_limit, u_limit, colors='k', linestyles='--', label='Best focus') + ax2.set_xlabel('Focus position') ax2.set_ylabel('Focus metric') - if coarse: - ax2.set_title('{} coarse focus at {}'.format(self._camera, start_time)) - else: - ax2.set_title('{} fine focus at {}'.format(self._camera, start_time)) - ax2.legend(loc='best') - - final_focus = self.move_to(best_focus) - file_path = "{}/{}_{}.{}".format(file_path_root, final_focus, - "final", self._camera.file_extension) - thumbnail = self._camera.get_thumbnail(seconds, file_path, thumbnail_size, keep_file=True) + ax2.set_title('{} {} focus at {}'.format(self._camera, focus_type, start_time)) + ax2.legend(loc='best') - if plots: - thumbnail = focus_utils.mask_saturated(thumbnail) - if dark_thumb is not None: - thumbnail = thumbnail - dark_thumb ax3 = fig.add_subplot(3, 1, 3) - im3 = ax3.imshow(thumbnail, interpolation='none', cmap=palette, norm=colours.LogNorm()) + im3 = ax3.imshow(final_thumbnail, interpolation='none', + cmap=palette, norm=colours.LogNorm()) fig.colorbar(im3) ax3.set_title('Final focus position: {}'.format(final_focus)) - if coarse: - plot_path = file_path_root + '_coarse.png' - else: - plot_path = file_path_root + '_fine.png' + plot_path = os.path.join(file_path_root, '{}_focus.png'.format(focus_type)) fig.tight_layout() - fig.savefig(plot_path) + fig.savefig(plot_path, transparent=False) plt.close(fig) - if coarse: - self.logger.info('Coarse focus plot for camera {} written to {}'.format( - self._camera, plot_path)) - else: - self.logger.info('Fine focus plot for camera {} written to {}'.format( - self._camera, plot_path)) + + self.logger.info('{} focus plot for camera {} written to {}'.format( + focus_type.capitalize(), self._camera, plot_path)) self.logger.debug( 'Autofocus of {} complete - final focus position: {}', self._camera, final_focus) From 73cbe7519e6085015cf5b9d8adf2592450667d14 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Sun, 23 Sep 2018 07:28:12 +1000 Subject: [PATCH 07/10] Only take final thumbnail if plotting --- pocs/focuser/focuser.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index c6d58d919..363ad6147 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -501,14 +501,14 @@ def _autofocus(self, final_focus = self.move_to(best_focus) - final_fn = "{}_{}.{}".format(final_focus, "final", self._camera.file_extension) - file_path = os.path.join(file_path_root, final_fn) - - final_thumbnail = self._camera.get_thumbnail( - seconds, file_path, thumbnail_size, keep_file=True) - if plots: initial_thumbnail = focus_utils.mask_saturated(initial_thumbnail) + + final_fn = "{}_{}.{}".format(final_focus, "final", self._camera.file_extension) + file_path = os.path.join(file_path_root, final_fn) + + final_thumbnail = self._camera.get_thumbnail( + seconds, file_path, thumbnail_size, keep_file=True) final_thumbnail = focus_utils.mask_saturated(final_thumbnail) if dark_thumb is not None: initial_thumbnail = initial_thumbnail - dark_thumb From d76bff79e08a745f195dbda4ad04026a2129aab5 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Mon, 24 Sep 2018 07:05:22 +1000 Subject: [PATCH 08/10] Cleanup of focus * Pull out shared parameters from focus * Rearranged underlying _autofocus params to reflect how focus_parmas is set up (which is a more logical order - doesn't really matter in the end). --- pocs/focuser/focuser.py | 73 ++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index 363ad6147..559ecb9c9 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -216,9 +216,14 @@ def autofocus(self, coarse (bool, optional): Whether to begin with coarse focusing, default False. plots (bool, optional: Whether to write focus plots to images folder, default True. blocking (bool, optional): Whether to block until autofocus complete, default False. + *args: Optional arguments passed to focus procedure. + **kwargs: Optional keyword arguments passed to focus procedure. Returns: threading.Event: Event that will be set when autofocusing is complete + + Raises: + ValueError: If invalid values are passed for any of the focus parameters. """ self.logger.debug('Starting autofocus') assert self._camera.is_connected, self.logger.error( @@ -284,49 +289,41 @@ def autofocus(self, else: mask_dilations = 10 + # Set up the focus parameters + focus_params = { + 'seconds': seconds, + 'focus_range': focus_range, + 'focus_step': focus_step, + 'thumbnail_size': thumbnail_size, + 'keep_files': keep_files, + 'take_dark': take_dark, + 'merit_function': merit_function, + 'merit_function_kwargs': merit_function_kwargs, + 'mask_dilations': mask_dilations, + 'spline_smoothing': spline_smoothing, + 'plots': plots, + 'start_event': None, + 'finished_event': None, + } + + # Coarse focus if coarse: coarse_event = Event() - coarse_thread = Thread(target=self._autofocus, - args=args, - kwargs={'seconds': seconds, - 'focus_range': focus_range, - 'focus_step': focus_step, - 'thumbnail_size': thumbnail_size, - 'keep_files': keep_files, - 'take_dark': take_dark, - 'merit_function': merit_function, - 'merit_function_kwargs': merit_function_kwargs, - 'mask_dilations': mask_dilations, - 'spline_smoothing': spline_smoothing, - 'coarse': True, - 'plots': plots, - 'start_event': None, - 'finished_event': coarse_event, - **kwargs} - ) + focus_params['finished_event'] = coarse_event + focus_params['coarse'] = True + + coarse_thread = Thread(target=self._autofocus, kwargs=focus_params) coarse_thread.start() else: coarse_event = None + # Fine Focus - This will wait for the coarse_event to finish. fine_event = Event() - fine_thread = Thread(target=self._autofocus, - args=args, - kwargs={'seconds': seconds, - 'focus_range': focus_range, - 'focus_step': focus_step, - 'thumbnail_size': thumbnail_size, - 'keep_files': keep_files, - 'take_dark': take_dark, - 'merit_function': merit_function, - 'merit_function_kwargs': merit_function_kwargs, - 'mask_dilations': mask_dilations, - 'spline_smoothing': spline_smoothing, - 'coarse': False, - 'plots': plots, - 'start_event': coarse_event, - 'finished_event': fine_event, - **kwargs}) + focus_params['start_event'] = coarse_event + focus_params['finished_event'] = fine_event + focus_params['coarse'] = False + fine_thread = Thread(target=self._autofocus, kwargs=focus_params) fine_thread.start() if blocking: @@ -343,12 +340,12 @@ def _autofocus(self, take_dark, merit_function, merit_function_kwargs, - coarse, + mask_dilations, + spline_smoothing, plots, + coarse, start_event, finished_event, - mask_dilations, - spline_smoothing, *args, **kwargs): """Private helper method for calling autofocus in a Thread. From c292f96720cbd64d6cddb4bce726c5c755866d16 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Mon, 24 Sep 2018 07:06:10 +1000 Subject: [PATCH 09/10] Strip out the args and kwargs as they are unused. --- pocs/focuser/focuser.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index 559ecb9c9..01ca950f0 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -180,8 +180,7 @@ def autofocus(self, spline_smoothing=None, coarse=False, plots=True, - blocking=False, - *args, **kwargs): + blocking=False): """ Focuses the camera using the specified merit function. Optionally performs a coarse focus first before performing the default fine focus. The @@ -216,8 +215,6 @@ def autofocus(self, coarse (bool, optional): Whether to begin with coarse focusing, default False. plots (bool, optional: Whether to write focus plots to images folder, default True. blocking (bool, optional): Whether to block until autofocus complete, default False. - *args: Optional arguments passed to focus procedure. - **kwargs: Optional keyword arguments passed to focus procedure. Returns: threading.Event: Event that will be set when autofocusing is complete From 705ab69d3657560818e978f566ba0ad5f6ae1978 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Mon, 24 Sep 2018 16:59:36 +1000 Subject: [PATCH 10/10] Removing all `spline_smoothing` parameters --- pocs/camera/camera.py | 4 ---- pocs/focuser/focuser.py | 5 ----- 2 files changed, 9 deletions(-) diff --git a/pocs/camera/camera.py b/pocs/camera/camera.py index d25fd204b..501ecca35 100644 --- a/pocs/camera/camera.py +++ b/pocs/camera/camera.py @@ -300,7 +300,6 @@ def autofocus(self, merit_function='vollath_F4', merit_function_kwargs={}, mask_dilations=None, - spline_smoothing=None, coarse=False, plots=True, blocking=False, @@ -334,8 +333,6 @@ def autofocus(self, keyword arguments for the merit function. mask_dilations (int, optional): Number of iterations of dilation to perform on the saturated pixel mask (determine size of masked regions), default 10 - spline_smoothing (float, optional): smoothing parameter for the spline fitting to - the autofocus data, 0.0 to 1.0, smaller values mean *less* smoothing, default 0.4 coarse (bool, optional): Whether to begin with coarse focusing, default False plots (bool, optional: Whether to write focus plots to images folder, @@ -359,7 +356,6 @@ def autofocus(self, merit_function=merit_function, merit_function_kwargs=merit_function_kwargs, mask_dilations=mask_dilations, - spline_smoothing=spline_smoothing, coarse=coarse, plots=plots, blocking=blocking, diff --git a/pocs/focuser/focuser.py b/pocs/focuser/focuser.py index 01ca950f0..c810e5b94 100644 --- a/pocs/focuser/focuser.py +++ b/pocs/focuser/focuser.py @@ -177,7 +177,6 @@ def autofocus(self, merit_function=None, merit_function_kwargs=None, mask_dilations=None, - spline_smoothing=None, coarse=False, plots=True, blocking=False): @@ -210,8 +209,6 @@ def autofocus(self, keyword arguments for the merit function. mask_dilations (int, optional): Number of iterations of dilation to perform on the saturated pixel mask (determine size of masked regions), default 10 - spline_smoothing (float, optional): smoothing parameter for the spline fitting to - the autofocus data, 0.0 to 1.0, smaller values mean *less* smoothing, default 0.4 coarse (bool, optional): Whether to begin with coarse focusing, default False. plots (bool, optional: Whether to write focus plots to images folder, default True. blocking (bool, optional): Whether to block until autofocus complete, default False. @@ -297,7 +294,6 @@ def autofocus(self, 'merit_function': merit_function, 'merit_function_kwargs': merit_function_kwargs, 'mask_dilations': mask_dilations, - 'spline_smoothing': spline_smoothing, 'plots': plots, 'start_event': None, 'finished_event': None, @@ -338,7 +334,6 @@ def _autofocus(self, merit_function, merit_function_kwargs, mask_dilations, - spline_smoothing, plots, coarse, start_event,