nipy / PySurfer

Cortical neuroimaging visualization in Python
https://pysurfer.github.io/
BSD 3-Clause "New" or "Revised" License
240 stars 97 forks source link

System-dependent handling of saturated data values #188

Closed mwaskom closed 7 years ago

mwaskom commented 7 years ago

I am getting pysurfer set up on our new Ubuntu system and have discovered something unusual. Values that are plotted with Brain.add_data are transparent when they are below the min or above the max values. i.e. they are being treated as if they are below the threshold, even when I am not using a threshold. This behavior does not occur on my OSX system, using github master on both machines. It also does not occur when using Brain.add_overlay.

The behavior can be reproduced using the examples/plot_resting_correlations.py script. Values around the "seed" focus are clipped/transparent in the final plot (but not in the intermediate plot created with add_overlay).

Can anyone else reproduce this? Does anyone have any ideas what the issue is?

larsoner commented 7 years ago

Can you make a minimal example? I can it. But I haven't noticed this behavior so far (but maybe my install is not so up-to-date).

mwaskom commented 7 years ago

The problem is nicely demonstrated by the examples/plot_resting_correlations.py script we ship. I will add a screenshot if I figure out how to make on in ubuntu :). I don't think the problem is recent, as I had 0.6 installed on this system at first and saw it there too.

larsoner commented 7 years ago

Printscreen for the while screen or alt printscreen for the window

larsoner commented 7 years ago

Mine looks okay:

screenshot from 2017-04-24 09-48-00

And just to be safe I downloaded Anaconda2-4.3.1-Linux-x86_64.sh, and (after installing it) did:

sed -i "s/ENABLE_USER_SITE = .*/ENABLE_USER_SITE = False/g" ~/anaconda2/lib/python2.7/site.py
python setup.py develop  # for PySurfer
cd examples
python -i plot_resting_correlations.py

And got the same result.

What GPU are you using? I wonder if there is some bug in your drivers and/or their interaction with VTK (which does the drawing at the lowest level).

mwaskom commented 7 years ago

Here's what I see:

screenshot from 2017-04-24 10-02-30

Here's the output of lshw -c video

  *-display
       description: VGA compatible controller
       product: GK208 [GeForce GT 730]
       vendor: NVIDIA Corporation
       physical id: 0
       bus info: pci@0000:81:00.0
       version: a1
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress vga_controller bus_master cap_list rom
       configuration: driver=nvidia latency=0
       resources: irq:143 memory:fa000000-faffffff memory:f0000000-f7ffffff memory:f8000000-f9ffffff ioport:f000(size=128) memory:fb000000-fb07ffff
larsoner commented 7 years ago

Yikes.

Okay we're both running NVIDIA so that's not a likely culprit. But just to be safe, which drivers are you on? I'm on 375.79 (Ubuntu 16.04.2 latest repo version).

Did you do the site.py modification to ensure it's actually using Anaconda and not system mayavi?

mwaskom commented 7 years ago

I am using the 378.13 driver. I'd prefer not to muck with that, as just getting the graphics card working set off a chain of problem that took the system down for days.

Here's some other version information:


[kianilab-cs1 pysurfer]{master}$ conda list vtk
# packages in environment at /home/mwaskom/anaconda2:
#
vtk                       7.1.0                    py27_2    conda-forge
[kianilab-cs1 pysurfer]{master}$ conda list mayavi
# packages in environment at /home/mwaskom/anaconda2:
#
mayavi                    4.5.0               np111py27_1    conda-forge
[kianilab-cs1 pysurfer]{master}$ conda list pysurfer
# packages in environment at /home/mwaskom/anaconda2:
#
pysurfer                  0.6                       <pip>
[kianilab-cs1 pysurfer]{master}$ ipython
import Python 2.7.12 |Anaconda custom (64-bit)| (default, Jul  2 2016, 17:42:40) 
Type "copyright", "credits" or "license" for more information.

IPython 5.2.2 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import mayavi

In [2]: mayavi.__path__
Out[2]: ['/home/mwaskom/anaconda2/lib/python2.7/site-packages/mayavi']

I don't think I have mayavi installed in the system python packages:

[kianilab-cs1 pysurfer]{master}$ /usr/bin/python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mayavi
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named mayavi
larsoner commented 7 years ago

I don't think I have mayavi installed in the system python packages:

It's still a good idea IMO to turn off access in site.py so it doesn't inadvertently use anything outside the Anaconda install, but YMMV.

I am using the 378.13 driver. I'd prefer not to muck with that, as just getting the graphics card working set off a chain of problem that took the system down for days.

Unfortunately this could be the source of error, and the only lead I can think of currently. So if you want to dig further it's probably worthwhile.

Is this the Ubuntu repo version, or one from the NVIDIA website? If it's from the website, did you try the Ubuntu repo version? I usually find the repo versions require less maintenance than the website versions.

mwaskom commented 7 years ago

Here is a failure to reproduce in a very simple script that uses mayavi directly:

from mayavi import mlab
from nibabel.freesurfer import read_geometry

verts, faces = read_geometry("/usr/local/freesurfer/current/subjects/fsaverage/surf/lh.inflated")

f = mlab.figure()
mesh = mlab.pipeline.triangular_mesh_source(*verts.T, triangles=faces, scalars=verts[:, 1])
surf = mlab.pipeline.surface(mesh, vmin=-50, vmax=50, colormap="Spectral")

image

mwaskom commented 7 years ago

It's still a good idea IMO to turn off access in site.py so it doesn't inadvertently use anything outside the Anaconda install, but YMMV.

I hadn't heard about this, but enabling your edits doesn't change anything.

mwaskom commented 7 years ago

Ah, a successful lobectomy:

import numpy as np
from mayavi import mlab
from nibabel.freesurfer import read_geometry
import matplotlib as mpl

verts, faces = read_geometry("/usr/local/freesurfer/current/subjects/fsaverage/surf/lh.inflated")

f = mlab.figure()
mesh = mlab.pipeline.triangular_mesh_source(*verts.T, triangles=faces, scalars=verts[:, 1])
surf = mlab.pipeline.surface(mesh, vmin=-100, vmax=50, colormap="Spectral")

lut = mpl.cm.BrBG(np.linspace(0, 1, 256)) * 255
surf.module_manager.scalar_lut_manager.lut.table = lut

image

larsoner commented 7 years ago

Nice. That can be pretty easily modified to be just a few lines requiring no nibabel, etc.

So you could try to open an issue with Mayavi. But I doubt that it's their problem because it works over here and they don't interface with the graphics directly.

The best thing would be to try to us vtkpython directly to see if you can reproduce the problem, but this would probably take some work.

Eventually my guess is that it will be a VTK / graphics-driver problem, so possible the VTK folks can fix it. But that will take quite some time to trickle back down :(

mwaskom commented 7 years ago

My current thinking is that it is a problem with the (data)type of the lut object we are setting. i.e. if you interrogate the scalar lut in the original (working) example

lut = surf.module_manager.scalar_lut_manager.lut.table
type(lut)

it is not a numpy array but a tvtk.tvtk_classes.unsigned_char_array.UnsignedCharArray

I need to track down how to initialize one of those, but my hope is that it will solve the problem. I am also crossing my fingers that it will solve #83.

larsoner commented 7 years ago

My current thinking is that it is a problem with the (data)type of the lut object we are setting

That would be great. Even if it's possible we can work around the issue by changing this, though, the fact that it works on my system but not yours means there is a problem in an upstream package somewhere between the VTK type checking/setting (Mayavi vars) and execution of the compiled GPU code (NVIDIA drivers). But if we can fix it ourselves that's already a big help.

mwaskom commented 7 years ago

Hey, progress. Based on https://github.com/enthought/mayavi/issues/280 I tried

lut = mpl.cm.BrBG(np.linspace(0, 1, 256))
surf.module_manager.scalar_lut_manager.load_lut_from_list(lut)

and it seems to work:

image

I'll do some more testing for robustness and if everything looks good to a pysurfer PR. I'm not sure what to conclude about the upstream issues.

larsoner commented 7 years ago

I'm not sure what to conclude about the upstream issues.

I think it's the same as with any other potential upstream issue -- you can dig deeper into the problem by continuing to try to isolate the causes using more and more basic functionality or not, depending on time availability and interest.