Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
77f79ee
WIP: Add multiple simultaneous views
larsoner Mar 16, 2013
2a917bb
FIX: Cleanup
larsoner Mar 16, 2013
41f3917
STY: Fewer pyflakes warnings
larsoner Mar 16, 2013
eb82e49
ENH: Adding toolbar hiding
larsoner Mar 18, 2013
4f72e26
WIP: Refactoring
larsoner Mar 18, 2013
eed8b45
ENH: Tests pass
larsoner Mar 19, 2013
b1b1105
ENH: Adding example
larsoner Mar 19, 2013
b631626
ENH: Adding hemi="both" support, logging/verbose, cleanups
larsoner Mar 20, 2013
b446b2b
WIP: Refactor to split data loading and display
larsoner Mar 20, 2013
0aa7d59
STY: Minor cleanup
larsoner Mar 20, 2013
43290f3
WIP: Refactoring more
larsoner Mar 21, 2013
418c9d1
ENH: Refactored
larsoner Mar 22, 2013
07eb576
ENH: Dealing with Mayavi plotting bugs
larsoner Mar 22, 2013
6e69eca
FIX: Multiple fixes
larsoner Mar 25, 2013
02d2dc2
FIX: Fixing after rebase
larsoner Jul 23, 2013
b288c8d
FIX: Multiple fixes, toolbar toggling, docstring
larsoner Aug 2, 2013
6c54bd1
FIX: View skew (focal point) error, config doc
larsoner Aug 2, 2013
64ab812
ENH: Example including both hemispheres
larsoner Aug 2, 2013
0129278
STY: Adding better doc for save_image, screenshot
larsoner Aug 2, 2013
afe9c86
ENH: Add auto parc and annot parsing
larsoner Aug 2, 2013
56d6a68
FIX: Fixing docs
larsoner Aug 2, 2013
498414c
FIX: Fixing docs
larsoner Aug 2, 2013
85f04c5
FIX: Close each global brain in doc gen
larsoner Aug 2, 2013
bbece3d
FIX: Fix command-line tool, add placeholder for tutorial
larsoner Aug 11, 2013
e8483f0
STY: Better doc
larsoner Aug 11, 2013
308eef4
ENH: Add image, clarify doc
larsoner Aug 11, 2013
51f986d
FIX: Cleaner arg parsing
larsoner Aug 12, 2013
da9a7c3
STY: Cleaner
larsoner Aug 12, 2013
5fad8c9
STY: Fixing changes
larsoner Aug 12, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
PySurfer Changes
================

Version 0.4
-------------

Enhancements
~~~~~~~~~~~~

- Display data from both hemispheres simultaneously
- Display multiple views simultaneously
- Toggling Mayavi toolbars
- Use nibabel for IO functions

Version 0.3.1
-------------

Expand Down
17 changes: 12 additions & 5 deletions bin/pysurfer
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ if __name__ == '__main__':
# boot up mlab/IPython
if len(sys.argv) > 3:
subjects_dir = os.environ['SUBJECTS_DIR']
surf_file = os.path.join(subjects_dir,
"%s/surf/%s.%s" % tuple(sys.argv[1:4]))
if not os.path.exists(surf_file):
sys.exit("ERROR: Could not find %s" % surf_file)
if sys.argv[2] in ['both', 'split']:
hemi_checks = ['lh', 'rh']
else:
hemi_checks = [sys.argv[2]]
for h in hemi_checks:
surf_file = os.path.join(subjects_dir,
"%s/surf/%s.%s" % (sys.argv[1], h,
sys.argv[3]))
if not os.path.exists(surf_file):
sys.exit("ERROR: Could not find %s" % surf_file)

if not is_ipython:
# Parse the args so that --help exits back to the shell
Expand Down Expand Up @@ -62,10 +68,11 @@ if __name__ == '__main__':
argdict = args.__dict__
config_opts = dict([(k, v) for k, v in argdict.items()
if k in confkeys and v])
views = args.views

# Load up the figure and underlying brain object
b = Brain(args.subject_id, args.hemi, args.surf, args.curv,
args.title, config_opts=config_opts)
args.title, views=views, config_opts=config_opts)

# Maybe load some morphometry
if args.morphometry is not None:
Expand Down
Binary file added doc/_static/split_view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@

# General information about the project.
project = u'PySurfer'
copyright = u'2011-2012, Michael Waskom, Alexandre Gramfort, Scott Burns, Martin Luessi'
copyright = (u'2011-2013, Michael Waskom, Alexandre Gramfort, Scott Burns, '
'Martin Luessi, Eric Larson')

# Generate the plots for the gallery
plot_gallery = True
Expand Down Expand Up @@ -222,5 +223,5 @@
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'pysurfer', u'PySurfer Documentation',
[u'Michael Waskom, Alexandre Gramfort, Scott Burns'], 1)
[u'Michael Waskom, Alexandre Gramfort, Scott Burns, Eric Larson'], 1)
]
18 changes: 14 additions & 4 deletions doc/documentation/config_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ There are several aspects of how PySurfer looks and behaves that you may
wish to customize but do not want to have to alter every time you
instantiate a Brain object or use the command-line interface. To
facilitate this, PySurfer allows you to set certain options with a
standard Python config file.
standard Python config file.

When a new Brain object is created (either in a script or via the
command-line), it can read configuration options from one of two places:
Expand All @@ -27,9 +27,14 @@ Visual

*size*
How large the sides of the display window should be (measured in
pixels.) The window is always square, so just give one value, and
it will be used for the height and width. (Possible values: any
positive number.)
pixels.) When using this option, the window will be square, and
"size" it will be used for the height and width. (Possible values:
any positive number.)

*width* and *height*
The size of the window. This is an alternative to size, allowing
the width and height to be set independently. (Possible values:
any positive number.)

*default_view*
Which view should be shown at the beginning of a visualization
Expand All @@ -49,3 +54,8 @@ Overlay
provided when calling the :meth:`Brain.add_overlay` method.
(Possible values: any float, ``robust_max``, ``actual_max``.)

Options
-------
*logging_level*
Amount of verbosity to use in outputting status messages.
(Possible values: ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``.)
1 change: 1 addition & 0 deletions doc/documentation/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ Documentation

./command_line
./custom_viz
./split_brain
./config_file

48 changes: 48 additions & 0 deletions doc/documentation/split_brain.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.. _split_brain:

Working with a split-screen brain
=================================

The split-screen view can be activated by using the argument ``hemi='split'``.
Using this option will put views of the left hemisphere in consecutive
vertical frames on the left, and views of the right hemisphere in
consecutive vertical frames on the right. For example, running the following::

brain = Brain('fsaverage', 'split', 'inflated', views=['lat', 'med'])

Will produce a window with two columns (hemispheres) and two rows (the
lateral and medial views, respectively), shown below.

.. image:: ../../_static/split_view.png

Adding and displaying data
--------------------------

Data can be added to either hemisphere using the same functions that are
normally used, e.g. ``add_data``, ``add_overlay``, ``add_morphometry``.
The objects are automatically shown on all views of the brain. When
calling these functions, the ``hemi`` keyword argument can be set to
``hemi='lh'`` or ``hemi='rh'`` to specify the hemisphere to plot to.
In some instances (e.g., ``add_morphometry``), if no keyword argument
is provided, PySurfer will attempt to load data or both hemispheres
automtically.

Note that the ``show_view`` method accepts arguments for the ``row`` and
``col`` values, which allow the user to control which ``Brain`` panel
gets the updated view.

Caveats
-------
The multi-view support is available thanks to the capabilities of the
TraitsUI framework. However, due to some limitations in the implementation
of TraitsUI, there is no guarantee that a set of scripted commands will
result in a painted window when the user may think it will. For
example, making a series of calls to ``brain.add_label()`` followed by
``brain.save_image('out.png')`` may result in some or all of the labels
being absent from the saved ``out.png``. While we have implemented some
workarounds to help prevent this occurrance, we cannot guarantee it will
work. Thus we recommend that for critical non-interactive plotting (e.g.,
if scripting figure generation for a paper) only a single view is used
with ``hemi`` set to ``'lh'``, ``'rh'``, or ``'both'``. This will use a single,
pure Mayavi window, thereby bypassing TraisUI entirely -- this helps
guarantee that drawing commands result in updated visual display.
6 changes: 4 additions & 2 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ MRI and MEG data.

PySurfer offers both a command-line interface designed to broadly
replicate Freesurfer's Tksurfer program as well as a Python library
for writing scripts to efficiently explore complex datasets.
for writing scripts to efficiently explore complex datasets.

Contents
--------

.. toctree::
:maxdepth: 2

install
examples/index.rst
documentation/index.rst
Expand All @@ -33,6 +33,8 @@ Scott Burns, Harvard Med. School MGH Martinos Center

Martin Luessi, Harvard Med. School MGH Martinos Center

Eric Larson, University of Washington ILABS

License
-------

Expand Down
51 changes: 18 additions & 33 deletions doc/sphinxext/gen_rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,66 +148,51 @@ def generate_file_rst(fname, target_dir, src_dir, plot_gallery):
this_template = rst_template
last_dir = os.path.split(src_dir)[-1]
# to avoid leading . in file names
if last_dir == '.': last_dir = ''
else: last_dir += '_'
short_fname = last_dir + fname
if last_dir == '.':
last_dir = ''
else:
last_dir += '_'
short_fname = last_dir + fname
src_file = os.path.join(src_dir, fname)
example_file = os.path.join(target_dir, fname)
shutil.copyfile(src_file, example_file)
if plot_gallery and fname.startswith('plot'):
# generate the plot as png image if file name
# starts with plot and if it is more recent than an
# existing image.
if not os.path.exists(
os.path.join(target_dir, 'images')):
if not os.path.exists(os.path.join(target_dir, 'images')):
os.makedirs(os.path.join(target_dir, 'images'))
image_file = os.path.join(target_dir, 'images', image_name)
if (not os.path.exists(image_file) or
os.stat(image_file).st_mtime <=
os.stat(src_file).st_mtime):
os.stat(image_file).st_mtime <= os.stat(src_file).st_mtime):
print 'plotting %s' % fname
import matplotlib.pyplot as plt
plt.close('all')
try:
try:
from mayavi import mlab
except ImportError:
from enthought.mayavi import mlab
mlab.close(all=True)
except:
pass

try:
execfile(example_file, {'pl' : plt})
facecolor = plt.gcf().get_facecolor() # hack to keep black bg
brain = None
global plt
global brain
execfile(example_file, globals())
facecolor = plt.gcf().get_facecolor() # hack to keep black bg
if facecolor == (0.0, 0.0, 0.0, 1.0):
plt.savefig(image_file, facecolor='black')
else:
plt.savefig(image_file)

try:
try:
from mayavi import mlab
except ImportError:
from enthought.mayavi import mlab

e = mlab.get_engine()
if len(e.scenes) > 0:
mlab.savefig(image_file, size=(400, 400))
except:
pass
brain.save_image(image_file)
brain.close()

except:
print 80*'_'
print 80 * '_'
print '%s is not compiling:' % fname
traceback.print_exc()
print 80*'_'
print 80 * '_'
this_template = plot_rst_template

docstring, short_desc, end_row = extract_docstring(example_file)

f = open(os.path.join(target_dir, fname[:-2] + 'rst'),'w')
f.write( this_template % locals())
f = open(os.path.join(target_dir, fname[:-2] + 'rst'), 'w')
f.write(this_template % locals())
f.flush()


Expand Down
2 changes: 2 additions & 0 deletions doc/surfer.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[visual]
width=600
height=600
background=black
cortex=classic
default_view=lateral
Empty file removed examples/example_data/index.rst
Empty file.
Binary file added examples/example_data/meg_source_estimate-rh.stc
Binary file not shown.
18 changes: 12 additions & 6 deletions examples/plot_from_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,37 @@
from surfer import Brain, io

"""Bring up the visualization"""
brain = Brain("fsaverage", "lh", "inflated",
brain = Brain("fsaverage", "split", "inflated", views=['lat', 'med'],
config_opts=dict(background="white"))

"""Project the volume file and return as an array"""
mri_file = "example_data/resting_corr.nii.gz"
reg_file = "example_data/register.dat"
surf_data = io.project_volume_data(mri_file, "lh", reg_file)
surf_data_lh = io.project_volume_data(mri_file, "lh", reg_file)
surf_data_rh = io.project_volume_data(mri_file, "rh", reg_file)

"""
You can pass this array to the add_overlay method for
a typical activation overlay (with thresholding, etc.)
"""
brain.add_overlay(surf_data, min=.3, max=.7, name="ang_corr")
brain.add_overlay(surf_data_lh, min=.3, max=.7, name="ang_corr_lh", hemi='lh')
brain.add_overlay(surf_data_rh, min=.3, max=.7, name="ang_corr_rh", hemi='rh')

"""
You can also pass it to add_data for more control
over the visualzation. Here we'll plot the whole
range of correlations
"""
brain.overlays["ang_corr"].remove()
brain.add_data(surf_data, -.7, .7, colormap="jet", alpha=.7)
for overlay in brain.overlays_dict["ang_corr_lh"]:
overlay.remove()
for overlay in brain.overlays_dict["ang_corr_rh"]:
overlay.remove()
brain.add_data(surf_data_lh, -.7, .7, colormap="jet", alpha=.7, hemi='lh')
brain.add_data(surf_data_rh, -.7, .7, colormap="jet", alpha=.7, hemi='rh')

"""
This overlay represents resting-state correlations with a
seed in left angular gyrus. Let's plot that seed.
"""
seed_coords = (-45, -67, 36)
brain.add_foci(seed_coords, map_surface="white")
brain.add_foci(seed_coords, map_surface="white", hemi='lh')
Loading