Skip to content

Instantly share code, notes, and snippets.

@lopuhin
Last active March 3, 2020 09:55
Show Gist options
  • Select an option

  • Save lopuhin/b11cd94ad441b3f45df8168e33cb9bfb to your computer and use it in GitHub Desktop.

Select an option

Save lopuhin/b11cd94ad441b3f45df8168e33cb9bfb to your computer and use it in GitHub Desktop.
Simple OpenGL visualization starter for Kaggle TrackML 2018
#!/usr/bin/env python3
"""
Install glumpy dependencies::
pip install Cython pyopengl
brew install glfw freetype # on OS X
Install glumpy::
pip install glumpy
"""
import argparse
from pathlib import Path
from glumpy import app, gl, gloo
from glumpy.transforms import Trackball, Position
import numpy as np
import pandas as pd
point_vertex = """
attribute vec3 position;
attribute vec4 color;
attribute float point_size;
varying vec4 v_color;
void main()
{
v_color = color;
gl_PointSize = point_size;
gl_Position = <transform>;
}
"""
point_fragment = """
varying vec4 v_color;
void main()
{
gl_FragColor = v_color;
}
"""
def main():
parser = argparse.ArgumentParser()
arg = parser.add_argument
arg('event_prefix', help='path to any event file or it\'s prefix')
arg('--n-tracks', type=int, default=20)
args = parser.parse_args()
print('Loading event data...')
event_prefix = Path(args.event_prefix)
event_id = event_prefix.stem.split('-')[0]
event_prefix = str(event_prefix.parent / event_id)
hits_df = pd.read_csv(event_prefix + '-hits.csv')
# cells_df = pd.read_csv(event_prefix + '-cells.csv')
particles_df = pd.read_csv(event_prefix + '-particles.csv')
truth_df = pd.read_csv(event_prefix + '-truth.csv')
print(f'{event_id}: {len(hits_df):,} hits, {len(particles_df):,} particles')
print('done.')
point_prog = gloo.Program(point_vertex, point_fragment)
window = app.Window(width=1024, height=1024, color=(1, 1, 1, 1))
trackball = Trackball(Position('position'))
point_prog['transform'] = trackball
window.attach(point_prog['transform'])
vtype = [('position', np.float32, 3),
('color', np.float32, 4),
('point_size', np.float32, 1)]
axes = np.zeros(6, vtype)
axes['position'] = np.array(
[[-1, 0, 0], [1, 0, 0],
[0, -1, 0], [0, 1, 0],
[0, 0, -1], [0, 0, 1],
])
axes['color'] = np.array([[0, 1, 0, 1]] * len(axes))
axes['point_size'] = np.array([8] * len(axes))
points = np.zeros(len(hits_df), vtype)
for i, axis in enumerate('xyz'):
points['position'][:, i] = hits_df[axis].values / 1000
points['color'] = np.array([[0, 0, 0, 1]] * len(points))
points['point_size'] = np.array([2] * len(points))
# points first so that points indices have zero offset
vertices = np.concatenate([points, axes]).view(gloo.VertexBuffer)
point_prog.bind(vertices)
point_indices = (np.arange(len(points), dtype=np.uint32)
.view(gloo.IndexBuffer))
axes_indices = ((len(points) + np.arange(len(axes), dtype=np.uint32))
.view(gloo.IndexBuffer))
# draw some random particles
particle_indices = []
for particle_id in (particles_df[particles_df['nhits'] > 3]
.sample(args.n_tracks, random_state=42)
['particle_id'].values):
p_truth = truth_df[truth_df['particle_id'] == particle_id]
p_hits = hits_df[hits_df['hit_id'].isin(p_truth['hit_id'])]
p_hits = p_hits.sort_values('z')
particle_indices.extend(zip(p_hits.index, p_hits.index[1:]))
for idx in p_hits.index:
vertices['color'][idx] = [1, 0, 0, 1]
vertices['point_size'][idx] = 10
particle_indices = (np.array(particle_indices, dtype=np.uint32)
.view(gloo.IndexBuffer))
gl.glLineWidth(2)
@window.event
def on_draw(dt):
window.clear()
gl.glDisable(gl.GL_DEPTH_TEST)
point_prog.draw(gl.GL_POINTS, point_indices)
gl.glEnable(gl.GL_DEPTH_TEST)
point_prog.draw(gl.GL_LINES, particle_indices)
point_prog.draw(gl.GL_LINES, axes_indices)
point_prog.draw(gl.GL_POINTS, axes_indices)
app.run()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment