application example: apod_viewer_1win

This is a sample GUI application showing how nmrglue can be used with additional python modules like matplotlib and wxPython to create full fledged NMR applications.

In this application users can examine graphically the apodization windows produced by the various window functions supported by NMRPipe. In this example the canvas in which the apodization windows are drawn and the location to input the apodization parameter are contained in the same window. The application example: apod_viewer_2win example has the canvas and input area in seperate windows.

[source code]

#!/usr/bin/env python
"""
An example of using wxPython to build a GUI application using nmrglue
This application displays NMRPipe apodization windows.
"""

import wx
import numpy as np
import nmrglue as ng
import matplotlib

# uncomment the following to use wx rather than wxagg
#matplotlib.use('WX')
#from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas

# comment out the following to use wx rather than wxagg
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure

apod_list = ["SP", "EM", "GM", "GMB", "TM", "TRI", "JMOD"]

class ParameterPanel(wx.Panel):
    """ WX panel where apodization parameters can be set by the user """

    def __init__(self, parent):
        """ Initialize the frame """
        wx.Panel.__init__(self, parent, -1)

        self.parent = parent

        # create the various elements in the panel
        self.qName1 = wx.StaticText(self, -1, "Type:")
        self.qName2 = wx.Choice(self, -1, choices=apod_list)
        self.Bind(wx.EVT_CHOICE, self.ApodChoose, self.qName2)
        
        self.q1_1 = wx.StaticText(self, -1, "q1:")
        self.q1_2 = wx.TextCtrl(self, -1, "0.0")

        self.q2_1 = wx.StaticText(self, -1, "q2:")
        self.q2_2 = wx.TextCtrl(self, -1, "1.0")
        
        self.q3_1 = wx.StaticText(self, -1, "q3:")
        self.q3_2 = wx.TextCtrl(self, -1, "1.0")

        self.c1 = wx.StaticText(self, -1, "c")
        self.c2 = wx.TextCtrl(self, -1, "1.0")

        self.start_1 = wx.StaticText(self, -1, "Start")
        self.start_2 = wx.TextCtrl(self, -1, "1.0")

        self.size_1 = wx.StaticText(self, -1, "Size")
        self.size_1.Enable(False)
        self.size_2 = wx.TextCtrl(self, -1, "1.0")
        self.size_2.Enable(False)

        self.inv = wx.CheckBox(self, -1, "Invert")

        self.use_size = wx.CheckBox(self, -1, "Custom Size")
        self.Bind(wx.EVT_CHECKBOX, self.OnLimitCheck, self.use_size)

        self.points_1 = wx.StaticText(self, -1, "Number of Points:")
        self.points_2 = wx.TextCtrl(self, -1, "1000")

        self.sw_1 = wx.StaticText(self, -1, "Spectral Width:")
        self.sw_2 = wx.TextCtrl(self, -1, "50000.")

        self.b1 = wx.Button(self, 10, "Draw")
        self.Bind(wx.EVT_BUTTON, self.OnDraw, self.b1)
        self.b1.SetDefault()

        self.b2 = wx.Button(self, 20, "Clear")
        self.Bind(wx.EVT_BUTTON, self.OnClear, self.b2)
        self.b2.SetDefault()

        self.InitApod("SP")

        # layout of the panel
        apod_grid = wx.GridSizer(8, 2)

        apod_grid.AddMany([self.qName1, self.qName2,
                   self.q1_1, self.q1_2,
                   self.q2_1, self.q2_2,
                   self.q3_1, self.q3_2, 
                   self.c1, self.c2,
                   self.start_1, self.start_2,
                   self.size_1, self.size_2,
                   self.inv, self.use_size])
        
        data_grid = wx.GridSizer(2, 2)
        data_grid.AddMany([self.points_1, self.points_2,
                self.sw_1, self.sw_2])

        apod_box = wx.StaticBoxSizer(wx.StaticBox(self, -1, 
                                        "Apodization Parameters"))
        apod_box.Add(apod_grid)

        data_box = wx.StaticBoxSizer(wx.StaticBox(self, -1,
                                        "Data Parameters"))
        data_box.Add(data_grid)

        button_box = wx.GridSizer(1, 2)
        button_box.AddMany([self.b1, self.b2])

        mainbox = wx.BoxSizer(wx.VERTICAL)
        mainbox.Add(apod_box)
        mainbox.Add(data_box)
        mainbox.Add(button_box)
        self.SetSizer(mainbox)

    def OnLimitCheck(self, event):
        """ Set the custom size when the check box is checked.  """
        k = event.IsChecked()
        self.size_1.Enable(k)
        self.size_2.Enable(k)
        points = float(self.points_2.GetValue())
        self.size_2.SetValue(str(points))

    def ApodChoose(self, event):
        """ Set the choosen apodization type """
        self.InitApod(apod_list[self.qName2.GetCurrentSelection()])

    def InitApod(self, qName):
        """ Set the default parameter for a choosen apodization window """
        
        if qName == "SP":
            self.q1_1.Enable(True)
            self.q1_1.SetLabel("off")
            self.q1_2.Enable(True)
            self.q1_2.SetValue("0.0")

            self.q2_1.Enable(True)
            self.q2_1.SetLabel("end")
            self.q2_2.Enable(True)
            self.q2_2.SetValue("1.0")

            self.q3_1.Enable(True)
            self.q3_1.SetLabel("pow")
            self.q3_2.Enable(True)
            self.q3_2.SetValue("1.0")

        elif qName == "EM":
            self.q1_1.Enable(True)
            self.q1_1.SetLabel("lb (Hz)")
            self.q1_2.Enable(True)
            self.q1_2.SetValue("0.0")

            self.q2_1.Enable(False)
            self.q2_2.Enable(False)

            self.q3_1.Enable(False)
            self.q3_2.Enable(False)

        elif qName == "GM":
            self.q1_1.Enable(True)
            self.q1_1.SetLabel("g1 (Hz)")
            self.q1_2.Enable(True)
            self.q1_2.SetValue("0.0")

            self.q2_1.Enable(True)
            self.q2_1.SetLabel("g2 (Hz)")
            self.q2_2.Enable(True)
            self.q2_2.SetValue("0.0")

            self.q3_1.Enable(True)
            self.q3_1.SetLabel("g3")
            self.q3_2.Enable(True)
            self.q3_2.SetValue("0.0")

        elif qName == "GMB":
            self.q1_1.Enable(True)
            self.q1_1.SetLabel("lb")
            self.q1_2.Enable(True)
            self.q1_2.SetValue("0.0")

            self.q2_1.Enable(True)
            self.q2_1.SetLabel("gb")
            self.q2_2.Enable(True)
            self.q2_2.SetValue("0.0")

            self.q3_1.Enable(False)
            self.q3_2.Enable(False)

        elif qName == "TM":
            self.q1_1.Enable(True)
            self.q1_1.SetLabel("t1")
            self.q1_2.Enable(True)
            self.q1_2.SetValue("0.0")

            self.q2_1.Enable(True)
            self.q2_1.SetLabel("t2")
            self.q2_2.Enable(True)
            self.q2_2.SetValue("0.0")

            self.q3_1.Enable(False)
            self.q3_2.Enable(False)

        elif qName == "TRI":
            self.q1_1.Enable(True)
            self.q1_1.SetLabel("loc")
            self.q1_2.Enable(True)
            points = points = float(self.points_2.GetValue())
            self.q1_2.SetValue(str(points / 2.))

            self.q2_1.Enable(True)
            self.q2_1.SetLabel("lHi")
            self.q2_2.Enable(True)
            self.q2_2.SetValue("0.0")

            self.q3_1.Enable(True)
            self.q3_1.SetLabel("rHi")
            self.q3_2.Enable(True)
            self.q3_2.SetValue("0.0")

        elif qName == "JMOD":
            self.q1_1.Enable(True)
            self.q1_1.SetLabel("off")
            self.q1_2.Enable(True)
            self.q1_2.SetValue("0.0")

            self.q2_1.Enable(True)
            self.q2_1.SetLabel("j (Hz)")
            self.q2_2.Enable(True)
            self.q2_2.SetValue("0.0")

            self.q3_1.Enable(True)
            self.q3_1.SetLabel("lb (Hz)")
            self.q3_2.Enable(True)
            self.q3_2.SetValue("0.0")

    def OnDraw(self, event):
        """ Draw the apodization window """
        qName = apod_list[self.qName2.GetCurrentSelection()]
        q1 = float(self.q1_2.GetValue())
        q2 = float(self.q2_2.GetValue())
        q3 = float(self.q3_2.GetValue())
        c = float(self.c2.GetValue())
        start = float(self.start_2.GetValue())
        size = float(self.size_2.GetValue())
        
        inv = self.inv.GetValue()
        use_size = self.use_size.GetValue()

        points = float(self.points_2.GetValue())
        sw = float(self.sw_2.GetValue())

        self.parent.ApplyApod(qName, q1, q2, q3, c, start, size, inv, 
                                use_size, points, sw)
        
    def OnClear(self, event):
        """ Clear all apodization windows previously drawn """
        self.parent.ClearFigure()

class CanvasFrame(wx.Frame):
    """ 
    WX frame containing a matplotlib canvas where the apodization windows are
    drawn and the parameter panel where apodization parameter can be set.
    """
    def __init__(self):
        """ Initializate the frame """
        wx.Frame.__init__(self, None, -1, 'Apodization Viewer')

        self.SetBackgroundColour(wx.NamedColor("WHITE"))

        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.params = ParameterPanel(self)
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        
        # layout
        fsizer = wx.BoxSizer(wx.VERTICAL)
        fsizer.Add(self.canvas, 0, wx.EXPAND)
        fsizer.Add(self.toolbar, 0, wx.EXPAND)

        self.sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.sizer.Add(self.params, 0, wx.EXPAND) 
        self.sizer.Add(fsizer, 0, wx.EXPAND)

        self.SetSizer(self.sizer)
        self.Fit()

    def OnPaint(self, event):
        """ Draw the apodization window """
        self.canvas.draw()

    def ClearFigure(self):
        """ Clear all previously drawn apodization windows """
        self.axes.cla()
        self.OnPaint(-1)

    def ApplyApod(self, qName, q1, q2, q3, c, start, size, inv, use_size, 
                    points, sw):
        """ Apply the selected apodization, draw the windows on the canvas """
        
        # create the dictionary
        dic = ng.fileiobase.create_blank_udic(1)
        dic[0]["sw"] = sw
        dic[0]["size"] = points

        # create the data
        data = np.ones(points, dtype="complex")

        # convert to NMRPipe format
        C = ng.convert.converter()
        C.from_universal(dic, data)
        pdic, pdata = C.to_pipe()

        if use_size == True:
            tsize = size
        else:
            tsize = 'default'
        null, apod_data = ng.pipe_proc.apod(pdic, pdata, qName=qName,
                q1=q1, q2=q2, q3=q3, c=c, inv=inv, size=tsize, start=start)

        # draw the window
        #self.axes.cla()
        self.axes.plot(apod_data)
        self.OnPaint(-1)

class App(wx.App):
    """ Wx application """
    def OnInit(self):
        """ Create the main window and insert the custom frame """
        frame = CanvasFrame()
        frame.Show(True)
        return True

app = App(0)
app.MainLoop()