nel-lab / mesmerize-core

High level pandas-based API for batch analysis of Calcium Imaging data using CaImAn
Other
60 stars 15 forks source link

Plots not displaying with a RTX A2000 on Windows #267

Closed JohnStout closed 7 months ago

JohnStout commented 8 months ago

Running some code from the caiman workshop to visualize gaussian blurring of my calcium imaging data. The attached code works fine on my mac, but isn't rendering on my windows machine. GPU is NVIDIA RTX A2000. I'm downloading mescore and fastplotlib as described in the installation instructions (not editing mode).

Any potential ideas?

Thanks! John

Screenshot 2024-01-25 145604

Screenshot 2024-01-25 145825

kushalkolar commented 8 months ago

you probably need to click the buttons to reset the vmin-vmax

JohnStout commented 8 months ago

you probably need to click the buttons to reset the vmin-vmax

This doesn't fix the problem, but it does rescale the axes on my screen. The images remain black. I've tested this on the caimanmanager endoscope data as well as my own.

Is there anything else I can provide to help solve this?

I do get this warning about the graphics, which goes away when I convert the data to a numpy array. C:\Users\Public\anaconda3\envs\mescore\lib\site-packages\fastplotlib\graphics_features_base.py:34: UserWarning: converting float64 array to float32 warn(f"converting {array.dtype} array to float32")

However, even converting to numpy array doesn't solve the issue. Moreover, as you can probably see from the picture above, I do not see the signal intensity distribution with bars that I can drag. Instead, I see two blue bars. I think this has to do with graphics rendering, although I'm just not sure what it is.

kushalkolar commented 8 months ago

Can you plot a simple 100x100 random array?

JohnStout commented 8 months ago

Here is a random numpy array (1000,600,600). First screenshot shows the random data. Second screen shot shows that the rendering of the fastplotlib plot is blank. I've also reset the vmin-vmax.

Screenshot 2024-01-26 102515 Screenshot 2024-01-26 102529

kushalkolar commented 8 months ago

I mean just a simple Plot of the random array

JohnStout commented 8 months ago

This what you're asking for? I have two subplots, one showing data and the other being a random numpy array of size 100x100

Screenshot 2024-01-31 113928

JohnStout commented 8 months ago

Also, here is an actual plot of the 100x100 numpy array. Literally plt.plot(np.random.rand(100,100))

Screenshot 2024-01-31 114103

JohnStout commented 8 months ago

Ignore everything above, I now see you wanted me to do a fastplotlib Plot. Here you go

Screenshot 2024-01-31 115919

kushalkolar commented 8 months ago

This is probably a WGPU issue. After displaying the plot can you print the output of this:

import pygfx

print_wgpu_report()
kushalkolar commented 8 months ago

I'm curious if other graphics display, lines and scatter, to rule out if this is something specific to images:

Do these work:

# linspace, create 100 evenly spaced x values from -10 to 10
xs = np.linspace(-10, 10, 100)
# sine wave
ys = np.sin(xs)
sine = np.dstack([xs, ys])[0]

# cosine wave
ys = np.cos(xs)
cosine = np.dstack([xs, ys])[0]

plot = fpl.Plot()

plot.add_line(sine, thickness=10)

plot.show()

and scatter:

# create a random distribution of 10,000 xyz coordinates
n_points = 10_000

# if you have a good GPU go for 1.2 million points :D 
# this is multiplied by 3
#n_points = 400_000
dims = (n_points, 3)

offset = 15

normal = np.random.normal(size=dims, scale=5)
cloud = np.vstack(
    [
        normal - offset,
        normal,
        normal + offset,
    ]
)

colors = ["yellow"] * n_points + ["cyan"] * n_points + ["magenta"] * n_points

# grid with 2 rows and 2 columns
shape = (2, 2)

# define the camera
# a mix of 2d and 3d
cameras = [
    ['2d', '3d'], 
    ['3d', '2d']
]

# pan-zoom controllers for each view
# views are synced if they have the 
# same controller ID
# you can only sync controllers that use the same camera type
# i.e. you cannot sync between 2d and 3d subplots
controller_ids = [
    [0, 1],
    [1, 0]
]

# create the grid plot
grid_plot = GridPlot(
    shape=shape,
    cameras=cameras,
    controller_ids=controller_ids
)

for subplot in grid_plot:
    subplot.add_scatter(data=cloud, colors=colors, alpha=0.7, sizes=5)

    subplot.set_axes_visibility(True)
    subplot.set_grid_visibility(True)

grid_plot.show()
JohnStout commented 8 months ago

For some reason my response didn't send.

The first plot didn't work (black window again).

The second plot showed circles varying in color on a black screen.

kushalkolar commented 8 months ago

Screenshot of the second?

kushalkolar commented 8 months ago

At this point I'm going to have to refer you to post an issue with pygfx because this seems like a very low-level issue. Make an issue where you run each of these in separate cells and post the results. This will test meshes, image, scatter and lines.

Mesh

import pygfx as gfx
import pylinalg as la

cube = gfx.Mesh(
    gfx.box_geometry(200, 200, 200),
    gfx.MeshPhongMaterial(color="#336699"),
)

def animate():
    rot = la.quat_from_euler((0.005, 0.01), order="XY")
    cube.local.rotation = la.quat_mul(rot, cube.local.rotation)

disp = gfx.Display()
disp.before_render = animate
disp.stats = True
disp.show(cube)

Scatter

import numpy as np
from wgpu.gui.auto import WgpuCanvas, run
import pygfx as gfx

canvas = WgpuCanvas()
renderer = gfx.WgpuRenderer(canvas)

scene = gfx.Scene()

positions = np.random.normal(0, 0.5, (100, 3)).astype(np.float32)
sizes = np.random.rand(100).astype(np.float32) * 50
colors = np.random.rand(100, 4).astype(np.float32)
geometry = gfx.Geometry(positions=positions, sizes=sizes, colors=colors)

material = gfx.PointsMaterial(color_mode="vertex", vertex_sizes=True)
points = gfx.Points(geometry, material)
scene.add(points)

scene.add(
    gfx.Background(None, gfx.BackgroundMaterial((0.2, 0.0, 0, 1), (0, 0.0, 0.2, 1)))
)

camera = gfx.NDCCamera()

canvas.request_draw(lambda: renderer.render(scene, camera))
run()

Image

import imageio.v3 as iio
from wgpu.gui.auto import WgpuCanvas, run
import pygfx as gfx

canvas = WgpuCanvas()
renderer = gfx.renderers.WgpuRenderer(canvas)
scene = gfx.Scene()

im = iio.imread("imageio:astronaut.png")[:, :, 1]

image = gfx.Image(
    gfx.Geometry(grid=gfx.Texture(im, dim=2)),
    gfx.ImageBasicMaterial(clim=(0, 255)),
)
scene.add(image)

camera = gfx.OrthographicCamera(512, 512)
camera.local.position = (256, 256, 0)
camera.local.scale_y = -1

canvas.request_draw(lambda: renderer.render(scene, camera))
run()

Lines

import numpy as np
from wgpu.gui.auto import WgpuCanvas, run
import pygfx as gfx

canvas = WgpuCanvas()
renderer = gfx.WgpuRenderer(canvas)
renderer_svg = gfx.SvgRenderer(640, 480, "~/line.svg")

scene = gfx.Scene()
positions = [[200 + np.sin(i) * i * 6, 200 + np.cos(i) * i * 6, 0] for i in range(20)]
positions += [[np.nan, np.nan, np.nan]]
positions += [[400 - np.sin(i) * i * 6, 200 + np.cos(i) * i * 6, 0] for i in range(20)]
positions += [[np.nan, np.nan, np.nan]]
positions += [
    [450, 400, 0],
    [375, 400, 0],
    [300, 400, 0],
    [400, 370, 0],
    [300, 340, 0],
]

# Spiral away in z (to make the depth buffer less boring)
for i in range(len(positions)):
    positions[i][2] = i

line = gfx.Line(
    gfx.Geometry(positions=positions),
    gfx.LineMaterial(thickness=12.0, color=(0.8, 0.7, 0.0)),
)
scene.add(line)

camera = gfx.OrthographicCamera(600, 500)
camera.local.position = (300, 250, 0)

controller = gfx.PanZoomController(camera, register_events=renderer)

renderer_svg.render(scene, camera)
canvas.request_draw(lambda: renderer.render(scene, camera))
run()
kushalkolar commented 8 months ago

@JohnStout if this is still occuring it would be great if you can post this over at pygfx since we want to make this work across all GPUs, or at least know if there are incompatibilities with some GPUs. :)

JohnStout commented 8 months ago

Thanks Kushal, it is an unresolved issue but that is because I haven’t gotten around to that machine. Hoping to do this soon!

On Fri, Feb 16, 2024 at 1:01 AM Kushal Kolar @.***> wrote:

@JohnStout https://github.com/JohnStout if this is still occuring it would be great if you can post this over at pygfx since we want to make this work across all GPUs, or at least know if there are incompatibilities with some GPUs. :)

— Reply to this email directly, view it on GitHub https://github.com/nel-lab/mesmerize-core/issues/267#issuecomment-1947806341, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK7U57UEC5MH5GSONUPOBHDYT3Y27AVCNFSM6AAAAABCLC6TYOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBXHAYDMMZUGE . You are receiving this because you were mentioned.Message ID: @.***>

JohnStout commented 7 months ago

Solved. Was as simple as an outdated graphics driver. Never posted to pygfx or wgpu, just dug into the wgpu docs on making sure windows graphics cards have updated drivers. Thanks Kushal.

kushalkolar commented 7 months ago

Yea nvidia and drivers is always a pain, I assume you just updated to the latest drivers?

JohnStout commented 7 months ago

Yup! I was a little concerned just doing a blinded update to the latest driver because I don't know when that nvidia gpu was installed, but it worked out!