示例#1
0
def applyCommandLineArgs(overlayList,
                         displayCtx,
                         argv,
                         panel=None,
                         applyOverlayArgs=True,
                         **kwargs):
    """Applies the command line arguments stored in ``argv`` to the
    :class:`.CanvasPanel` ``panel``. If ``panel is None``, it is assumed
    that ``argv`` only contains overlay arguments.

    :arg overlayList:      The :class:`.OverlayList`.

    :arg displayCtx:       The :class:`.DisplayContext`. If a ``panel`` is
                           provided, this should be the ``DisplayContext``
                           associated with that panel.

    :arg argv:             List of command line arguments to apply.
    :arg panel:            Optional :class:`.CanvasPanel` to apply the
                           arguments to.

    :arg applyOverlayArgs: If ``False``, overlay arguments are not applied.

    All other keyword arguments are passed to the
    :func:`.parseargs.applyOverlayArgs`  function.
    """

    # We patch sys.stdout/stderr
    # while parseargs.parseArgs is
    # called so we can capture its
    # output.
    stdout = six.StringIO()
    stderr = six.StringIO()

    if argv[0] == 'fsleyes':
        argv = argv[1:]

    parser = argparse.ArgumentParser(add_help=False)

    try:
        real_stdout = sys.stdout
        real_stderr = sys.stderr
        sys.stdout = stdout
        sys.stderr = stderr
        namespace = parseargs.parseArgs(parser, argv, 'fsleyes')

    except SystemExit as e:
        raise ApplyCLIExit(e.code, stdout.getvalue(), stderr.getvalue())

    finally:
        sys.stdout = real_stdout
        sys.stderr = real_stderr

    if applyOverlayArgs:
        parseargs.applyOverlayArgs(namespace, overlayList, displayCtx,
                                   **kwargs)

    if panel is not None:
        sceneOpts = panel.sceneOpts
        parseargs.applySceneArgs(namespace, overlayList, displayCtx, sceneOpts)
示例#2
0
def makeDisplayContext(namespace, splash):
    """Creates the top-level *FSLeyes* :class:`.DisplayContext` and
    :class:`.OverlayList` .

    This function does the following:

     1. Creates the :class:`.OverlayList` and the top level
        :class:`.DisplayContext`.

     2. Loads and configures all of the overlays which were passed in on the
        command line.

    :arg namesace: Parsed command line arguments (see :func:`parseArgs`).

    :arg splash:   The :class:`.FSLeyesSplash` frame, created in :func:`init`.

    :returns: a tuple containing:
                - the :class:`.OverlayList`
                - the master :class:`.DisplayContext`
    """

    import fsleyes_widgets.utils.status as status
    import fsleyes.overlay as fsloverlay
    import fsleyes.parseargs as parseargs
    import fsleyes.displaycontext as displaycontext

    # Splash status update must be
    # performed on the main thread.
    def splashStatus(msg):
        wx.CallAfter(splash.SetStatus, msg)

    # Redirect status updates
    # to the splash frame
    status.setTarget(splashStatus)

    # Create the overlay list (only one of these
    # ever exists) and the master DisplayContext.
    # A new DisplayContext instance will be
    # created for every new view that is opened
    # in the FSLeyesFrame, but all child
    # DisplayContext instances will be linked to
    # this master one.
    overlayList = fsloverlay.OverlayList()
    displayCtx = displaycontext.DisplayContext(overlayList)

    log.debug('Created overlay list and master DisplayContext ({})'.format(
        id(displayCtx)))

    # Load the images - the splash screen status will
    # be updated with the currently loading overlay name.
    parseargs.applyMainArgs(namespace, overlayList, displayCtx)
    parseargs.applyOverlayArgs(namespace, overlayList, displayCtx)

    return overlayList, displayCtx
示例#3
0
def applyCommandLineArgs(overlayList, displayCtx, argv, panel=None):
    """Applies the command line arguments stored in ``argv`` to the
    :class:`.CanvasPanel` ``panel``. If ``panel is None``, it is assumed
    that ``argv`` only contains overlay arguments.
    """

    # We patch sys.stdout/stderr
    # while parseargs.parseArgs is
    # called so we can capture its
    # output.
    stdout = six.StringIO()
    stderr = six.StringIO()

    if argv[0] == 'fsleyes':
        argv = argv[1:]

    parser = argparse.ArgumentParser(add_help=False)

    try:
        real_stdout = sys.stdout
        real_stderr = sys.stderr
        sys.stdout = stdout
        sys.stderr = stderr
        namespace = parseargs.parseArgs(parser, argv, 'fsleyes')

    except SystemExit as e:
        raise ApplyCLIExit(e.code, stdout.getvalue(), stderr.getvalue())

    finally:
        sys.stdout = real_stdout
        sys.stderr = real_stderr

    parseargs.applyOverlayArgs(namespace, overlayList, displayCtx)

    # No panel, no need to do anything else
    if panel is None:
        return

    sceneOpts = panel.sceneOpts
    parseargs.applySceneArgs(namespace, overlayList, displayCtx, sceneOpts)
示例#4
0
def makeDisplayContext(namespace):
    """Creates :class:`.OverlayList`, :class:`.DisplayContext``, and
    :class:`.SceneOpts` instances which represent the scene to be rendered,
    as described by the arguments in the given ``namespace`` object.
    """

    # Create an overlay list and display context.
    # The DisplayContext, Display and DisplayOpts
    # classes are designed to be created in a
    # parent-child hierarchy. So we need to create
    # a 'dummy' master display context to make
    # things work properly.
    overlayList = fsloverlay.OverlayList()
    masterDisplayCtx = displaycontext.DisplayContext(overlayList)
    childDisplayCtx = displaycontext.DisplayContext(overlayList,
                                                    parent=masterDisplayCtx)

    # We have to artificially create a ref to the
    # master display context, otherwise it may get
    # gc'd arbitrarily. The parent reference in the
    # child creation above is ultimately stored as
    # a weakref, so we need to create a real one.
    childDisplayCtx.masterDisplayCtx = masterDisplayCtx

    # The handleOverlayArgs function uses the
    # fsleyes.overlay.loadOverlays function,
    # which will call these functions as it
    # goes through the list of overlay to be
    # loaded.
    def load(ovl):
        log.info('Loading overlay {} ...'.format(ovl))

    def error(ovl, error):
        log.info('Error loading overlay {}: '.format(ovl, error))

    # Load the overlays specified on the command
    # line, and configure their display properties
    parseargs.applyOverlayArgs(namespace,
                               overlayList,
                               masterDisplayCtx,
                               loadFunc=load,
                               errorFunc=error)

    # Create a SceneOpts instance describing
    # the scene to be rendered. The parseargs
    # module assumes that GL canvases have
    # already been created, so we use mock
    # objects to trick it. The options applied
    # to these mock objects are applied to the
    # real canvases later on, in the render
    # function below.
    if namespace.scene == 'ortho':
        sceneOpts = orthoopts.OrthoOpts(MockCanvasPanel(3))
    elif namespace.scene == 'lightbox':
        sceneOpts = lightboxopts.LightBoxOpts(MockCanvasPanel(1))
    elif namespace.scene == '3d':
        sceneOpts = scene3dopts.Scene3DOpts(MockCanvasPanel(1))

    # 3D views default to
    # world display space
    if namespace.scene == '3d':
        childDisplayCtx.displaySpace = 'world'

    parseargs.applySceneArgs(namespace, overlayList, childDisplayCtx,
                             sceneOpts)

    # Centre the location. The DisplayContext
    # will typically centre its location on
    # initialisation, but this may not work
    # if any overlay arguments change the bounds
    # of an overlay (e.g. mesh reference image)
    if namespace.worldLoc is None and namespace.voxelLoc is None:
        b = childDisplayCtx.bounds
        childDisplayCtx.location = [
            b.xlo + 0.5 * b.xlen, b.ylo + 0.5 * b.ylen, b.zlo + 0.5 * b.zlen
        ]

    # This has to be applied after applySceneArgs,
    # in case the user used the '-std'/'-std1mm'
    # options.
    if namespace.selectedOverlay is not None:
        masterDisplayCtx.selectedOverlay = namespace.selectedOverlay

    if len(overlayList) == 0:
        raise RuntimeError('At least one overlay must be specified')

    return overlayList, childDisplayCtx, sceneOpts
示例#5
0
def makeDisplayContext(namespace, splash):
    """Creates the top-level *FSLeyes* :class:`.DisplayContext` and
    :class:`.OverlayList` .

    This function does the following:

     1. Creates the :class:`.OverlayList` and the top level
        :class:`.DisplayContext`.

     2. Loads and configures all of the overlays which were passed in on the
        command line.

    :arg namesace: Parsed command line arguments (see :func:`parseArgs`).

    :arg splash:   The :class:`.FSLeyesSplash` frame, created in :func:`init`.

    :returns: a tuple containing:
                - the :class:`.OverlayList`
                - the master :class:`.DisplayContext`
    """

    import fsleyes_widgets.utils.status as status
    import fsleyes.overlay as fsloverlay
    import fsleyes.parseargs as parseargs
    import fsleyes.displaycontext as displaycontext

    # Splash status update must be
    # performed on the main thread.
    def splashStatus(msg):
        wx.CallAfter(splash.SetStatus, msg)

    # Redirect status updates
    # to the splash frame
    status.setTarget(splashStatus)

    # Create the overlay list (only one of these
    # ever exists) and the master DisplayContext.
    # A new DisplayContext instance will be
    # created for every new view that is opened
    # in the FSLeyesFrame, but all child
    # DisplayContext instances will be linked to
    # this master one.
    overlayList = fsloverlay.OverlayList()
    displayCtx = displaycontext.DisplayContext(overlayList)

    # While the DisplayContext may refer to
    # multiple overlay groups, we are currently
    # using just one, allowing the user to specify
    # a set of overlays for which their display
    # properties are 'locked'.
    lockGroup = displaycontext.OverlayGroup(displayCtx, overlayList)
    displayCtx.overlayGroups.append(lockGroup)

    log.debug('Created overlay list and master DisplayContext ({})'.format(
        id(displayCtx)))

    # Load the images - the splash screen status will
    # be updated with the currently loading overlay name.
    #
    # The applyOverlayArgs function gets called before
    # the applySceneArgs function, so we'll manually
    # apply some important settings to the DC here so
    # they get used when any overlays are loaded.
    if namespace.bigmem is not None:
        displayCtx.loadInMemory = namespace.bigmem
    if namespace.autoDisplay is not None:
        displayCtx.autoDisplay = namespace.autoDisplay

    parseargs.applyOverlayArgs(namespace, overlayList, displayCtx)

    return overlayList, displayCtx
示例#6
0
def applyCommandLineArgs(overlayList,
                         displayCtx,
                         argv,
                         panel=None,
                         applyOverlayArgs=True,
                         baseDir=None,
                         **kwargs):
    """Applies the command line arguments stored in ``argv`` to the
    :class:`.CanvasPanel` ``panel``. If ``panel is None``, it is assumed
    that ``argv`` only contains overlay arguments.

    :arg overlayList:      The :class:`.OverlayList`.

    :arg displayCtx:       The :class:`.DisplayContext`. If a ``panel`` is
                           provided, this should be the ``DisplayContext``
                           associated with that panel.

    :arg argv:             List of command line arguments to apply.

    :arg panel:            Optional :class:`.CanvasPanel` to apply the
                           arguments to.

    :arg applyOverlayArgs: If ``False``, overlay arguments are not applied.

    :arg baseDir:          Directory from which to interpret the arguments,
                           in case this is different from the current working
                           directory, and overlays have been specified with
                           relative paths.

    All other keyword arguments are passed to the
    :func:`.parseargs.applyOverlayArgs`  function.
    """

    # We patch sys.stdout/stderr
    # while parseargs.parseArgs is
    # called so we can capture its
    # output.
    stdout = six.StringIO()
    stderr = six.StringIO()

    if argv[0] == 'fsleyes':
        argv = argv[1:]

    parser = argparse.ArgumentParser(add_help=False)

    try:
        real_stdout = sys.stdout
        real_stderr = sys.stderr
        sys.stdout = stdout
        sys.stderr = stderr

        with chdir(baseDir):
            namespace = parseargs.parseArgs(parser, argv, 'fsleyes')

    except SystemExit as e:
        raise ApplyCLIExit(e.code, stdout.getvalue(), stderr.getvalue())

    finally:
        sys.stdout = real_stdout
        sys.stderr = real_stderr

    if baseDir is not None:
        for o in namespace.overlays:
            if not op.isabs(o.overlay):
                o.overlay = op.join(baseDir, o.overlay)

    if applyOverlayArgs:
        parseargs.applyOverlayArgs(namespace, overlayList, displayCtx,
                                   **kwargs)

    if panel is not None:
        sceneOpts = panel.sceneOpts
        parseargs.applySceneArgs(namespace, overlayList, displayCtx, sceneOpts)