Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 111 additions & 68 deletions PYME/Acquire/SpoolController.py

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions PYME/Acquire/Spooler.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ def __init__(self, filename, frameSource, protocol = p.NullProtocol,

self.maxFrames = maxFrames

stack_settings = kwargs.get('stack_settings', None)
if stack_settings:
# only record stack settings if provided (letting protocol fall through to global stack settings,
# if not provided / None)
self.stack_settings = stack_settings

self.onSpoolStop = dispatch.Signal()

#if we've got a fake camera - the cycle time will be wrong - fake our time sig to make up for this
Expand Down
12 changes: 9 additions & 3 deletions PYME/Acquire/acquire_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import threading

from PYME.Acquire import event_loop
#from PYME.Acquire import webui

class PYMEAcquireServer(event_loop.EventLoop):
def __init__(self, options = None):
Expand Down Expand Up @@ -331,8 +332,11 @@ def __init__(self, options, port, bind_addr=''):
self.daemon_threads = True

self.add_endpoints(SpoolController.SpoolControllerWrapper(self.scope.spoolController), '/spool_controller')
#self.add_endpoints(self.scope.stackSettings, '/stack_settings')
self.add_static_handler('static', webframework.StaticFileHandler(os.path.join(os.path.dirname(__file__), 'webui', 'static')))

webui.set_server(self)

self._main_page = webui.load_template('PYMEAcquire.html')

@webframework.register_endpoint('/do_login')
Expand Down Expand Up @@ -397,6 +401,7 @@ def main():
parser.add_option("-i", "--init-file", dest="initFile",
help="Read initialisation from file [defaults to init.py]",
metavar="FILE", default='init.py')
parser.add_option('-b', '--reuse-browser', dest="browser", default=True, action="store_false")

(options, args) = parser.parse_args()

Expand All @@ -414,12 +419,13 @@ def main():
logger.info('using initialization script %s' % init_file)

server = AcquireHTTPServer(options, 8999)
ns = dict(scope=server.scope)
ns = dict(scope=server.scope, server=server)
print('namespace:', ns)
ipy.launch_ipy_server_thread(user_ns=ns)

import webbrowser
webbrowser.open('http://localhost:8999') #FIXME - delay this until server is up
if options.browser:
import webbrowser
webbrowser.open('http://localhost:8999') #FIXME - delay this until server is up

server.run()

Expand Down
4 changes: 2 additions & 2 deletions PYME/Acquire/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ def __init__(self, **kwargs):
Action.__init__(self, **kwargs)

def __call__(self, scope):
return scope.spoolController.StartSpooling(**self._args)
return scope.spoolController.start_spooling(**self._args)

def __repr__(self):
return 'SpoolSeries(%s)' % (self._args)
return 'SpoolSeries(%s)' % ', '.join(['%s = %s' % (k,repr(v)) for k, v in self._args.items()])


def action_from_dict(serialised):
Expand Down
10 changes: 6 additions & 4 deletions PYME/Acquire/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,11 @@ def __init__(self, taskList, startFrame, dwellTime, metadataEntries=[], prefligh
self.require_camera_restart = require_camera_restart

def Init(self, spooler):
self.zPoss = np.arange(scope.stackSettings.GetStartPos(),
scope.stackSettings.GetEndPos() + .95 * scope.stackSettings.GetStepSize(),
scope.stackSettings.GetStepSize() * scope.stackSettings.GetDirection())
stack_settings = getattr(spooler, 'stack_settings', scope.stackSettings)

self.zPoss = np.arange(stack_settings.GetStartPos(),
stack_settings.GetEndPos() + .95 * stack_settings.GetStepSize(),
stack_settings.GetStepSize() * stack_settings.GetDirection())

if self.slice_order != 'saw':
if self.slice_order == 'random':
Expand All @@ -210,7 +212,7 @@ def Init(self, spooler):
self.zPoss = np.concatenate([self.zPoss[::2], self.zPoss[-1::-2]])


self.piezoName = 'Positioning.%s' % scope.stackSettings.GetScanChannel()
self.piezoName = 'Positioning.%s' % stack_settings.GetScanChannel()
self.startPos = scope.state[self.piezoName + '_target'] #FIXME - _target positions shouldn't be part of scope state
self.pos = 0

Expand Down
123 changes: 111 additions & 12 deletions PYME/Acquire/stackSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@

import time
from PYME.IO import MetaDataHandler
from PYME.util import webframework

import logging
logger = logging.getLogger(__name__)

import threading

class StackSettings(object):
"""A class to keep settings for acquiring z-stacks"""
# 'Constants'
Expand All @@ -38,24 +41,99 @@ class StackSettings(object):
START_AND_END = 1
FORWARDS = 1
BACKWARDS = -1

SCAN_MODES = ['Middle and Number', 'Start and End']

DEFAULTS = {
'StartPos': 0,
'EndPos': 0,
'StepSize': 0.2,
'NumSlices': 100,
'ScanMode': SCAN_MODES[0],
'ScanPiezo': 'z',
'DwellFrames': -1,
}

def __init__(self,scope):
def __init__(self,scope, **kwargs):
"""
Create a stack settings object.

NB - extra args map 1:1 to stack metadata entries. Start and end pos are ignored if ScanMode = 'Middle and Number'

Parameters
----------
scope
ScanMode
StartPos
EndPos
StepSize
NumSlices
ScanPiezo
"""
#PreviewAquisator.__init__(self, chans, cam, shutters, None)
self.scope= scope
#self.log = _log
self.mdh = MetaDataHandler.NestedClassMDHandler()
#register as a provider of metadata
MetaDataHandler.provideStartMetadata.append(self.ProvideStackMetadata)

self._settings_changed = threading.Condition()

self.ScanChan = 'z'
self.StartMode = self.CENTRE_AND_LENGTH
self.SeqLength = 100
self.StepSize = 0.2
self.startPos = 0
self.endPos = 0
d1 = dict(self.DEFAULTS)
d1.update(kwargs)

self.update(**d1)

self.direction = self.FORWARDS

from PYME.Acquire import webui
# add webui endpoints (if running under webui)
webui.add_endpoints(self, '/stack_settings')


def update(self, ScanMode=None, StartPos=None, EndPos=None, StepSize=None, NumSlices=None, ScanPiezo=None, DwellFrames=None):
if ScanPiezo is not None:
self.ScanChan = ScanPiezo
if ScanMode is not None:
self.StartMode = self.SCAN_MODES.index(ScanMode)
if NumSlices is not None:
self.SeqLength = int(NumSlices)
if StepSize is not None:
self.StepSize = float(StepSize)
if StartPos is not None:
self.startPos = float(StartPos)
if EndPos is not None:
self.endPos = float(EndPos)
if DwellFrames is not None:
self._dwell_frames = float(DwellFrames)

with self._settings_changed:
self._settings_changed.notify_all()

@webframework.register_endpoint('/update', output_is_json=False)
def update_json(self, body):
import json
self.update(**json.loads(body))

@webframework.register_endpoint('/settings', output_is_json=False)
def settings(self):
return {
'StartPos' : self.GetStartPos(),
'EndPos' : self.GetEndPos(),
'StepSize': self.GetStepSize(),
'NumSlices' : self.GetSeqLength(),
'ScanMode': self.SCAN_MODES[self.GetStartMode()],
'ScanPiezo' : self.GetScanChannel(),
'DwellFrames' : self._dwell_frames,
}

@webframework.register_endpoint('/settings_longpoll', output_is_json=False)
def settings_longpoll(self):
with self._settings_changed:
self._settings_changed.wait()

return self.settings()


def GetScanChannel(self):
return self.ScanChan
Expand All @@ -66,9 +144,13 @@ def piezoGoHome(self):

def SetScanChannel(self,iMode):
self.ScanChan = iMode
with self._settings_changed:
self._settings_changed.notify_all()

def SetSeqLength(self,iLength):
self.SeqLength = iLength
self.SeqLength = int(iLength)
with self._settings_changed:
self._settings_changed.notify_all()

def GetSeqLength(self):
if (self.StartMode == 0):
Expand All @@ -78,15 +160,24 @@ def GetSeqLength(self):

def SetStartMode(self, iMode):
self.StartMode = iMode
with self._settings_changed:
self._settings_changed.notify_all()

def GetStartMode(self):
return self.StartMode

def SetStepSize(self, fSize):
self.StepSize = fSize
self.StepSize = float(fSize)
with self._settings_changed:
self._settings_changed.notify_all()

def GetStepSize(self):
return self.StepSize

def SetStartPos(self, sPos):
self.startPos = sPos
self.startPos = float(sPos)
with self._settings_changed:
self._settings_changed.notify_all()

def GetStartPos(self):
if (self.GetStartMode() == 0):
Expand All @@ -97,23 +188,31 @@ def GetStartPos(self):
return self.startPos

def SetEndPos(self, ePos):
self.endPos = ePos
self.endPos = float(ePos)
with self._settings_changed:
self._settings_changed.notify_all()

def GetEndPos(self):
if (self.GetStartMode() == 0):
return self._CurPos() + (self.GetStepSize()*(self.GetSeqLength() - 1)*self.GetDirection()/2)
else:
if not ("endPos" in dir(self)):
raise RuntimeError("Please call SetEndPos first !!")
return self.endPos

def SetPrevPos(self, sPos):
self.prevPos = sPos

def GetPrevPos(self):
if not ("prevPos" in dir(self)):
raise RuntimeError("Please call SetPrevPos first !!")
return self.prevPos

def SetDirection(self, dir):
" Fowards = 1, backwards = -1 "
self.direction = dir
with self._settings_changed:
self._settings_changed.notify_all()

def GetDirection(self):
if (self.GetStartMode() == 0):
Expand Down Expand Up @@ -162,7 +261,7 @@ def ProvideStackMetadata(self, mdh):
mdh.setEntry('StackSettings.EndPos', self.GetEndPos())
mdh.setEntry('StackSettings.StepSize', self.GetStepSize())
mdh.setEntry('StackSettings.NumSlices', self.GetSeqLength())
mdh.setEntry('StackSettings.ScanMode', ['Middle and Number', 'Start and End'][self.GetStartMode()])
mdh.setEntry('StackSettings.ScanMode', self.SCAN_MODES[self.GetStartMode()])
mdh.setEntry('StackSettings.ScanPiezo', self.GetScanChannel())

mdh.setEntry('voxelsize.z', self.GetStepSize())
Expand Down
5 changes: 1 addition & 4 deletions PYME/Acquire/ui/HDFSpoolFrame.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,7 @@ def OnBStartSpoolButton(self, event=None, stack=False):


try:
self.spoolController.StartSpooling(fn, #stack=stack, #compLevel = compLevel,
#pzf_compression_settings=self.get_compression_settings(),
#cluster_h5=self.cbClusterh5.GetValue()
)
self.spoolController.start_spooling(fn)
except IOError as e:
logger.exception('IO error whilst spooling')
ans = wx.MessageBox(str(e.message), 'Error', wx.OK)
Expand Down
28 changes: 14 additions & 14 deletions PYME/Acquire/ui/actionUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import numpy as np
import logging

from PYME.Acquire import actions

logger = logging.getLogger(__name__)

class ActionList(wx.ListCtrl):
Expand Down Expand Up @@ -179,28 +181,26 @@ def OnAddAction(self, event):

def OnAddMove(self, event):
nice = float(self.tNice.GetValue())
#functionName = self.tFunction.GetValue()
#args = eval('dict(%s)' % self.tArgs.GetValue())

functionName = 'state.update'
args = {'state' : {'Positioning.x': self.scope.state['Positioning.x'],
'Positioning.y': self.scope.state['Positioning.y'],
'Positioning.z': self.scope.state['Positioning.z']}}

timeout = float(self.tTimeout.GetValue())
max_duration = float(self.t_duration.GetValue())
self.actionManager.QueueAction(functionName, args, nice, timeout,
max_duration)

state = {'Positioning.x': self.scope.state['Positioning.x'],
'Positioning.y': self.scope.state['Positioning.y'],
'Positioning.z': self.scope.state['Positioning.z']}

self.actionManager.queue_actions([actions.UpdateState(state),],
nice, timeout, max_duration)


def OnAddSequence(self, event):
nice = float(self.tNice.GetValue())
functionName = 'spoolController.StartSpooling'
args = {'maxFrames' : int(self.tNumFrames.GetValue()), 'stack': bool(self.rbZStepped.GetValue())}
timeout = float(self.tTimeout.GetValue())
max_duration = float(self.t_duration.GetValue())
self.actionManager.QueueAction(functionName, args, nice, timeout,
max_duration)

settings = {'max_frames': int(self.tNumFrames.GetValue()), 'z_stepped': bool(self.rbZStepped.GetValue())}

self.actionManager.queue_actions([actions.SpoolSeries(settings=settings, preflight_mode='warn'),],
nice , timeout,max_duration)


def _add_ROIs(self, rois):
Expand Down
Loading