典型的なコンポーネントの例

PyLAFでは1ビュー1パラメータパネルの典型的なコンポーネントを簡単に作成するため、 サポートクラスEasyComponentを用意しています。 以下は正弦波を発生させるコンポーネントです。

FGSIN.png

  1. # coding: utf-8
  2. import Tkinter
  3. # PyLAFをロードするとTkinterが暗黙でインポートされるが、
  4. # Pythonに不慣れなユーザが混乱しないよう、わかりやすさの為にTkinterを明示的にインポートした
  5. from PyLAF import *
  6. from scipy import savetxt
  7. class FGSIN(EasyComponent):
  8. PLOTTER = Oscilloscope
  9. def __init__(self,master=None):
  10. EasyComponent.__init__(self,master)
  11. self.mag = EasyPort(Variable(1.),'Magnitude [mV]').bind(self.trigger)
  12. self.freq = EasyPort(Variable(0.01),'Frequency [MHz]').bind(self.trigger)
  13. self.phase = EasyPort(Variable(0.),'Phase Offset [deg]').bind(self.trigger)
  14. self.bias = EasyPort(Variable(0.),'Bias Voltage [mV]').bind(self.trigger)
  15. self.dt = EasyPort(Variable(1.),'Time Step [us]').bind(self.trigger)
  16. self.tend = EasyPort(Variable(500.),'End [us]').bind(self.trigger)
  17. self._menu = [['File', ['Load', None],
  18. ['Save', ['All', None],
  19. ['As' , self.save]]],
  20. ['Edit', ['Copy' , None],
  21. ['Cut' , None],
  22. ['Paste', None]]
  23. ]
  24. def trigger(self):
  25. t = arange(0.,self.tend.get(),self.dt.get())
  26. self.sig_out.set(self.mag.get() * sin(2 * pi * self.freq.get() * t + self.phase.get() / 180. * pi) + self.bias.get())
  27. def save(self):
  28. fname = tkFileDialog.asksaveasfilename(title='Save As?')
  29. if fname != "":
  30. file = open(fname,'w')
  31. savetxt(file,self.sig_out.get().transpose(),delimiter=',')
  32. file.close()
  33. def test(master=None):
  34. o = App(master,FGSIN)
  35. o.master.title('FGSIN'); o.pack()
  36. o.component.trigger()
  37. if __name__ == '__main__':
  38. test(Tkinter.Tk())
  39. Tkinter.mainloop()

以下は2入力を積算するミキサーコンポーネントです。

  1. # coding: utf-8
  2. import Tkinter
  3. from scipy import array
  4. from PyLAF import EasyComponent, Embed, Port, Variable, Oscilloscope, Spectrum
  5. from FGSIN import FGSIN
  6. class MIXER(EasyComponent):
  7. PLOTTER = Oscilloscope
  8. def __init__(self,master=None):
  9. EasyComponent.__init__(self,master)
  10. self.sig_a = Port(Variable(array([]))).bind(self.trigger)
  11. self.sig_b = Port(Variable(array([]))).bind(self.trigger)
  12. def trigger(self):
  13. a, b = self.sig_a.get(), self.sig_b.get()
  14. if a.shape == b.shape:
  15. self.sig_out.set(self.sig_a.get() * self.sig_b.get())
  16. def test_embed(master=None):
  17. master.title('MODULATION:AM')
  18. frm = Tkinter.Frame(master); frm.pack(side=Tkinter.RIGHT)
  19. mx = Embed(frm,MIXER,text='MIXER:RF'); mx.pack(side=Tkinter.TOP)
  20. vw = Embed(frm,Spectrum,text='FGSIN:IF'); vw.pack(side=Tkinter.TOP)
  21. lo = Embed(master,FGSIN,text='FGSIN:LO'); lo.pack(side=Tkinter.RIGHT)
  22. im = Embed(master,FGSIN,text='FGSIN:IF'); im.pack(side=Tkinter.RIGHT)
  23. vw.xmin.set(0.); vw.xmax.set(.2)
  24. lo.freq.set(0.1)
  25. im.bias.set(1.0)
  26. lo.dt.link(im.dt)
  27. lo.tend.link(im.tend)
  28. lo.sig_out.link(mx.sig_a)
  29. im.sig_out.link(mx.sig_b)
  30. mx.sig_out.link(vw.sig_in)
  31. lo.component.trigger()
  32. if __name__ == '__main__':
  33. test_embed(Tkinter.Tk())
  34. Tkinter.mainloop()

典型的なワークセットの例

PyLAFでは簡単にコンポーネントを連携動作させるスクリプト(ワークセットと呼んでいます)を作成できます。 以下はFGSINとMIXERを使って作成したAM変調ワークセットの例です。 複数のコンポーネントがそれぞれ別々のトップレベルウィンドウを使って表示されます。

  1. # coding: utf-8
  2. import Tkinter
  3. from PyLAF import App
  4. from FGSIN import FGSIN
  5. from MIXER import MIXER
  6. master = Tkinter.Tk()
  7. mx = App(master,MIXER); mx.master.title('MIXER:RF'); mx.pack()
  8. lo = App(Tkinter.Toplevel(master),FGSIN); lo.master.title('FGSIN:LO'); lo.pack()
  9. im = App(Tkinter.Toplevel(master),FGSIN); im.master.title('FGSIN:IF'); im.pack()
  10. lo.freq.set(0.1)
  11. im.bias.set(1.0)
  12. lo.sig_out.link(mx.sig_a)
  13. im.sig_out.link(mx.sig_b)
  14. lo.dt.link(im.dt)
  15. lo.tend.link(im.tend)
  16. mx.component.trigger()
  17. Tkinter.mainloop()

ワークセットを単一のウィンドウにまとめたい場合、Embed(LabelFrame,Equipment)クラスを使ってコンポーネントを装置化します。

modam_set2.png

  1. # coding: utf-8
  2. import Tkinter
  3. from PyLAF import Embed
  4. from FGSIN import FGSIN
  5. from MIXER import MIXER
  6. master = Tkinter.Tk()
  7. master.title('MODULATION:AM')
  8. mx = Embed(master,MIXER,text='MIXER:RF'); mx.pack(side=Tkinter.RIGHT)
  9. lo = Embed(master,FGSIN,text='FGSIN:LO'); lo.pack(side=Tkinter.RIGHT)
  10. im = Embed(master,FGSIN,text='FGSIN:IF'); im.pack(side=Tkinter.RIGHT)
  11. im.bias.set(1.0)
  12. lo.freq.set(0.1)
  13. lo.dt.link(im.dt)
  14. lo.tend.link(im.tend)
  15. lo.sig_out.link(mx.sig_a)
  16. im.sig_out.link(mx.sig_b)
  17. mx.component.trigger()
  18. Tkinter.mainloop()

EmbedとAppは混在できます。スペクトルを見たい場合、トップレベルウィンドウに スペアナを作成し、mixer.sig_outにスペアナのsig_inを接続すれば連携動作します。

  1. # coding: utf-8
  2. import Tkinter
  3. from PyLAF import Embed, App, Spectrum
  4. from FGSIN import FGSIN
  5. from MIXER import MIXER
  6. master = Tkinter.Tk()
  7. master.title('MODULATION:AM')
  8. frm = Tkinter.Frame(master); frm.pack(side=Tkinter.RIGHT)
  9. mx = Embed(frm,MIXER,text='MIXER:RF'); mx.pack(side=Tkinter.TOP)
  10. lo = Embed(master,FGSIN,text='FGSIN:LO'); lo.pack(side=Tkinter.RIGHT)
  11. im = Embed(master,FGSIN,text='FGSIN:IF'); im.pack(side=Tkinter.RIGHT)
  12. im.bias.set(1.0)
  13. lo.freq.set(0.1)
  14. lo.dt.link(im.dt)
  15. lo.tend.link(im.tend)
  16. lo.sig_out.link(mx.sig_a)
  17. im.sig_out.link(mx.sig_b)
  18. vw = App(Tkinter.Toplevel(master),Spectrum); vw.master.title('Spectrum:RF'); vw.pack(side=Tkinter.TOP)
  19. mx.sig_out.link(vw.sig_in)
  20. mx.component.trigger()
  21. Tkinter.mainloop()

典型的な複合コンポーネントの例

サブコンポーネントを含んだ複合コンポーネントとしてまとめると、 他のコンポーネントと同じ様に利用することができます。 ワークセットを恒久的に使いたい場合などに使います。

  1. # coding: utf-8
  2. from PyLAF import *
  3. from MIXER import MIXER
  4. from FGSIN import FGSIN
  5. class MODAM(Component):
  6. def __init__(self,master=None):
  7. Component.__init__(self,master)
  8. self.fglo = fglo = FGSIN(self)
  9. self.fgif = fgif = FGSIN(self)
  10. self.mixer = mixer = MIXER(self)
  11. fglo.dt.link(fgif.dt)
  12. fglo.tend.link(fgif.tend)
  13. fglo.sig_out.link(mixer.sig_a)
  14. fgif.sig_out.link(mixer.sig_b)
  15. fgif.bias.set(1.0)
  16. fglo.freq.set(0.1)
  17. def gui(self,master,cnf={},**kw):
  18. frm = Frame(master)
  19. out = Tkinter.Frame(frm); out.pack(side=Tkinter.RIGHT)
  20. setattr(frm,'mixer',Embed(out,self.mixer,text='MIXER:RF')); frm.mixer.pack(side=Tkinter.TOP)
  21. setattr(frm,'spana',Embed(out,Spectrum,text='Spectrum:RF')); frm.spana.pack(side=Tkinter.TOP)
  22. setattr(frm,'fglo' ,Embed(frm,self.fglo,text='FGSIN:LO')); frm.fglo.pack(side=Tkinter.RIGHT)
  23. setattr(frm,'fgif' ,Embed(frm,self.fgif,text='FGSIN:IF')); frm.fgif.pack(side=Tkinter.RIGHT)
  24. self.mixer.sig_out.link(frm.spana.sig_in)
  25. self.fglo.trigger()
  26. self.fgif.trigger()
  27. return frm
  28. def test(master=None):
  29. master.title('MODULATION:AM')
  30. master.option_add('*font','FixedSys 10')
  31. o = App(master,MODAM); o.pack()
  32. o.gui.spana.gui.resize((200,200)) # o.gui.spana.gui.configure(figsize=(200,200))でもいい
  33. o.component.mixer.trigger()
  34. if __name__ == '__main__':
  35. test(Tkinter.Tk())
  36. Tkinter.mainloop()
  1. # coding: utf-8
  2. from PyLAF import *
  3. from MIXER import MIXER
  4. from FGSIN import FGSIN
  5. from functools import partial
  6. class MODAM(Component):
  7. def __init__(self,master=None):
  8. Component.__init__(self,master)
  9. self.fglo = fglo = FGSIN(self)
  10. self.fgif = fgif = FGSIN(self)
  11. self.mixer = mixer = MIXER(self)
  12. fglo.dt.link(fgif.dt)
  13. fglo.tend.link(fgif.tend)
  14. fglo.sig_out.link(mixer.sig_a)
  15. fgif.sig_out.link(mixer.sig_b)
  16. fgif.bias.set(1.0)
  17. fglo.freq.set(0.1)
  18. self._menu = [['Sub', ['FGLO', partial(self.popup,master=master,comp=self.fglo)],
  19. ['SPANA', partial(self.popup_spana,master=master)]]]
  20. def gui(self,master,cnf={},**kw):
  21. frm = Frame(master)
  22. setattr(frm,'mixer',Embed(frm,self.mixer,text='MIXER:RF')); frm.mixer.pack(side=Tkinter.RIGHT)
  23. setattr(frm,'fgif' ,Embed(frm,self.fgif,text='FGSIN:IF')); frm.fgif.pack(side=Tkinter.RIGHT)
  24. self.fgif.trigger()
  25. return frm
  26. def guib(self,master,cnf={},**kw):
  27. frm = Frame(master)
  28. setattr(frm,'mixer',Embed(frm,self.mixer,text='MIXER:RF')); frm.mixer.pack(side=Tkinter.RIGHT)
  29. setattr(frm,'fgif' ,Embed(frm,self.fgif,text='FGSIN:IF')); frm.fgif.pack(side=Tkinter.RIGHT)
  30. setattr(frm,'fglo' ,Embed(frm,self.fglo,text='FGSIN:LO')); frm.fglo.pack(side=Tkinter.RIGHT)
  31. self.fgif.trigger()
  32. self.fglo.trigger()
  33. return frm
  34. def menu(self,master,cnf={},**kw):
  35. menu = EasyMenu(master,list=self._menu,cnf=cnf,**kw)
  36. return menu
  37. def popup(self,master,comp):
  38. App(Tkinter.Toplevel(master),comp).pack()
  39. comp.trigger()
  40. def popup_spana(self,master):
  41. o = App(Tkinter.Toplevel(master),Spectrum); o.pack()
  42. self.mixer.sig_out.link(o.component.sig_in)
  43. self.mixer.sig_out.set(self.mixer.sig_out.get())
  44. def test(master=None):
  45. master.title('MODULATION:AM')
  46. o = App(master,MODAM,gui=False); o.pack()
  47. o.configure(gui=o.component.guib)
  48. if __name__ == '__main__':
  49. test(Tkinter.Tk())
  50. Tkinter.mainloop()
  1. # coding: utf-8
  2. from PyLAF import *
  3. from MIXER import MIXER
  4. from FGSIN import FGSIN
  5. from functools import partial
  6. class MODAM(Component):
  7. def __init__(self,master=None):
  8. Component.__init__(self,master)
  9. self.fglo = fglo = FGSIN(self)
  10. self.fgif = fgif = FGSIN(self)
  11. self.mixer = mixer = MIXER(self)
  12. fglo.dt.link(fgif.dt)
  13. fglo.tend.link(fgif.tend)
  14. fglo.sig_out.link(mixer.sig_a)
  15. fgif.sig_out.link(mixer.sig_b)
  16. fgif.bias.set(1.0)
  17. fglo.freq.set(0.1)
  18. self._menu = [['Sub', ['FGLO', partial(self.popup,master=master,comp=self.fglo)],
  19. ['SPANA', partial(self.popup_spana,master=master)]]]
  20. def gui(self,master,cnf={},**kw):
  21. frm = Frame(master)
  22. setattr(frm,'mixer',Embed(frm,self.mixer,text='MIXER:RF')); frm.mixer.pack(side=Tkinter.RIGHT)
  23. setattr(frm,'fgif' ,Embed(frm,self.fgif,text='FGSIN:IF')); frm.fgif.pack(side=Tkinter.RIGHT)
  24. self.fgif.trigger()
  25. return frm
  26. def menu(self,master,cnf={},**kw):
  27. menu = EasyMenu(master,list=self._menu,cnf=cnf,**kw)
  28. return menu
  29. def popup(self,master,comp):
  30. App(Tkinter.Toplevel(master),comp).pack()
  31. comp.trigger()
  32. def popup_spana(self,master):
  33. o = App(Tkinter.Toplevel(master),Spectrum); o.pack()
  34. self.mixer.sig_out.link(o.component.sig_in)
  35. self.mixer.sig_out.set(self.mixer.sig_out.get())
  36. def test(master=None):
  37. master.title('MODULATION:AM')
  38. o = App(master,MODAM); o.pack()
  39. if __name__ == '__main__':
  40. test(Tkinter.Tk())
  41. Tkinter.mainloop()