From 6d113c4c95c984b5d3ddf6dc7574a94196d715eb Mon Sep 17 00:00:00 2001 From: David Baddeley Date: Tue, 22 Dec 2020 09:54:25 +1300 Subject: [PATCH 1/2] Only create stack settings if there are stages attached to microscope (and some refactoring) --- PYME/Acquire/ExecTools.py | 14 +++++------- PYME/Acquire/acquire_server.py | 5 +---- PYME/Acquire/microscope.py | 38 +++++++++++++++++++++++++++++++- PYME/Acquire/ui/HDFSpoolFrame.py | 14 +++++++----- PYME/Acquire/ui/seqdialog.py | 4 ++-- 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/PYME/Acquire/ExecTools.py b/PYME/Acquire/ExecTools.py index f3e4215d3..398336ac2 100755 --- a/PYME/Acquire/ExecTools.py +++ b/PYME/Acquire/ExecTools.py @@ -91,20 +91,18 @@ def execBG(codeObj, localVars = defLocals, globalVars = defGlobals): t.start() return t -def execFile(filename, localVars = defLocals, globalVars = defGlobals): +def execFile(filename, localVars = defLocals, globalVars = defGlobals, then=None): #fid = open(checkFilename(filename)) #code = fid.read() #fid.close() _execfile(filename, localVars, globalVars) + if then is not None: + then() -def execFileBG(filename, localVars = defLocals, globalVars = defGlobals): - #fid = open(checkFilename(filename)) - #code = fid.read() - #fid.close() - - #execBG(checkFilename(filename), localVars, globalVars) - threading.Thread(target=execFile, args = (filename, localVars, globalVars)).start() +def execFileBG(filename, localVars = defLocals, globalVars = defGlobals, then=None): + #return the thread so we can join it ... + return threading.Thread(target=execFile, args = (filename, localVars, globalVars, then)).start() def _bginit(name, codeObj): global defGlobals diff --git a/PYME/Acquire/acquire_server.py b/PYME/Acquire/acquire_server.py index 19cdb0702..0cbae8784 100755 --- a/PYME/Acquire/acquire_server.py +++ b/PYME/Acquire/acquire_server.py @@ -126,10 +126,7 @@ def _initialize_hardware(self): logger.debug('Init run, waiting on background threads') def _wait_for_init_complete(self): - while not self.scope.initDone: - time.sleep(0.1) - - #if self.scope.initDone == True: + self.scope.wait_for_init() logger.debug('Backround initialization done') def _on_frame_group(self, *args, **kwargs): diff --git a/PYME/Acquire/microscope.py b/PYME/Acquire/microscope.py index 7aacf2470..75ad8dd4a 100755 --- a/PYME/Acquire/microscope.py +++ b/PYME/Acquire/microscope.py @@ -877,7 +877,43 @@ def initialize(self, init_script_name, locals={}): locals.update(scope=self) ExecTools.setDefaultNamespace(locals, globals()) - ExecTools.execFileBG(init_script_name, locals, globals()) + self._init_thread = ExecTools.execFileBG(init_script_name, locals, globals(), then=self._post_init) + + return self._init_thread + + @property + def initialsed(self): + """ + Checks if the initialisation thread has run (replaces check of initDone flag which needed to be manually set + in initialisation script). Semantics are slightly different in that this returns true even if there is an error + whist the old way of checking would get forever stuck at the splash screen. + + Returns + ------- + + True if the initialisation script has run, False otherwise + + """ + try: + return not self._init_thread.is_alive() + except AttributeError: + # don't have and _init_thread yet + return False + + def wait_for_init(self): + self._init_thread.join() + + def _post_init(self): + """ + Called after the init script runs to do stuff based on what hardware is present + """ + + if len(self.positioning) > 0: + # we have registered piezos => we can do z-stacks + from PYME.Acquire import stackSettings + + # FIXME - this looks like it will create a circular reference + self.stackSettings = stackSettings.StackSettings(self) def register_piezo(self, piezo, axis_name, multiplier=1, needCamRestart=False, channel=0): """ diff --git a/PYME/Acquire/ui/HDFSpoolFrame.py b/PYME/Acquire/ui/HDFSpoolFrame.py index 842853c07..e91aea8a7 100755 --- a/PYME/Acquire/ui/HDFSpoolFrame.py +++ b/PYME/Acquire/ui/HDFSpoolFrame.py @@ -83,6 +83,9 @@ def _protocol_pan(self): self.rbZStepped = wx.RadioButton(pan, -1, 'Z stepped') self.rbZStepped.Bind(wx.EVT_RADIOBUTTON, self.OnToggleZStepping) hsizer.Add(self.rbZStepped, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2) + + if not hasattr(self.scope, 'stackSettings'): + self.rbZStepped.Disable() if self.spoolController.z_stepped: self.rbZStepped.SetValue(True) @@ -279,11 +282,12 @@ def _spool_pan(self): def _init_ctrls(self): self.AddNewElement(self._protocol_pan()) - clp = afp.collapsingPane(self, caption='Z stepping ...') - self._seq_panel = seqdialog.seqPanel(clp, self.scope, mode='sequence') - clp.AddNewElement(self._seq_panel) - self.AddNewElement(clp) - self.seq_pan = clp + if hasattr(self.scope, 'stackSettings'): + clp = afp.collapsingPane(self, caption='Z stepping ...') + self._seq_panel = seqdialog.seqPanel(clp, self.scope, mode='sequence') + clp.AddNewElement(self._seq_panel) + self.AddNewElement(clp) + self.seq_pan = clp self.AddNewElement(self._spool_to_pan()) diff --git a/PYME/Acquire/ui/seqdialog.py b/PYME/Acquire/ui/seqdialog.py index 020b68746..eeb512e6d 100755 --- a/PYME/Acquire/ui/seqdialog.py +++ b/PYME/Acquire/ui/seqdialog.py @@ -205,9 +205,9 @@ def __init__(self, parent, scope, mode='default'): #if not ('sa' in self.scope.__dict__): # self.stackSettings = simplesequenceaquisator.SimpleSequenceAquisitor(self.scope.chaninfo, self.scope.cam, self.scope.shutters, self.scope.piezos) - if not 'stackSettings' in dir(self.scope): + #if not 'stackSettings' in dir(self.scope): #inject stack settings into the scope object - self.scope.stackSettings = stackSettings.StackSettings(scope) + # self.scope.stackSettings = stackSettings.StackSettings(scope) #for pz in self.scope.piezos: # self.chPiezo.Append(pz[2]) From a541b08a5dff20872f1dc79f988a2093b59b66c9 Mon Sep 17 00:00:00 2001 From: David Baddeley Date: Tue, 12 Jan 2021 14:34:49 +1300 Subject: [PATCH 2/2] fix some typos in scope init code --- PYME/Acquire/ExecTools.py | 4 +++- PYME/Acquire/acquiremainframe.py | 2 +- PYME/Acquire/microscope.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/PYME/Acquire/ExecTools.py b/PYME/Acquire/ExecTools.py index 398336ac2..241980ff9 100755 --- a/PYME/Acquire/ExecTools.py +++ b/PYME/Acquire/ExecTools.py @@ -101,8 +101,10 @@ def execFile(filename, localVars = defLocals, globalVars = defGlobals, then=None then() def execFileBG(filename, localVars = defLocals, globalVars = defGlobals, then=None): + t = threading.Thread(target=execFile, args = (filename, localVars, globalVars, then)) + t.start() #return the thread so we can join it ... - return threading.Thread(target=execFile, args = (filename, localVars, globalVars, then)).start() + return t def _bginit(name, codeObj): global defGlobals diff --git a/PYME/Acquire/acquiremainframe.py b/PYME/Acquire/acquiremainframe.py index b03d08e7b..7c7d4c75f 100755 --- a/PYME/Acquire/acquiremainframe.py +++ b/PYME/Acquire/acquiremainframe.py @@ -163,7 +163,7 @@ def _initialize_hardware(self): def _check_init_done(self): - if self.scope.initDone == True and self._check_init_done in self.time1.WantNotification: + if self.scope.initialized == True and self._check_init_done in self.time1.WantNotification: logger.debug('Backround initialization done') self.time1.WantNotification.remove(self._check_init_done) diff --git a/PYME/Acquire/microscope.py b/PYME/Acquire/microscope.py index 75ad8dd4a..6371e5704 100755 --- a/PYME/Acquire/microscope.py +++ b/PYME/Acquire/microscope.py @@ -882,7 +882,7 @@ def initialize(self, init_script_name, locals={}): return self._init_thread @property - def initialsed(self): + def initialized(self): """ Checks if the initialisation thread has run (replaces check of initDone flag which needed to be manually set in initialisation script). Semantics are slightly different in that this returns true even if there is an error