easyret_gui 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/usr/bin/env python
  2. import os
  3. import wx
  4. import wx.lib.filebrowsebutton as libtest
  5. import wx.lib.agw.floatspin as FS
  6. from os.path import join as opj
  7. MAIN_WINDOW_DEFAULT_SIZE = (650,700)
  8. class Frame(wx.Frame):
  9. def __init__(self, parent, id, title):
  10. style=wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER) # XOR to remove the resizeable border
  11. wx.Frame.__init__(self, parent, id, title=title, size=MAIN_WINDOW_DEFAULT_SIZE, style=style)
  12. self.Center() # open in the centre of the screen
  13. self.panel = wx.Panel(self)
  14. self.subject_id_label = wx.StaticText(self.panel, pos=(50, 45), size=(140,-1), label="Enter Subject ID:")
  15. self.subject_id = wx.TextCtrl(self.panel, pos=(200, 40), size=(60,-1))
  16. self.contract = libtest.FileBrowseButton(self.panel, pos=(50, 80), initialValue='Enter path to Contracting volume', toolTip='Enter/Browse path to Contracting volume', fileMask='*.nii.gz', size=(500,30), labelWidth=100)
  17. self.expand = libtest.FileBrowseButton(self.panel, pos=(50, 120), initialValue='Enter path to Expanding volume', toolTip='Enter/Browse path to Expanding volume', fileMask='*.nii.gz', size=(500,30), labelWidth=100)
  18. self.clock = libtest.FileBrowseButton(self.panel, pos=(50, 160), initialValue='Enter path to Clockwise volume', toolTip='Enter/Browse path to Clockwise volume', fileMask='*.nii.gz', size=(500,30), labelWidth=100)
  19. self.counter = libtest.FileBrowseButton(self.panel, labelWidth=10, pos=(50, 200), initialValue='Enter path to Counter clockwise volume', toolTip='Enter/Browse path to Counter clockwise volume', fileMask='*.nii.gz', size=(500,30))
  20. self.mask = libtest.FileBrowseButton(self.panel, labelWidth=10, pos=(50, 240), initialValue='Enter path to mask', toolTip='Enter/Browse path to brain mask of the retmapping volumes', fileMask='*.nii.gz', size=(350,30))
  21. self.FWHM_label = wx.StaticText(self.panel, pos=(50, 285), size=(250,-1), label="Spatial Smoothing FWHM (mm):")
  22. self.FWHM = FS.FloatSpin(self.panel, value='4', pos=(300, 280), size=(45, -1), min_val=0, max_val=10, increment=1)
  23. self.FWHM.SetDigits(0)
  24. self.output_folder_label = wx.StaticText(self.panel, pos=(50, 325), size=(250,-1), label="Select output folder:")
  25. self.output = wx.DirPickerCtrl(self.panel, pos=(250, 320))
  26. self.postprocessingshift = wx.CheckBox(self.panel, -1, 'Post Processing Shift', pos=(50, 385))
  27. self.Bind(wx.EVT_CHECKBOX, self.OnPostProcessShift, self.postprocessingshift)
  28. self.surfacemaps = wx.CheckBox(self.panel, -1, 'Surface Maps', pos=(50, 415))
  29. self.Bind(wx.EVT_CHECKBOX, self.OnSurfaceMaps, self.surfacemaps)
  30. self.debugmode = wx.CheckBox(self.panel, -1, 'Debug Mode', pos=(50, 580))
  31. self.process_button = wx.Button(self.panel, pos=(470, 580), size=(80, 25), label="EasyRet")
  32. self.Bind(wx.EVT_BUTTON, self.OnProcess, self.process_button)
  33. self.CreateMenuBar()
  34. self.CreateStatusBar()
  35. def CreateMenuBar(self):
  36. menuBar = wx.MenuBar()
  37. # Tell our Frame about this MenuBar
  38. self.SetMenuBar(menuBar)
  39. menuFile = wx.Menu()
  40. # NOTE on wx ids - they're used everywhere, we don't care about them
  41. # Used to handle events and other things
  42. # An id can be -1 or wx.ID_ANY, wx.NewId(), your own id
  43. # Get the id using object.GetId()
  44. # add a Help menu with an About item
  45. menuHelp = wx.Menu()
  46. menuBar.Append(menuHelp, '&Help')
  47. helpMenuItem = menuHelp.Append(-1, '&About', 'About EasyRet')
  48. self.Bind(wx.EVT_MENU, self.OnAbout, helpMenuItem)
  49. # create a menu item for Exit and bind it to the OnExit function
  50. exitMenuItem = menuHelp.Append(-1, '&Exit', 'Exit EasyRet')
  51. self.Bind(wx.EVT_MENU, self.OnExit, exitMenuItem)
  52. def OnAbout(self,e):
  53. # A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
  54. help_text='I am working on it\n please bear with me'
  55. dlg = wx.MessageDialog( self, help_text, "About EasyRet", wx.OK)
  56. dlg.ShowModal() # Show it
  57. dlg.Destroy() # finally destroy it when finished.
  58. def OnPostProcessShift(self, event):
  59. if self.postprocessingshift.GetValue():
  60. self.con_shift_text = wx.StaticText(self.panel, pos=(250, 360), size=(200,-1), label="Con")
  61. self.con_shift = FS.FloatSpin(self.panel, value='22.5', pos=(250, 380), size=(70, -1), min_val=-360, max_val=360, increment=0.25)
  62. self.con_shift.SetDigits(2)
  63. self.exp_shift_text = wx.StaticText(self.panel, pos=(320, 360), size=(200,-1), label="Exp")
  64. self.exp_shift = FS.FloatSpin(self.panel, value='22.5', pos=(320, 380), size=(70, -1), min_val=-360, max_val=360, increment=0.25)
  65. self.exp_shift.SetDigits(2)
  66. self.clw_shift_text = wx.StaticText(self.panel, pos=(390, 360), size=(200,-1), label="Clw")
  67. self.clw_shift = FS.FloatSpin(self.panel, value='22.5', pos=(390, 380), size=(70, -1), min_val=-360, max_val=360, increment=0.25)
  68. self.clw_shift.SetDigits(2)
  69. self.ccw_shift_text = wx.StaticText(self.panel, pos=(460, 360), size=(200,-1), label="Ccw")
  70. self.ccw_shift = FS.FloatSpin(self.panel, value='22.5', pos=(460, 380), size=(70, -1), min_val=-360, max_val=360, increment=0.25)
  71. self.ccw_shift.SetDigits(2)
  72. else:
  73. self.con_shift.Destroy()
  74. self.con_shift_text.Destroy()
  75. self.exp_shift.Destroy()
  76. self.exp_shift_text.Destroy()
  77. self.clw_shift.Destroy()
  78. self.clw_shift_text.Destroy()
  79. self.ccw_shift.Destroy()
  80. self.ccw_shift_text.Destroy()
  81. def OnSurfaceMaps(self, event):
  82. if self.surfacemaps.GetValue():
  83. self.anatomy = libtest.FileBrowseButton(self.panel, labelWidth=10, pos=(150, 450), initialValue='Enter path to anatomy', toolTip='Enter/Browse path to the anatomical volume that was used for Freesurfer recon-all analysis', fileMask='*.nii.gz', size=(400,30))
  84. self.transformation = libtest.FileBrowseButton(self.panel, labelWidth=10, pos=(150, 490), initialValue='Enter transformation matrix', toolTip='Enter/Browse path to the fsl type transformation file for co-registering BOLD retmapping volumes to anatomical volumes', fileMask='*.mat', size=(400,30))
  85. self.ROI = libtest.FileBrowseButton(self.panel, labelWidth=10, pos=(150, 530), initialValue='Enter path to ROI mask', fileMask='*.nii.gz', toolTip='Enter/Browse path to the ROI mask if you want your surface maps to be restricted to Occipital lobe only', size=(400,30))
  86. else:
  87. self.anatomy.Destroy()
  88. self.transformation.Destroy()
  89. self.ROI.Destroy()
  90. def OnProcess(self, event):
  91. from subprocess import PIPE, CalledProcessError, check_call, Popen
  92. bash_processing_script=opj(os.path.dirname(os.path.realpath(__file__)), 'process_retmap')
  93. subject_id = str(self.subject_id.GetValue())
  94. contract_volume = str(self.contract.GetValue())
  95. expand_volume = str(self.expand.GetValue())
  96. clock_volume = str(self.clock.GetValue())
  97. counter_volume = str(self.counter.GetValue())
  98. mask = str(self.mask.GetValue())
  99. FWHM = str(self.FWHM.GetValue())
  100. output_folder = str(self.output.GetPath())
  101. contract_shift=expand_shift=clock_shift=counter_shift=anatomy_volume=transformation_matrix=ROI=''
  102. post_processing_shift=str(self.postprocessingshift.GetValue())
  103. if self.postprocessingshift.GetValue():
  104. contract_shift=str(self.con_shift.GetValue())
  105. expand_shift=str(self.exp_shift.GetValue())
  106. clock_shift=str(self.clw_shift.GetValue())
  107. counter_shift=str(self.ccw_shift.GetValue())
  108. surface_maps=str(self.surfacemaps.GetValue())
  109. if self.surfacemaps.GetValue():
  110. anatomy_volume=str(self.anatomy.GetValue())
  111. transformation_matrix=str(self.transformation.GetValue())
  112. ROI=str(self.ROI.GetValue())
  113. debug_mode=str(self.debugmode.GetValue())
  114. error_log=opj(output_folder, subject_id+'_error.log')
  115. #scripts/pyretmap/code/processing_pipeline/process_retmap sub-16 /home/data/psyinf/forrest_gump/anondata/sub016/BOLD/task005_run001/bold_bold3Tp2_to_subjbold3Tp2.nii.gz /home/data/psyinf/forrest_gump/anondata/sub016/BOLD/task005_run003/bold_bold3Tp2_to_subjbold3Tp2.nii.gz /home/data/psyinf/forrest_gump/anondata/sub016/BOLD/task005_run004/bold_bold3Tp2_to_subjbold3Tp2.nii.gz /home/data/psyinf/forrest_gump/anondata/sub016/BOLD/task005_run002/bold_bold3Tp2_to_subjbold3Tp2.nii.gz /home/data/psyinf/forrest_gump/anondata/sub016/templates/bold3Tp2/brain_mask.nii.gz /home/data/exppsy/spark/Study_Forrest checked -337.5 0.0 101.25 -281.25 checked /home/data/psyinf/forrest_gump/anondata/sub016/templates/t1w/head.nii.gz /home/data/psyinf/forrest_gump/anondata/sub016/templates/bold3Tp2/in_t1w/xfm_6dof.mat ''
  116. arguments_list=[bash_processing_script, subject_id, contract_volume, expand_volume, clock_volume, counter_volume, mask, FWHM, output_folder, post_processing_shift, contract_shift, expand_shift, clock_shift, counter_shift, surface_maps, anatomy_volume, transformation_matrix, ROI, debug_mode]
  117. print '\n\n'
  118. print ' '.join(arguments_list)
  119. print '\n\n'
  120. print 'Processing Retmap'
  121. with open(error_log, "w") as f:
  122. try:
  123. check_call(arguments_list, stderr=f)
  124. except CalledProcessError as e:
  125. print(e)
  126. exit(1)
  127. print 'Done'
  128. def OnExit(self, event):
  129. "Close the application by Destroying the object"
  130. # TRY add in your own print call here
  131. self.Destroy() # SHOW HELP SIDEBAR
  132. class App(wx.App):
  133. def OnInit(self):
  134. self.frame = Frame(parent=None, id=-1, title='EasyRet')
  135. self.frame.Show()
  136. self.SetTopWindow(self.frame)
  137. return True
  138. if __name__ == "__main__":
  139. # make an App object, set stdout to the console so we can see errors
  140. app = App(redirect=False)
  141. app.MainLoop()