Esempio n. 1
0
    def __init__(self, scope, dim_order='XYCZT', stack_settings=None, time_settings=None, channel_settings=None, backend=MemoryBackend):
        if stack_settings is None:
            stack_settings = scope.stackSettings

        assert(dim_order[:2] == 'XY') #first two dimensions must be XY (camera acquisition)
        # TODO more sanity checks on dim_order
        
        self.dim_order = dim_order
        self.scope = scope
        
        self.shape_x, self.shape_y = scope.frameWrangler.currentFrame.shape[:2]
        self.shape_z = stack_settings.GetSeqLength()
        self.shape_t = getattr(time_settings, 'num_timepoints', 1)
        self.shape_c = getattr(channel_settings, 'num_channels', 1)
        
        # note shape_t can be negative if we want to run until explicitly stopped
        self.n_frames = self.shape_z*self.shape_c*self.shape_t
        self.frame_num = 0
        
        self.storage = backend(self.shape_x, self.shape_y, self.n_frames, dim_order=dim_order, shape=self.shape)
        
        #do any precomputation
        self._init_z(stack_settings)
        self._init_t(time_settings)
        self._init_c(channel_settings)

        self.on_single_frame = dispatch.Signal()  #dispatched when a frame is ready
        self.on_series_end = dispatch.Signal()  #dispatched when a sequence is complete
    def __init__(self, testFrameSize=TEST_FRAME_SIZE, serverfilter=''):

        self.testData = (100 * np.random.rand(*testFrameSize)).astype('uint16')
        self.onFrame = dispatch.Signal(['frameData'])
        self.spoolProgress = dispatch.Signal(['percent'])

        self.mdh = MetaDataHandler.NestedClassMDHandler()
        self.serverfilter = serverfilter
    def __init__(self, _cam, _ds = None, event_loop=None):
        #wx.EvtHandler.__init__(self)
        #self.timer = wx.Timer(self)
        #self.Bind(wx.EVT_TIMER, self.Notify)
        
        if event_loop is None:
            from PYME.ui import mytimer
            self._event_loop = mytimer
        else:
            self._event_loop = event_loop
        
        self.timer = self._event_loop.SingleTargetTimer(self.Notify)
        
        self.currentFrame = _ds
        self.cam = _cam

        self.aqOn = False

        #list of functions to call to see if we ought to wait on any hardware
        self.HardwareChecks = []
        
        #should we start a new exposure on the next timer check?
        self.needExposureStart = False
        
        #did the buffer overflow?
        self.bufferOverflowed = False

        self.tLastFrame=0
        self.tThisFrame=0
        self.nFrames = 0
        self.n_frames_in_group=0
        self.tl=0
        
        self.inNotify = False
        self._notify_lock = threading.Lock()
        
        #Signals
        ##########################
        # these allow other files to listen to key events happingin within the acquisiotn        
        #new style signals - these will replace the WantFrameNotification etc ...
        #which are currently being kept for backwards compatibility
        
        self.onFrame = dispatch.Signal(['frameData']) #called each time a new frame appears in our buffer
        self.onFrameGroup = dispatch.Signal() #called on each new frame group (once per polling interval) - use for updateing GUIs etc.
        self.onStop = dispatch.Signal()
        self.onStart = dispatch.Signal()

        # should the thread which polls the camera still be running?
        self._poll_camera = True

        self._current_frame_lock = threading.Lock()
        self._poll_lock = threading.Lock()
        self._polling_interval = 0.01  # time between calls to poll the camera [s]
        self._poll_thread = threading.Thread(target=self._poll_loop)
        self._poll_thread.start()
Esempio n. 4
0
    def __init__(self, imageMdh=None, tq=None):
        self.analysisMDH = MetaDataHandler.CopyOnWriteMDHandler(
            imageMdh)  #MetaDataHandler.NestedClassMDHandler(imageMdh)
        self.onImagesPushed = dispatch.Signal()
        self.onMetaDataChange = dispatch.Signal()

        self.tq = tq

        if self.tq is None:
            #try and find a task queue
            try:
                self._checkTQ()
            except:
                pass
Esempio n. 5
0
    def __init__(self, filename=None, visFr=None):
        self.filter = None
        self.mapping = None
        self.colourFilter = None
        self.events = None

        self.recipe = Recipe(execute_on_invalidation=True)
        self.recipe.recipe_executed.connect(self.Rebuild)

        self.selectedDataSourceKey = None
        self.filterKeys = {
            'error_x': (0, 30),
            'error_y': (0, 30),
            'A': (5, 20000),
            'sig': (95, 200)
        }

        self.blobSettings = BlobSettings()
        self.objects = None

        self.imageBounds = ImageBounds(0, 0, 0, 0)
        self.mdh = MetaDataHandler.NestedClassMDHandler()

        self.Triangles = None
        self.edb = None
        self.Quads = None
        self.GeneratedMeasures = {}

        self.QTGoalPixelSize = 5

        self._extra_chan_num = 0

        self.filesToClose = []

        self.ev_mappings = {}

        #define a signal which a GUI can hook if the pipeline is rebuilt (i.e. the output changes)
        self.onRebuild = dispatch.Signal()

        #a cached list of our keys to be used to decide whether to fire a keys changed signal
        self._keys = None
        #define a signal which can be hooked if the pipeline keys have changed
        self.onKeysChanged = dispatch.Signal()

        self.ready = False
        #self.visFr = visFr

        if not filename is None:
            self.OpenFile(filename)
Esempio n. 6
0
    def __init__(self, *args, **kwargs):
        HasTraits.__init__(self, *args, **kwargs)

        self.namespace = {}

        # we open hdf files and don't necessarily read their contents into memory - these need to be closed when we
        # either delete the recipe, or clear the namespace
        self._open_input_files = []

        self.recipe_changed = dispatch.Signal()
        self.recipe_executed = dispatch.Signal()
        self.recipe_failed = dispatch.Signal()

        self.failed = False

        self._dg_sig = None
    def __init__(self, scope, pixels = 10, pixelsize=0.1, dwelltime = 1, background=0, avg=True, evtLog=False, sync=False,
                 trigger=False, stop_on_complete=False, return_to_start=True):
        """
        :param return_to_start: bool
            Flag to toggle returning home at the end of the scan. False leaves scope position as-is on scan completion.
        """
        self.scope = scope
        #self.xpiezo = xpiezo
        #self.ypiezo = ypiezo

        self.trigger = trigger

        self.dwellTime = dwelltime
        self.background = background
        self.avg = avg
        self.pixels = pixels
        self.pixelsize = pixelsize
        self._stop_on_complete = stop_on_complete
        self._return_to_start = return_to_start

        if np.isscalar(pixelsize):
            self.pixelsize = np.array([pixelsize, pixelsize])

        self.evtLog = evtLog
        self.sync = sync

        self._rlock = threading.Lock()
        
        self.running = False
        self._uuid = uuid.uuid4()
        self.on_stop = dispatch.Signal()
Esempio n. 8
0
    def __init__(self, key, getFcn=None, setFcn=None, needCamRestart=False):
        """Define a state-change handler for a give state key, based on supplied
        get and set functions which interact with the underlying hardware.
        
        This wrapper class serves two functions - a) allowing the get and set methods
        to be stored under a single dictionary key in the StateManager, and b)
        making sure a signal is fired when the state changes.
        
        Parameters
        ----------
        
        key : string
            The hardware key - e.g. "Positioning.x", or "Lasers.405.Power". This
            will also be how the hardware state is recorder in the metadata.
        getFcn : function
            The function to call to get the value of the parameter. Should take
            one parameter which is the value to get
        setFcn : function
            The function to call to set the value of the parameter. Should take
            one parameter which is the value to set. Not providing a setFcn results
            in a read-only property.
        needCamRestart : bool
            Does this absolutely need a camera restart (e.g. we are changing which 
            camera we are using). Will override other preferences.
        
        """
        self.getValue = getFcn
        self.setFcn = setFcn
        self.key = key

        self.needCamRestart = needCamRestart

        self.onChange = dispatch.Signal()
Esempio n. 9
0
    def __init__(self, *args, **kwargs):
        try:
            self.orientation = kwargs.pop('orientation')
        except KeyError:
            self.orientation = wx.VERTICAL

        try:
            self.padding = kwargs.pop('padding')
        except KeyError:
            self.padding = 5

        self._stretch_sizer = kwargs.pop('bottom_spacer', True)
        self._one_pane_active = kwargs.pop('single_active_pane', False)

        wx.Panel.__init__(self, *args, **kwargs)

        if self.orientation == wx.VERTICAL:
            self.sizerflags = wx.EXPAND  #| wx.BOTTOM
        else:
            self.sizerflags = wx.EXPAND  #| wx.RIGHT

        self.priorities = []
        self.panes = []

        self.sizer = wx.BoxSizer(self.orientation)
        self.SetSizer(self.sizer)

        self._in_fold1 = False

        self.fold_signal = dispatch.Signal()

        self.Bind(wx.EVT_SIZE, self.OnResize)
        self.Bind(EVT_CMD_PANEL_FOLD, self.OnResize)
Esempio n. 10
0
    def __init__(self):
        self.LIST_CHANGED_SIGNAL = dispatch.Signal()

        self._visibility_mask = []
        self._names = {}
        self._rois = []
        self._partial_ensemble_parameters = np.array([])
Esempio n. 11
0
    def __init__(self, *args, **kwargs):
        try:
            self.orientation = kwargs.pop('orientation')
        except KeyError:
            self.orientation = wx.VERTICAL

        try:
            self.padding = kwargs.pop('padding')
        except KeyError:
            self.padding = 5

        wx.Panel.__init__(self, *args, **kwargs)

        if self.orientation == wx.VERTICAL:
            self.sizerflags = wx.EXPAND  #| wx.BOTTOM
        else:
            self.sizerflags = wx.EXPAND  #| wx.RIGHT

        self.priorities = []
        self.panes = []

        self.sizer = wx.BoxSizer(self.orientation)
        self.SetSizer(self.sizer)

        self.fold_signal = dispatch.Signal()
Esempio n. 12
0
    def __init__(self, scope):
        """Initialise our action manager
        
        Parameters
        ----------
        
        scope : PYME.Acquire.microscope.microscope object
            The microscope. The function object to call for an action should be 
            accessible within the scope namespace, and will be resolved by
            calling eval('scope.functionName')
        
        """
        self.actionQueue = Queue.PriorityQueue()
        self.scope = weakref.ref(scope)

        #this will be assigned to a callback to indicate if the last task has completed
        self.isLastTaskDone = None
        self.paused = False

        self.currentTask = None

        self.onQueueChange = dispatch.Signal()

        self._timestamp = 0

        self._monitoring = True
        self._monitor = threading.Thread(target=self._monitor_defunct)
        self._monitor.daemon = True
        self._monitor.start()

        self._lock = threading.Lock()
Esempio n. 13
0
    def __init__(self,
                 scope,
                 tile_dir,
                 max_radius_um=100,
                 tile_spacing=None,
                 dwelltime=1,
                 background=0,
                 evtLog=False,
                 trigger=False,
                 base_tile_size=256,
                 return_to_start=True):
        """
        :param return_to_start: bool
            Flag to toggle returning home at the end of the scan. False leaves scope position as-is on scan completion.
        """
        if tile_spacing is None:
            fs = np.array(scope.frameWrangler.currentFrame.shape[:2])
            # calculate tile spacing such that there is ~30% overlap.
            tile_spacing = (1 / np.sqrt(2)) * fs * np.array(
                scope.GetPixelSize())
        # take the pixel size to be the same or at least similar in both directions
        pixel_radius = int(max_radius_um / tile_spacing.mean())
        logger.debug(
            'Circular tiler target radius in units of (overlapped) FOVs: %d' %
            pixel_radius)

        pointScanner.CircularPointScanner.__init__(
            self,
            scope,
            pixel_radius,
            tile_spacing,
            dwelltime,
            background,
            False,
            evtLog,
            trigger=trigger,
            stop_on_complete=True,
            return_to_start=return_to_start)

        self._tiledir = tile_dir
        self._base_tile_size = base_tile_size
        self._flat = None  #currently not used

        self._last_update_time = 0

        self.on_stop = dispatch.Signal()
        self.progress = dispatch.Signal()
    def __init__(self, _chans, _cam, _shutters, _ds=None):
        wx.EvtHandler.__init__(self)
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.Notify)

        self.chans = _chans
        #self.hwChans = _chans.hw
        #self.numHWChans = len(_chans.hw)
        #self.cols =  _chans.cols
        self.dsa = _ds
        self.cam = _cam
        self.shutters = _shutters
        self.loopnuf = 0
        self.aqOn = False
        #lists of functions to call on a new frame, and when the aquisition ends
        #self.WantFrameNotification = []
        #self.WantStopNotification = []
        #self.WantStartNotification = []
        #list of functions to call to see if we ought to wait on any hardware
        self.HardwareChecks = []
        #should we start a new exposure on the next timer check?
        self.needExposureStart = False

        self.tLastFrame = 0
        self.tThisFrame = 0
        self.nFrames = 0
        self.tl = 0

        self.inNotify = False

        self.zPos = 0

        #will be needed to allow the display load to be minimised by, e.g. only updating display once per poll rather than once per frame
        #self.WantFrameGroupNotification = []

        #Signals
        ##########################
        # these allow other files to listen to key events happingin within the acquisiotn
        #new style signals - these will replace the WantFrameNotification etc ...
        #which are currently being kept for backwards compatibility

        self.onFrame = dispatch.Signal(
            ['frameData'])  #called each time a new frame appears in our buffer
        self.onFrameGroup = dispatch.Signal(
        )  #called on each new frame group (once per polling interval) - use for updateing GUIs etc.
        self.onStop = dispatch.Signal()
        self.onStart = dispatch.Signal()
Esempio n. 15
0
    def __init__(self):
        self.analysisMDH = MetaDataHandler.NestedClassMDHandler()

        self.onMetadataChanged = dispatch.Signal()

        self.propagateToAcquisisitonMetadata = False

        MetaDataHandler.provideStartMetadata.append(self.genStartMetadata)
Esempio n. 16
0
    def __init__(self, scope, handlers={}):
        self._stateHandlers = {}
        self._cachedStates = {}

        self._stateHandlers.update(handlers)

        self.scope = weakref.ref(scope)
        self.stateChanged = dispatch.Signal()
Esempio n. 17
0
    def __init__(self,
                 filename,
                 frameSource,
                 protocol=p.NullProtocol,
                 guiUpdateCallback=None,
                 fakeCamCycleTime=None,
                 maxFrames=p.maxint,
                 **kwargs):
        """Create a new spooler.
        
        Parameters
        ----------
        scope : PYME.Acquire.microscope.microscope object
            The microscope providing the data
        filename : string
            The file into which to spool
        frameSource : dispatch.Signal object
            A source of frames we can subscribe to. It should implement a "connect"
            method allowing us to register a callback and then call the callback with
            the frame data in a "frameData" kwarg.
        protocol : PYME.Acquire.protocol.TaskListProtocol object
            The acquisition protocol
        guiUpdateCallback : function
            a function to call when the spooling GUI needs updating
            
        """
        global timeFcn
        #self.scope = scope
        self.filename = filename
        self.frameSource = frameSource
        self.guiUpdateCallback = guiUpdateCallback
        self.protocol = protocol

        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
        #if scope.cam.__class__.__name__ == 'FakeCamera':
        #    timeFcn = self.fakeTime

        self._last_gui_update = 0
        self.spoolOn = False
        self.imNum = 0

        self.spool_complete = False

        self._spooler_uuid = uuid.uuid4()

        if not fakeCamCycleTime is None:
            self.fakeCamCycleTime = fakeCamCycleTime
            timeFcn = self.fakeTime
Esempio n. 18
0
    def __init__(self,
                 scope,
                 tile_dir,
                 n_tiles=10,
                 tile_spacing=None,
                 dwelltime=1,
                 background=0,
                 evtLog=False,
                 trigger=False,
                 base_tile_size=256,
                 return_to_start=True,
                 backend='file'):
        """
        :param return_to_start: bool
            Flag to toggle returning home at the end of the scan. False leaves scope position as-is on scan completion.
        """

        if tile_spacing is None:
            fs = np.array(scope.frameWrangler.currentFrame.shape[:2])
            #calculate tile spacing such that there is 20% overlap.
            tile_spacing = 0.8 * fs * np.array(scope.GetPixelSize())

        pointScanner.PointScanner.__init__(self,
                                           scope=scope,
                                           pixels=n_tiles,
                                           pixelsize=tile_spacing,
                                           dwelltime=dwelltime,
                                           background=background,
                                           avg=False,
                                           evtLog=evtLog,
                                           trigger=trigger,
                                           stop_on_complete=True,
                                           return_to_start=return_to_start)

        self._tiledir = tile_dir
        self._base_tile_size = base_tile_size
        self._flat = None  #currently not used

        self._last_update_time = 0

        self._backend = backend

        self.on_stop = dispatch.Signal()
        self.progress = dispatch.Signal()
Esempio n. 19
0
    def __init__(self, use_shaders=False):
        self._new_layers = PYME.config.get('VisGUI-new_layers', False)
        self.viewMode = 'points' #one of points, triangles, quads, or voronoi
        #self.colData = 't'
        self.pointDisplaySettings = pointSettingsPanel.PointDisplaySettings()
        self.pointDisplaySettings.on_trait_change(self.RefreshView)
        
        self.quadTreeSettings = quadTreeSettings.QuadTreeSettings()
        self.quadTreeSettings.on_trait_change(self.RefreshView)
        
        self.pipeline.blobSettings.on_trait_change(self.RefreshView)
        self.pipeline.onRebuild.connect(self.RefreshView)
        
        #initialize the gl canvas
        if isinstance(self, wx.Window):
            win = self
        else:
            win = self.dsviewer

        gl_pan = wx.Panel(win)
        sizer = wx.BoxSizer(wx.VERTICAL)


        
        if not use_shaders:
            self.glCanvas = gl_render.LMGLCanvas(gl_pan)
        else:
            from PYME.LMVis.gl_render3D_shaders import LMGLShaderCanvas, LegacyGLCanvas
            if self._new_layers:
                #use stripped down version
                self.glCanvas = LMGLShaderCanvas(gl_pan)
            else:
                self.glCanvas = LegacyGLCanvas(gl_pan)

        sizer.Add(self.create_tool_bar(gl_pan), 0, wx.EXPAND, 0)
        sizer.Add(self.glCanvas, 5, wx.EXPAND, 0)
        gl_pan.SetSizerAndFit(sizer)
        win.AddPage(page=gl_pan, caption='View')#, select=True)

        #self.glCanvas.setCMap(pylab.cm.gist_rainbow) #pylab.cm.hot

        #self.rec_gui = recipeGui.
        #win.AddPage(page=self.glCanvas, caption='View')#, select=True)
        
        self.refv = False
        
        self._legacy_layer = None
        
        self.layer_added = dispatch.Signal()
        
        renderers.renderMetadataProviders.append(self.SaveMetadata)
        self.use_shaders = use_shaders
        
        wx.CallLater(100, self.OnIdle)
Esempio n. 20
0
    def __init__(self, scope):
        self.scope = scope
        self.stackSettings = scope.stackSettings
        self.off = 0
        self.sc = 100
        self.sqrt = False
        
        self.frameNum = 0
        
        #self.ds = scope.frameWrangler.currentFrame
        self.shape_x, self.shape_y = scope.frameWrangler.currentFrame.shape[:2]
        
        self.running = False
 
        #legacy signalling - don't use in new code.        
        #self.WantFrameNotification = []
        #self.WantTickNotification = []
        
        #These signals should instead of the notification lists above
        self.onStack = dispatch.Signal() #dispatched on completion of a stack
        self.onSingleFrame = dispatch.Signal()  #dispatched when a frame is ready
Esempio n. 21
0
    def __init__(self,
                 pipeline,
                 method='wireframe',
                 dsname='',
                 context=None,
                 **kwargs):
        EngineLayer.__init__(self, context=context, **kwargs)
        self._pipeline = pipeline
        self.engine = None
        self.cmap = 'gist_rainbow'

        self.x_key = 'x'  # TODO - make these traits?
        self.y_key = 'y'
        self.z_key = 'z'

        self.xn_key = 'xn'
        self.yn_key = 'yn'
        self.zn_key = 'zn'

        self._bbox = None

        # define a signal so that people can be notified when we are updated (currently used to force a redraw when
        # parameters change)
        self.on_update = dispatch.Signal()

        # define responses to changes in various traits
        self.on_trait_change(self._update, 'vertexColour')
        self.on_trait_change(lambda: self.on_update.send(self), 'visible')
        self.on_trait_change(
            self.update,
            'cmap, clim, alpha, dsname, normal_mode, display_normals, normal_scaling'
        )
        self.on_trait_change(self._set_method, 'method')

        # update any of our traits which were passed as command line arguments
        self.set(**kwargs)

        # update datasource and method
        self.dsname = dsname
        if self.method == method:
            #make sure we still call _set_method even if we start with the default method
            self._set_method()
        else:
            self.method = method

        # if we were given a pipeline, connect ourselves to the onRebuild signal so that we can automatically update
        # ourselves
        if not self._pipeline is None:
            try:
                self._pipeline.onRebuild.connect(self.update)
            except AttributeError:
                pass
Esempio n. 22
0
    def __init__(self, datasource, xp=0, yp=0, zp=0, aspect=1):
        self.WantChangeNotification = []  # MyWeakSet() #[]

        self.Chans = []
        self.Gains = []
        self.Offs = []
        self.cmaps = []
        self.names = []
        self.show = []

        self._xp = 0
        self._yp = 0

        self._zp = 0
        self._tp = 0

        self.maximumProjection = False
        self.colourMax = False
        self.cmax_offset = 0.0
        self.cmax_scale = 1.0

        self._complexMode = 'coloured'

        self.inOnChange = False
        self.syncedWith = []

        self.SetDataStack(datasource)
        self.SetAspect(aspect)
        self.ResetSelection()

        self.orientation = self.UPRIGHT
        self.slice = self.SLICE_XY
        self.scale = 0

        self.leftButtonAction = self.ACTION_POSITION
        self.selectionMode = self.SELECTION_RECTANGLE

        self.selectionWidth = 1

        self.showSelection = False

        #signals (currently just for selection end
        # this lets people know that we've made a selection. Used to allow modification of the selection by some filter
        # e.g. using active contours in the annotation module
        self.on_selection_end = dispatch.Signal()

        self.overlays = []
Esempio n. 23
0
    def __init__(self,
                 pipeline,
                 method='points',
                 dsname='',
                 context=None,
                 **kwargs):
        EngineLayer.__init__(self, context=context, **kwargs)
        self._pipeline = pipeline
        self.engine = None
        self.cmap = 'gist_rainbow'

        self.x_key = 'x'  #TODO - make these traits?
        self.y_key = 'y'
        self.z_key = 'z'

        self.xn_key = 'xn'
        self.yn_key = 'yn'
        self.zn_key = 'zn'

        self._bbox = None

        # define a signal so that people can be notified when we are updated (currently used to force a redraw when
        # parameters change)
        self.on_update = dispatch.Signal()

        # define responses to changes in various traits
        self.on_trait_change(self._update, 'vertexColour')
        self.on_trait_change(lambda: self.on_update.send(self), 'visible')
        self.on_trait_change(self.update,
                             'cmap, clim, alpha, dsname, point_size')
        self.on_trait_change(self._set_method, 'method')

        # update any of our traits which were passed as command line arguments
        self.set(**kwargs)

        # update datasource name and method
        #logger.debug('Setting dsname and method')
        self.dsname = dsname
        self.method = method

        self._set_method()

        # if we were given a pipeline, connect ourselves to the onRebuild signal so that we can automatically update
        # ourselves
        if not self._pipeline is None:
            self._pipeline.onRebuild.connect(self.update)
Esempio n. 24
0
    def __init__(self,
                 pipeline,
                 method='image',
                 dsname='',
                 display_opts=None,
                 context=None,
                 **kwargs):
        EngineLayer.__init__(self, context=context, **kwargs)
        self._pipeline = pipeline
        self.engine = None
        self.cmap = 'gray'

        self._bbox = None
        self._do = display_opts  #a dh5view display_options instance - if provided, this over-rides the the clim, cmap properties

        self._im_key = None

        # define a signal so that people can be notified when we are updated (currently used to force a redraw when
        # parameters change)
        self.on_update = dispatch.Signal()

        # define responses to changes in various traits
        #self.on_trait_change(self._update, 'vertexColour')
        self.on_trait_change(lambda: self.on_update.send(self), 'visible')
        self.on_trait_change(self.update, 'cmap, clim, alpha, dsname')
        self.on_trait_change(self._set_method, 'method')

        # update any of our traits which were passed as command line arguments
        self.set(**kwargs)

        # update datasource and method
        self.dsname = dsname
        if self.method == method:
            #make sure we still call _set_method even if we start with the default method
            self._set_method()
        else:
            self.method = method

        # if we were given a pipeline, connect ourselves to the onRebuild signal so that we can automatically update
        # ourselves
        if (not self._pipeline is None) and hasattr(pipeline, 'onRebuild'):
            self._pipeline.onRebuild.connect(self.update)
Esempio n. 25
0
    def __init__(self, spool_controller, posting_thread_queue_size=5):
        """
        Parameters
        ----------
        posting_thread_queue_size : int, optional
            sets the size of a queue to hold rule posting threads to ensure they
            have time to execute, by default 5. .. seealso:: modules :py:mod:`PYME.cluster.rules`
        """
        import queue

        OrderedDict.__init__(self)
        self.active = True
        self._spool_controller = spool_controller
        self.posting_thread_queue = queue.Queue(posting_thread_queue_size)
        self._updated = dispatch.Signal()
        self._updated.connect(self.update)

        self['default'] = RuleChain()

        self._spool_controller.onSpoolStart.connect(self.on_spool_start)
        self._spool_controller.onSpoolStop.connect(self.on_spool_stop)
Esempio n. 26
0
    def __init__(self):
        #self.image = image

        self.onFrame = dispatch.Signal(['frameData'])
        self.spoolProgress = dispatch.Signal(['percent'])
    def __init__(self, parent, show_lut=True, display_mode='2D', view=None):
        print("New Canvas")
        attribute_list = [
            wx.glcanvas.WX_GL_RGBA, wx.glcanvas.WX_GL_STENCIL_SIZE, 8,
            wx.glcanvas.WX_GL_DOUBLEBUFFER
        ]
        self._num_antialias_samples = int(
            config.get('VisGUI-antialias_samples', 4))
        if self._num_antialias_samples > 0:
            attribute_list.extend([
                wx.glcanvas.WX_GL_SAMPLE_BUFFERS, 1, wx.glcanvas.WX_GL_SAMPLES,
                self._num_antialias_samples
            ])

        GLCanvas.__init__(self, parent, -1, attribList=attribute_list)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.EVT_MOUSEWHEEL, self.OnWheel)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown)
        self.Bind(wx.EVT_MIDDLE_UP, self.OnMiddleUp)
        self.Bind(wx.EVT_RIGHT_DOWN, self.OnMiddleDown)
        self.Bind(wx.EVT_RIGHT_UP, self.OnMiddleUp)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress)
        # wx.EVT_MOVE(self, self.OnMove)
        try:
            self.gl_context = wx.glcanvas.GLContext(self)
        except:
            logger.exception(
                'Error creating OpenGL context, try modifying the number of anti-aliasing samples using the "VisGUI-antialias_samples" config setting (0 to disable antialiasing)'
            )
            raise

        self.displayMode = display_mode  # 3DPersp' #one of 3DPersp, 3DOrtho, 2D

        self.parent = parent

        self._scaleBarLength = 1000
        self.clear_colour = [0, 0, 0, 1.0]

        self.LUTDraw = show_lut

        self.zmin = -10
        self.zmax = 10

        self.angup = 0
        self.angright = 0

        if view is None:
            self.view = views.View()
        else:
            self.view = view

        self.sx = 100
        self.sy = 100

        self.zc_o = 0

        self.stereo = False

        self.eye_dist = .01

        self.dragging = False
        self.panning = False

        self.selectionSettings = SelectionSettings()
        self.selectionDragging = False

        self.layers = []
        self.overlays = []
        self.underlays = [
        ]  #draw these before data (assuming depth-testing is disabled)

        self.wantViewChangeNotification = WeakSet()
        self.pointSelectionCallbacks = []

        self.on_screen = True
        self.view_port_size = (self.Size[0], self.Size[1])

        self._old_bbox = None

        self.layer_added = dispatch.Signal()
Esempio n. 28
0
    def __init__(self, parent, filterKeys, dataSource=None):
        """

        Parameters
        ----------
        parent : wx.Window

        filterKeys : dict
            Dictionary keys

        dataSource : function
            function to call to get the current data source
        """
        wx.Panel.__init__(self, parent)

        self.filterKeys = filterKeys
        self._dataSource = dataSource

        self.on_filter_changed = dispatch.Signal()

        #GUI stuff
        vsizer = wx.BoxSizer(wx.VERTICAL)

        self.lFiltKeys = wx.ListCtrl(
            self,
            -1,
            style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.SUNKEN_BORDER,
            size=(-1, 25 * (max(len(self.filterKeys.keys()) + 1, 5))))

        self.lFiltKeys.InsertColumn(0, 'Key')
        self.lFiltKeys.InsertColumn(1, 'Min')
        self.lFiltKeys.InsertColumn(2, 'Max')

        self.populate()

        self.lFiltKeys.SetColumnWidth(0, wx.LIST_AUTOSIZE)
        self.lFiltKeys.SetColumnWidth(1, wx.LIST_AUTOSIZE)
        self.lFiltKeys.SetColumnWidth(2, wx.LIST_AUTOSIZE)

        # only do this part the first time so the events are only bound once
        if not hasattr(self, "ID_FILT_ADD"):
            self.ID_FILT_ADD = wx.NewId()
            self.ID_FILT_DELETE = wx.NewId()
            self.ID_FILT_EDIT = wx.NewId()

            self.Bind(wx.EVT_MENU, self.OnFilterAdd, id=self.ID_FILT_ADD)
            self.Bind(wx.EVT_MENU, self.OnFilterDelete, id=self.ID_FILT_DELETE)
            self.Bind(wx.EVT_MENU, self.OnFilterEdit, id=self.ID_FILT_EDIT)

        # for wxMSW
        self.lFiltKeys.Bind(wx.EVT_COMMAND_RIGHT_CLICK,
                            self.OnFilterListRightClick)

        # for wxGTK
        self.lFiltKeys.Bind(wx.EVT_RIGHT_UP, self.OnFilterListRightClick)

        self.lFiltKeys.Bind(wx.EVT_LIST_ITEM_SELECTED,
                            self.OnFilterItemSelected)
        self.lFiltKeys.Bind(wx.EVT_LIST_ITEM_DESELECTED,
                            self.OnFilterItemDeselected)
        self.lFiltKeys.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnFilterEdit)

        vsizer.Add(self.lFiltKeys, 1, wx.ALL | wx.EXPAND, 0)
        #self.stNumFiltered = wx.StaticText(self, -1, '')
        #vsizer.Add(self.stNumFiltered, 0, wx.ALL | wx.EXPAND, 2)
        self.SetSizerAndFit(vsizer)
    def __init__(self, scope, defDir=genHDFDataFilepath(), defSeries='%(day)d_%(month)d_series'):
        """Initialise the spooling controller.
        
        Parameters
        ----------
        scope : microscope instance
            The currently active microscope class (see microscope.py)
        defDir : string pattern
            The default directory to save data to. Any keys of the form `%(<key>)` 
            will be substituted using the values defined in `PYME.fileUtils.nameUtils.dateDict` 
        defSeries : string pattern
            This specifies a pattern for file naming. Keys will be substituted as for `defDir`
            
        """
        self.scope = scope
        
        if int(sys.version[0]) < 3:
            #default to Queue for Py2
            self.spoolType = 'Queue'
        else:
            #else default to file
            self.spoolType = 'File'
        
        #dtn = datetime.datetime.now()
        
        #dateDict = {'username' : win32api.GetUserName(), 'day' : dtn.day, 'month' : dtn.month, 'year':dtn.year}
        
        self._base_dir = nameUtils.get_local_data_directory()
        self._dirname = os.sep.join([self._base_dir, ] + nameUtils.get_spool_subdir())
        self._cluster_dirname = self.get_cluster_dirname(self._dirname)

        self.seriesStub = defSeries % nameUtils.dateDict

        self.seriesCounter = 0
        self._series_name = None

        self.protocol = prot.NullProtocol
        self.protocolZ = prot.NullZProtocol
        
        self.onSpoolProgress = dispatch.Signal()
        self.onSpoolStart = dispatch.Signal()
        self.onSpoolStop = dispatch.Signal()

        self._analysis_launchers = queue.Queue(3)
        
        self._status_changed_condition = threading.Condition()
        
        #settings which were managed by GUI
        self.hdf_compression_level = 2 # zlib compression level that pytables should use (spool to file and queue)
        self.z_stepped = False  # z-step during acquisition
        self.z_dwell = 100 # time to spend at each z level (if z_stepped == True)
        self.cluster_h5 = False # spool to h5 on cluster (cluster of one)
        self.pzf_compression_settings=HTTPSpooler.defaultCompSettings # only for cluster spooling

        #check to see if we have a cluster
        self._N_data_servers = len(hybrid_ns.getNS('_pyme-http').get_advertised_services())
        if self._N_data_servers > 0:
            # switch to cluster as spool method if available.
            self.SetSpoolMethod('Cluster')
            
        if self._N_data_servers  == 1:
            self.cluster_h5 = True # we have a cluster of one