Esempio n. 1
0
    def find(self, name):
        """Returns the first overlay with the given ``name`` or ``dataSource``,
        or ``None`` if there is no overlay with said ``name``/``dataSource``.
        """

        if name is None:
            return None

        absname = op.abspath(name)

        for overlay in self.overlays:

            if overlay.name == name:
                return overlay

            if overlay.dataSource is None:
                continue

            # Ignore file extensions for NIFTI images.
            if isinstance(overlay, fslimage.Image):
                if fslimage.removeExt(overlay.dataSource) == \
                   fslimage.removeExt(absname):
                    return overlay
            else:
                if overlay.dataSource == absname:
                    return overlay

        return None
Esempio n. 2
0
def makergb(infile, nchannels):

    img = fslimage.Image(infile)
    indata = img.data[..., :nchannels]

    if nchannels == 3:
        dtype = np.dtype([('R', 'uint8'), ('G', 'uint8'), ('B', 'uint8')])
    else:
        dtype = np.dtype([('R', 'uint8'), ('G', 'uint8'), ('B', 'uint8'),
                          ('A', 'uint8')])

    outdata = np.zeros(indata.shape[:3], dtype=dtype)

    for cn, ci in zip('RGBA', range(nchannels)):
        cd = indata[..., ci].astype(np.float32)
        lo, hi = cd.min(), cd.max()
        cd = (ci + 1) * 255 * (cd - lo) / (hi - lo)
        outdata[cn] = np.round(cd).astype(np.uint8)

    img = fslimage.Image(outdata, header=img.header)
    name = fslimage.removeExt(op.basename(infile))
    name = '{}_makergb_{}'.format(name, nchannels)

    img.save(name)

    return name
Esempio n. 3
0
def asmgh(infile):
    outfile = op.basename(fslimage.removeExt(infile))
    outfile = outfile + '.mgh'
    inimg   = fslimage.Image(infile)
    outimg  = nib.MGHImage(inimg.data, inimg.voxToWorldMat)
    outimg.to_filename(outfile)
    return outfile
Esempio n. 4
0
def _statImageDisplay(overlay,
                      overlayList,
                      displayCtx,
                      zthres=3.0,
                      posCmap=None,
                      negCmap=None):
    """Configure default display settings for the given statistic
    :class:`.Image` overlay.
    """

    opts        = displayCtx.getOpts(overlay)
    basename    = op.basename(overlay.dataSource)
    basename    = fslimage.removeExt(basename)

    pTokens     = ['p', 'corrp']
    statTokens  = ['zstat', 'tstat', 'zfstat']
    fStatTokens = ['fstat']

    # Rendered stat images (e.g.
    # rendered_thres_zstat1) are
    # generated specifically for
    # use with the Render1 colour
    # map.
    if 'rendered' in basename:
        opts.cmap = 'Render1'

    # Give each normal stat image
    # a different colour map
    else:
        cmap = _statImageDisplay.cmaps[_statImageDisplay.currentCmap]

        if posCmap is None: posCmap = cmap
        if negCmap is None: negCmap = cmap

        _statImageDisplay.currentCmap += 1
        _statImageDisplay.currentCmap %= len(_statImageDisplay.cmaps)
        opts.cmap                      = posCmap
        opts.negativeCmap              = negCmap

    # The order of these tests is
    # important, due to name overlap

    # P-value image ?
    if any([token in basename for token in pTokens]):
        opts.displayRange  = [0.95, 1.0]
        opts.clippingRange = [0.95, 1.0]

    # T or Z stat image?
    elif any([token in basename for token in statTokens]) and \
       'rendered' not in basename:

        maxVal               = overlay.dataRange[1]
        opts.useNegativeCmap = True
        opts.clippingRange   = [zthres, maxVal]
        opts.displayRange    = [zthres, min((7.5, maxVal))]

    # F stat image?
    elif any([token in basename for token in fStatTokens]):
        opts.displayRange = [0, 10]
Esempio n. 5
0
def test_removeExt():

    exts = ['.nii.gz', '.nii', '.img', '.img.gz', '.hdr', '.hdr.gz']

    for e in exts:
        prefix = 'blob'
        fname = '{}{}'.format(prefix, e)

        assert fslimage.removeExt(fname) == prefix
Esempio n. 6
0
def zero_centre(infile):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_zero_centre.nii.gz'.format(basename)
    img = fslimage.Image(infile)
    data = img[:]
    img[:] = data - data.mean()

    img.save(outfile)

    return outfile
Esempio n. 7
0
def gen_indices(infile):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_indices.nii.gz'.format(basename)
    img = fslimage.Image(infile, loadData=False)
    shape = img.shape
    data = np.arange(np.prod(shape)).reshape(shape)

    fslimage.Image(data, header=img.header).save(outfile)

    return outfile
Esempio n. 8
0
def _isPEImage(overlay):
    """Returns ``True`` if the given :class:`.Image` overlay looks like a
    statistic image, ``False`` otherwise.
    """
    basename = op.basename(overlay.dataSource)
    basename = fslimage.removeExt(basename)
    tokens   = ['cope', 'pe']
    pattern  = '^({})\d+'.format('|'.join(tokens))

    return re.search(pattern, basename) is not None
Esempio n. 9
0
def binarise(infile, low, high, scale=1):

    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_binarised_{}_{}_{}.nii.gz'.format(basename, low, high, scale)
    img = fslimage.Image(infile)
    data = img[:]
    binned = ((data > low) & (data < high)).astype(np.uint8) * scale

    fslimage.Image(binned, header=img.header).save(outfile)

    return outfile
Esempio n. 10
0
def roi(fname, roi):
    base    = fslimage.removeExt(fname)
    outfile = '{}_roi_{}_{}_{}_{}_{}_{}'.format(base, *roi)

    img = fslimage.Image(fname)
    xs, xe, ys, ye, zs, ze = roi
    data = img[xs:xe, ys:ye, zs:ze, ...]
    img = fslimage.Image(data, header=img.header)

    img.save(outfile)

    return outfile
Esempio n. 11
0
def oblique(infile):

    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_oblique.nii.gz'.format(basename)
    img = fslimage.Image(infile)
    xform = img.getAffine('voxel', 'world')
    rot = affine.compose([1, 1, 1], [0, 0, 0], [0, 0, 1])
    xform = affine.concat(rot, xform)
    img = fslimage.Image(img.data, xform=xform)

    img.save(outfile)

    return outfile
Esempio n. 12
0
def sqformcodes(infile, sform, qform):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_sqformcodes_{}_{}.nii.gz'.format(basename, sform, qform)
    img = nib.load(infile)
    xform = img.affine

    img.set_sform(xform, sform)
    img.set_qform(xform, qform)
    img.update_header()

    nib.save(img, outfile)

    return outfile
Esempio n. 13
0
def translate(infile, x, y, z):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_translated_{}_{}_{}.nii.gz'.format(basename, x, y, z)
    img = fslimage.Image(infile)
    xform = img.voxToWorldMat

    shift = affine.scaleOffsetXform(1, (x, y, z))
    xform = affine.concat(shift, xform)
    img.voxToWorldMat = xform

    img.save(outfile)

    return outfile
Esempio n. 14
0
def imglob(paths, output=None):
    """Given a list of file names, identifies and returns the unique
    NIFTI/ANALYZE image files that exist.

    :arg paths:  Sequence of paths/prefixes to glob.

    :arg output: One of ``'prefix'`` (the default), ``'all'``, or
                 ``'primary'``:

                  - ``'prefix'``:  Returns the files without extensions.
                  - ``'all'``:     Returns all files that match (e.g. both
                                   ``.img`` and ``.hdr`` files will be
                                   returned).
                  - ``'primary'``: Returns only the primary file of each
                                   matching file group, e.g. only the
                                   ``.hdr`` file would be returned from
                                   an ``.img``/``.hdr`` pair.

    :returns: A sequence of resolved path names, in the form specified
              by the ``output`` parameter.
    """

    if output is None:
        output = 'prefix'

    if output not in ('prefix', 'all', 'primary'):
        raise ValueError('Unsupported output format: {}'.format(output))

    imgfiles = []

    # Build a list of all image files (both
    # hdr and img and otherwise) that match
    for path in paths:
        try:
            path = fslimage.removeExt(path)
            imgfiles.extend(fslimage.addExt(path, unambiguous=False))
        except fslpath.PathError:
            continue

    if output == 'prefix':
        imgfiles = fslpath.removeDuplicates(imgfiles,
                                            allowedExts=exts,
                                            fileGroups=groups)
        imgfiles = [fslpath.removeExt(f, exts) for f in imgfiles]

    elif output == 'primary':
        imgfiles = fslpath.removeDuplicates(imgfiles,
                                            allowedExts=exts,
                                            fileGroups=groups)

    return list(sorted(set(imgfiles)))
Esempio n. 15
0
def fliporient(filename):
    base = fslimage.removeExt(filename)
    outfile = '{}_flipped'.format(base)

    img = fslimage.Image(filename)

    aff = img.voxToWorldMat
    aff[0, 0] = -aff[0, 0]
    aff[0, 3] = aff[0, 3] - (img.shape[0] - 1) * img.pixdim[0]

    img.voxToWorldMat = aff
    img[:] = img[::-1, ...]

    img.save(outfile)
    return outfile
Esempio n. 16
0
def rotate(infile, rx, ry, rz):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_rotated_{}_{}_{}.nii.gz'.format(basename, rx, ry, rz)
    img = fslimage.Image(infile)

    rx = rx * np.pi / 180
    ry = ry * np.pi / 180
    rz = rz * np.pi / 180

    rot = affine.axisAnglesToRotMat(rx, ry, rz)
    rot = affine.rotMatToAffine(rot)
    img.voxToWorldMat = affine.concat(rot, img.voxToWorldMat)

    img.save(outfile)

    return outfile
Esempio n. 17
0
def asrgb(infile):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_asrgb.nii.gz'.format(basename)
    img = fslimage.Image(infile)
    data = img.data

    shape = data.shape[:3]
    rgbdtype = np.dtype([('R', 'uint8'), ('G', 'uint8'), ('B', 'uint8')])
    newdata = np.zeros(shape, dtype=rgbdtype)

    for c, ci in zip('RGB', range(3)):
        cd = (0.5 * data[..., ci] + 0.5) * 255
        newdata[c] = np.round(cd).astype(np.uint8)

    fslimage.Image(newdata, xform=img.voxToWorldMat).save(outfile)

    return outfile
Esempio n. 18
0
def isMelodicImage(path):
    """Returns ``True`` if the given path looks like it is a melodic
    component image file, ``False`` otherwise.
    """

    try:
        path = fslimage.addExt(path)
    except fslimage.PathError:
        return False

    dirname = op.dirname(path)
    filename = op.basename(path)
    filename = fslimage.removeExt(filename)

    prefixes = ['melodic_IC', 'melodic_oIC']

    return any([filename == p for p in prefixes]) and isMelodicDir(dirname)
Esempio n. 19
0
def cast(infile, dtype):

    base    = fslimage.removeExt(infile)
    outfile = '{}_cast_{}'.format(base, dtype.__name__)

    img = fslimage.Image(infile)

    data = img[:].astype(np.float)

    # force range to 0-255 so it looks
    # the same regardless of dtype
    data = 255 * (data - data.min()) / (data.max() - data.min())

    if dtype in (np.int8, np.int16, np.int32):
        data = data - 128

    fslimage.Image(data, header=img.header).save(outfile)
    return outfile
Esempio n. 20
0
def swapdim(infile):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_swapdim.nii.gz'.format(basename)
    img = fslimage.Image(infile)

    data = img.data
    xform = img.voxToWorldMat

    data = data.transpose((2, 0, 1))
    rot = affine.rotMatToAffine(
        affine.concat(affine.axisAnglesToRotMat(np.pi / 2, 0, 0),
                      affine.axisAnglesToRotMat(0, 0, 3 * np.pi / 2)))
    xform = affine.concat(xform, affine.scaleOffsetXform((1, -1, -1),
                                                         (0, 0, 0)), rot)

    fslimage.Image(data, xform=xform, header=img.header).save(outfile)

    return outfile
Esempio n. 21
0
def roi(fname, roi):

    base = fslimage.removeExt(op.basename(fname))
    outfile = '{}_roi_{}_{}_{}_{}_{}_{}'.format(base, *roi)

    img = fslimage.Image(fname)
    xs, xe, ys, ye, zs, ze = roi
    data = img[xs:xe, ys:ye, zs:ze, ...]

    xform = img.voxToWorldMat
    offset = [lo for lo in roi[::2]]
    offset = affine.scaleOffsetXform([1, 1, 1], offset)
    xform = affine.concat(xform, offset)

    img = fslimage.Image(data, xform=xform, header=img.header)

    img.save(outfile)

    return outfile
Esempio n. 22
0
def makevol(infile, nchannels):

    img = fslimage.Image(infile)
    data = img.data[..., :nchannels]

    newdata = np.zeros(data.shape, dtype=np.uint8)

    for c in range(nchannels):
        d = data[..., c].astype(np.float32) * (c + 1)
        lo, hi = d.min(), d.max()
        newdata[..., c] = np.round(255 * (c + 1) * (d - lo) /
                                   (hi - lo)).astype(np.uint8)

    img = fslimage.Image(newdata, header=img.header)
    name = fslimage.removeExt(op.basename(infile))
    name = '{}_makevol_{}'.format(name, nchannels)

    img.save(name)

    return name
Esempio n. 23
0
def invert(infile):

    if fslimage.looksLikeImage(infile):
        basename = fslimage.removeExt(op.basename(infile))
        img = fslimage.Image(infile)
        data = img.data
        dmin, dmax = data.min(), data.max()
        data = dmin + (dmax - data)
        outfile = '{}_inverted.nii.gz'.format(basename)
        fslimage.Image(data, header=img.header).save(outfile)

    # assume text file
    else:
        basename, ext = op.split(infile)
        data = np.loadtxt(infile)
        dmin, dmax = data.min(), data.max()
        data = dmin + (dmax - data)
        outfile = '{}_inverted.{}'.format(basename, ext)
        np.savetxt(outfile, data)

    return outfile
Esempio n. 24
0
def discretise(infile, stepsize, min=None, max=None):
    basename = fslimage.removeExt(op.basename(infile))
    img = fslimage.Image(infile)
    data = img[:]

    if min is None:
        min = data.min()
    if max is None:
        max = data.max()

    outfile = '{}_discretised_{}_{}_{}.nii.gz'.format(basename, stepsize, min,
                                                      max)

    for i, li in enumerate(range(min, max, stepsize)):
        data[(data >= li) & (data < (li + stepsize))] = i

    img[:] = data

    img.save(outfile)

    return outfile
Esempio n. 25
0
def _loadComplexImage(path):
    """Loads the specified ``path`` assumed to be a NIFTI image
    with complex data.

    The image is loaded as two separate :class:`.Image` instances,
    containing the real and imaginary components respectively.
    """

    import nibabel as nib
    import fsl.data.image as fslimage

    image = nib.load(path)
    hdr = image.header
    data = image.get_data()

    name = op.basename(fslimage.removeExt(path))
    rname = '{} [real]'.format(name)
    iname = '{} [imag]'.format(name)

    real = fslimage.Image(np.real(data), name=rname, header=hdr)
    imag = fslimage.Image(np.imag(data), name=iname, header=hdr)

    return real, imag
Esempio n. 26
0
def saveOverlay(overlay, display=None):
    """Saves the currently selected overlay (only if it is a :class:`.Image`),
    by a call to :meth:`.Image.save`. If a ``display`` is provided, the
    :attr:`.Display.name` may be updated to match the new overlay file name.

    :arg overlay: The :class:`.Image` overlay to save
    :arg display: The :class:`.Display` instance associated with the overlay.
    """

    import wx

    # TODO support for other overlay types
    if not isinstance(overlay, fslimage.Image):
        raise RuntimeError('Non-volumetric types not supported yet')

    # If this image has been loaded from a file,
    # ask the user whether they want to overwrite
    # that file, or save the image to a new file.
    #
    if overlay.dataSource is not None:

        # If the data source is not nifti (e.g.
        # mgz), we are not going to overwrite it,
        # so we don't ask.
        if fslimage.looksLikeImage(overlay.dataSource):

            msg = strings.messages['SaveOverlayAction.overwrite'].format(
                overlay.dataSource)
            title = strings.titles['SaveOverlayAction.overwrite'].format(
                overlay.dataSource)

            dlg = wx.MessageDialog(wx.GetTopLevelWindows()[0],
                                   message=msg,
                                   caption=title,
                                   style=(wx.ICON_WARNING | wx.YES_NO
                                          | wx.CANCEL | wx.NO_DEFAULT))
            dlg.SetYesNoCancelLabels(
                strings.labels['SaveOverlayAction.overwrite'],
                strings.labels['SaveOverlayAction.saveNew'],
                strings.labels['SaveOverlayAction.cancel'])

            response = dlg.ShowModal()

            # Cancel == cancel the save
            # Yes    == overwrite the existing file
            # No     == save to a new file (prompt the user for the file name)
            if response == wx.ID_CANCEL:
                return

            if response == wx.ID_YES:
                doSave(overlay)
                return

        fromDir = op.dirname(overlay.dataSource)
        filename = fslimage.removeExt(op.basename(overlay.dataSource))
        filename = '{}_copy'.format(filename)
    else:
        fromDir = fslsettings.read('loadSaveOverlayDir', os.getcwd())

        if display is not None: filename = display.name
        else: filename = overlay.name

    filename = filename.replace('/', '_')
    filename = filename.replace('\\', '_')

    # Ask the user where they
    # want to save the image
    msg = strings.titles['SaveOverlayAction.saveFile']
    dlg = wx.FileDialog(wx.GetApp().GetTopWindow(),
                        message=msg,
                        defaultDir=fromDir,
                        defaultFile=filename,
                        style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

    if dlg.ShowModal() != wx.ID_OK:
        return

    # Make sure that the user chose a supported
    # extension. If not, use the default extension.
    savePath = dlg.GetPath()
    prefix, suffix = fslimage.splitExt(savePath)

    if suffix == '':
        savePath = '{}{}'.format(prefix, fslimage.defaultExt())

    oldPath = overlay.dataSource
    saveDir = op.dirname(savePath)

    if doSave(overlay, savePath):

        # Cache the save directory for next time.
        fslsettings.write('loadSaveOverlayDir', saveDir)

        # If image was in memory, or its old
        # name equalled the old datasource
        # base name, update its name.
        if oldPath is None or \
           fslimage.removeExt(op.basename(oldPath)) == overlay.name:

            overlay.name = fslimage.removeExt(op.basename(savePath))

            if display is not None:
                display.name = overlay.name
Esempio n. 27
0
    def __init__(self,
                 parent,
                 srcFile,
                 refOpts=None,
                 refOptFiles=None,
                 selectedRef=None,
                 matFile=None,
                 refFile=None,
                 save=False):
        """Create a ``FlirtFileDialog``.

        :arg parent:      The ``wx`` parent object.

        :arg srcFile:     Path to the FLIRT source image file

        :arg refOpts:     Options to use in the reference image drop down box.

        :arg refOptFiles: File paths which correspond to the ``refOpts``.

        :arg selectedRef: Index of initially selected ``refOpt``.

        :arg matFile:     Initial path to a FLIRT transformation matrix file

        :arg refFile:     Initial Path to a FLIRT reference image file

        :arg save:        If ``True``, the user will be prompted to save a
                          FLIRT matrix. Otherwise (the default), the user will
                          be prompted to load an existing FLIRT matrix.
        """

        titleKey = {True: 'save', False: 'load'}[save]

        wx.Dialog.__init__(self,
                           parent,
                           title=strings.titles[self, titleKey],
                           style=(wx.DEFAULT_DIALOG_STYLE | wx.STAY_ON_TOP))

        if refOpts is None: refOpts = []
        if refOptFiles is None: refOptFiles = []
        if selectedRef is None: selectedRef = 0

        self.__srcFile = srcFile
        self.__refOpts = list(refOpts)
        self.__refOptFiles = list(refOptFiles)
        self.__matFile = None
        self.__refFile = None
        self.__save = save
        self.__affineTypes = ['flirt', 'v2w']

        affTypeOpts = [
            strings.labels[self, 'affType', at] for at in self.__affineTypes
        ]

        refOpts = list(refOpts) + [strings.labels[self, 'refChoiceSelectFile']]

        overlayName = wx.StaticText(self, style=wx.ALIGN_CENTRE_HORIZONTAL)
        label = wx.StaticText(self, style=wx.ALIGN_CENTRE_HORIZONTAL)
        affType = wx.Choice(self, choices=affTypeOpts)
        affTypeLabel = wx.StaticText(self)
        refChoiceLabel = wx.StaticText(self)
        matFileLabel = wx.StaticText(self)
        refFileLabel = wx.StaticText(self)
        refChoice = wx.Choice(self, choices=refOpts)
        matFileText = wx.TextCtrl(self)
        refFileText = wx.TextCtrl(self)
        matFileButton = wx.Button(self)
        refFileButton = wx.Button(self)
        okButton = wx.Button(self, wx.ID_OK)
        cancelButton = wx.Button(self, wx.ID_CANCEL)

        self.__matFileText = matFileText
        self.__refFileText = refFileText
        self.__refFileLabel = refFileLabel
        self.__refFileButton = refFileButton
        self.__refChoiceLabel = refChoiceLabel
        self.__refChoice = refChoice
        self.__affType = affType

        if srcFile is None:
            srcName = strings.labels[self, 'inmemory']
        else:
            srcName = op.basename(srcFile)
            srcName = fslimage.removeExt(srcFile)

        overlayName.SetLabel(strings.labels[self, 'source'].format(srcName))
        affTypeLabel.SetLabel(strings.labels[self, 'affType'])
        refChoiceLabel.SetLabel(strings.labels[self, 'refImage'])
        matFileLabel.SetLabel(strings.labels[self, 'matFile'])
        refFileLabel.SetLabel(strings.labels[self, 'refFile'])
        matFileButton.SetLabel(strings.labels[self, 'selectFile'])
        refFileButton.SetLabel(strings.labels[self, 'selectFile'])
        okButton.SetLabel(strings.labels[self, 'ok'])
        cancelButton.SetLabel(strings.labels[self, 'cancel'])
        refChoice.SetSelection(selectedRef)
        affType.SetSelection(0)

        if save: label.SetLabel(strings.labels[self, 'save.message'])
        else: label.SetLabel(strings.labels[self, 'load.message'])

        if matFile is not None:
            matFileText.SetValue(matFile)
            matFileText.SetInsertionPointEnd()
        if refFile is not None:
            refFileText.SetValue(refFile)
            refFileText.SetInsertionPointEnd()

        sizer = wx.BoxSizer(wx.VERTICAL)
        widgetSizer = wx.FlexGridSizer(4, 3, 0, 0)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)

        widgetSizer.AddGrowableCol(1)

        sizer.Add((1, 10), flag=wx.EXPAND)
        sizer.Add(overlayName, flag=wx.ALIGN_CENTRE)
        sizer.Add((1, 10), flag=wx.EXPAND)
        sizer.Add(label, flag=wx.ALIGN_CENTRE)
        sizer.Add((1, 10), flag=wx.EXPAND)
        sizer.Add(widgetSizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=10)
        sizer.Add((1, 10), flag=wx.EXPAND)
        sizer.Add(btnSizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=10)
        sizer.Add((1, 10), flag=wx.EXPAND)

        widgetSizer.Add(affTypeLabel, flag=wx.ALL, border=3)
        widgetSizer.Add(affType, flag=wx.EXPAND, proportion=1)
        widgetSizer.Add((-1, -1))

        if refOpts is not None:
            widgetSizer.Add(refChoiceLabel, flag=wx.ALL, border=3)
            widgetSizer.Add(refChoice, flag=wx.EXPAND, proportion=1)
            widgetSizer.Add((-1, -1))
        else:
            widgetSizer.Add((-1, -1))
            widgetSizer.Add((-1, -1))
            widgetSizer.Add((-1, -1))

        widgetSizer.Add(refFileLabel, flag=wx.ALL, border=3)
        widgetSizer.Add(refFileText, flag=wx.EXPAND, proportion=1)
        widgetSizer.Add(refFileButton, flag=wx.EXPAND)
        widgetSizer.Add(matFileLabel, flag=wx.ALL, border=3)
        widgetSizer.Add(matFileText, flag=wx.EXPAND, proportion=1)
        widgetSizer.Add(matFileButton, flag=wx.EXPAND)

        btnSizer.Add((10, 1), flag=wx.EXPAND, proportion=1)
        btnSizer.Add(okButton, flag=wx.EXPAND)
        btnSizer.Add((10, 1), flag=wx.EXPAND)
        btnSizer.Add(cancelButton, flag=wx.EXPAND)
        btnSizer.Add((10, 1), flag=wx.EXPAND, proportion=1)

        matFileText.SetMinSize((400, -1))
        refFileText.SetMinSize((400, -1))

        okButton.SetDefault()
        self.SetSizer(sizer)

        okButton.Bind(wx.EVT_BUTTON, self.__onOkButton)
        cancelButton.Bind(wx.EVT_BUTTON, self.__onCancelButton)
        matFileButton.Bind(wx.EVT_BUTTON, self.__onMatFileButton)
        refFileButton.Bind(wx.EVT_BUTTON, self.__onRefFileButton)
        affType.Bind(wx.EVT_CHOICE, self.__onAffType)
        refChoice.Bind(wx.EVT_CHOICE, self.__onRefChoice)

        self.__okButton = okButton
        self.__cancelButton = cancelButton
        self.__matFileText = matFileText
        self.__refFileText = refFileText
        self.__affType = affType
        self.__refChoice = refChoice

        if len(refOpts) == 1:
            refChoice.Disable()
            refChoiceLabel.Disable()
        else:
            self.__onRefChoice(None)