Skip to content

Commit 37530cd

Browse files
authored
Merge pull request #10 from int-brain-lab/removeDeprecated
iblutil now dependency; import numerical from iblutil
2 parents 0a6af9c + 32ff36c commit 37530cd

File tree

2 files changed

+45
-48
lines changed

2 files changed

+45
-48
lines changed

iblviewer/mouse_brain.py

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from dataclasses import dataclass
2-
from typing import Any
32
import os
43
import logging
54
import numpy as np
@@ -11,17 +10,17 @@
1110
import nrrd
1211
import ibllib.atlas
1312
from ibllib.atlas.regions import BrainRegions
13+
from iblutil.numerical import ismember
1414

1515
from iblviewer.application import Viewer
1616
from iblviewer.volume import VolumeController, VolumeModel, LUTModel
1717
import iblviewer.utils as utils
1818

19-
2019
ALLEN_ATLAS_RESOLUTIONS = [10, 25, 50, 100]
2120
ALLEN_ATLASES = {'base_url': 'http://download.alleninstitute.org/informatics-archive',
2221
'mouse_ccf_folder': '/current-release/mouse_ccf',
23-
'atlas_folder': '/annotation/ccf_2017', 'atlas_prefix': '/annotation_',
24-
'dwi_folder': '/average_template', 'dwi_prefix': '/average_template_',
22+
'atlas_folder': '/annotation/ccf_2017', 'atlas_prefix': '/annotation_',
23+
'dwi_folder': '/average_template', 'dwi_prefix': '/average_template_',
2524
'volume_extension': '.nrrd'}
2625

2726
# Default origin is "bregma", an origin defined at the center of the XY axes (not on Z)
@@ -37,8 +36,8 @@
3736
class AllenAtlasExt(ibllib.atlas.AllenAtlas):
3837
"""
3938
This overwrites the constructor of AllenAtlas that is not designed to be used for the
40-
public, that is people outside of IBL. Typically, you'd want to display the Allen volume
41-
data in this viewer and perform additional tasks (such as loading your own extra data)
39+
public, that is people outside of IBL. Typically, you'd want to display the Allen volume
40+
data in this viewer and perform additional tasks (such as loading your own extra data)
4241
with other libraries. Dev note: I'm forced to copy and modify the whole constructor in this case.
4342
4443
Instantiates an atlas.BrainAtlas corresponding to the Allen CCF at the given resolution
@@ -54,7 +53,7 @@ def _read_volume(file_volume):
5453
volume = np.load(str(file_volume), allow_pickle=True)['arr_0']
5554
return volume
5655

57-
def __init__(self, res_um=25, brainmap='Allen', scaling=np.array([1, 1, 1]),
56+
def __init__(self, res_um=25, brainmap='Allen', scaling=np.array([1, 1, 1]),
5857
image_file_path=None, label_file_path=None):
5958
"""
6059
:param res_um: 10, 25 or 50 um
@@ -80,7 +79,7 @@ def __init__(self, res_um=25, brainmap='Allen', scaling=np.array([1, 1, 1]),
8079
label = self.remap_atlas(label_file_path, regions, ibregma)
8180

8281
# This calls BrainAtlas, the mother class of AllenAtlas because we want to overwrite it
83-
super(ibllib.atlas.AllenAtlas, self).__init__(image, label, dxyz, regions,
82+
super(ibllib.atlas.AllenAtlas, self).__init__(image, label, dxyz, regions,
8483
ibregma, dims2xyz=dims2xyz, xyz2dims=xyz2dims)
8584

8685
def remap_atlas(self, local_file_path, regions=None, ibregma=None):
@@ -110,8 +109,6 @@ def lateralize(self, label, regions=None, ibregma=None):
110109
:param label: Segmented volume
111110
:return: Modified volume
112111
"""
113-
# Another dependency, that probably comes along with ibllib
114-
from brainbox.numerical import ismember
115112
_logger.info("computing brain atlas annotations lookup table")
116113
if regions is None:
117114
regions = BrainRegions()
@@ -127,7 +124,7 @@ def lateralize(self, label, regions=None, ibregma=None):
127124
_, im = ismember(label, regions.id)
128125
label = np.reshape(im.astype(np.uint16), label.shape)
129126
return label
130-
127+
131128

132129

133130
@dataclass
@@ -244,7 +241,7 @@ def get_value_from_scalar_map(self, scalar):
244241
#print(scalar - scalar_map[value])
245242
if scalar_map[value] == scalar:
246243
return value
247-
244+
248245
def get_mapped_data(self, value):
249246
"""
250247
Given a value from the segmented volume, we retrieve useful info
@@ -270,7 +267,7 @@ def get_mapped_data(self, value):
270267
scalar = scalar_map.get(value)
271268
else:
272269
scalar = scalar_map[value]
273-
return {'scalar':scalar, 'region_id':region_id, 'color':color, 'alpha':alpha,
270+
return {'scalar':scalar, 'region_id':region_id, 'color':color, 'alpha':alpha,
274271
'region_name':region_name, 'region_data':region_data}
275272

276273
def remap(self, ids, source='Allen', dest='Beryl'):
@@ -282,7 +279,6 @@ def remap(self, ids, source='Allen', dest='Beryl'):
282279
:param dest: Destination mapping
283280
"""
284281
#from ibllib.atlas import BrainRegions as br
285-
from brainbox.numerical import ismember
286282
_, inds = ismember(ids, self.atlas.regions.mappings[source])
287283
return self.atlas.regions.mappings[dest][inds]
288284

@@ -313,7 +309,7 @@ def load_volume(self, file_path, remap_scalars=False, mapping=None, make_current
313309
"""
314310
Load a volume data file. Supports NRRD and many other formats thanks to vedo/VTK
315311
:param file_path: Volume file path. Could support other file types easily.
316-
:param remap_scalars: Whether scalar values in the volume are replaced by
312+
:param remap_scalars: Whether scalar values in the volume are replaced by
317313
their row id from a mapping that stores. This is necessary in the case of segmented
318314
volumes with regions that have a discontinuous id.
319315
:param mapping: Pandas Series or a Dictionary
@@ -333,7 +329,7 @@ def get_mapped_volume(self, volume, atlas_mapping=None, ibl_back_end=True):
333329
"""
334330
Set the volume data according to a mapping
335331
:param volume: Given volume to display
336-
:param atlas_mapping: Mapping, either a string for the name of the mapping or an integer.
332+
:param atlas_mapping: Mapping, either a string for the name of the mapping or an integer.
337333
:param ibl_back_end: If you are not using ibllib and want to load your own volume, set this to False
338334
so that there will be no transposition of the volume (needed for the ones from IBL)
339335
:return: Volume nd array
@@ -404,10 +400,10 @@ def __init__(self):
404400
self.ibl_model = None
405401
# Shortcut for users
406402
self.ibl_transpose = IBLAtlasModel.IBL_TRANSPOSE
407-
408-
def initialize(self, resolution=25, mapping='Beryl', add_atlas=True, add_dwi=False,
403+
404+
def initialize(self, resolution=25, mapping='Beryl', add_atlas=True, add_dwi=False,
409405
dwi_color_map='viridis', dwi_alpha_map=None, local_allen_volumes_path=None,
410-
offscreen=False, jupyter=False, embed_ui=False, embed_font_size=15,
406+
offscreen=False, jupyter=False, embed_ui=False, embed_font_size=15,
411407
plot=None, plot_window_id=0, num_windows=1, render=False, dark_mode=False):
412408
"""
413409
Initialize the controller, main entry point to the viewer
@@ -430,7 +426,7 @@ def initialize(self, resolution=25, mapping='Beryl', add_atlas=True, add_dwi=Fal
430426
"""
431427
self.model.title = 'IBL Viewer'
432428

433-
# ibllib works with two volumes at the same time: the segmented volume (called 'label')
429+
# ibllib works with two volumes at the same time: the segmented volume (called 'label')
434430
# and the DWI volume (called 'image')
435431
self.ibl_model = IBLAtlasModel()
436432
self.ibl_model.initialize(resolution, local_allen_volumes_path)
@@ -459,7 +455,7 @@ def initialize(self, resolution=25, mapping='Beryl', add_atlas=True, add_dwi=Fal
459455
self.load_bounding_mesh()
460456
except Exception:
461457
pass
462-
458+
463459
#light = vedo.Light(self.model.IBL_BREGMA_ORIGIN - [0, 0, 1000], c='w', intensity=0.2)
464460
#self.plot.add(light)
465461

@@ -480,7 +476,7 @@ def add_atlas_segmentation(self):
480476
"""
481477
if isinstance(self.atlas_controller, VolumeController):
482478
return
483-
self.atlas_controller = VolumeController(self.plot, self.ibl_model.atlas_volume,
479+
self.atlas_controller = VolumeController(self.plot, self.ibl_model.atlas_volume,
484480
alpha_unit_upper_offset=0.1, center_on_edges=True)
485481
self.register_controller(self.atlas_controller, self.atlas_controller.get_related_actors())
486482

@@ -492,10 +488,10 @@ def add_atlas_dwi(self, color_map, alpha_map):
492488
"""
493489
if isinstance(self.dwi_controller, VolumeController):
494490
return
495-
self.dwi_controller = VolumeController(self.plot, self.ibl_model.dwi_volume,
491+
self.dwi_controller = VolumeController(self.plot, self.ibl_model.dwi_volume,
496492
center_on_edges=True)
497493
self.dwi_controller.set_color_map(color_map, alpha_map)
498-
self.register_controller(self.dwi_controller, self.dwi_controller.get_related_actors())
494+
self.register_controller(self.dwi_controller, self.dwi_controller.get_related_actors())
499495

500496
def load_bounding_mesh(self, add_to_scene=False, alpha_on_scene=0.3):
501497
"""
@@ -528,7 +524,7 @@ def get_region_names(self):
528524
"""
529525
return self.ibl_model.atlas.regions.name.tolist()
530526

531-
def _select(self, actor=None, controller=None, event=None,
527+
def _select(self, actor=None, controller=None, event=None,
532528
camera_position=None, position=None, value=None):
533529
"""
534530
Define the current object selected
@@ -608,15 +604,15 @@ def add_many_points_test(self, positions, point_radius=2, auto_xy_rotate=True, a
608604
return point_cloud
609605

610606
def add_spheres(self, positions, radius=10, values=None, color_map='Accent', name='Spheres',
611-
use_origin=True, add_to_scene=True, noise_amount=0, trim_outliers=True,
607+
use_origin=True, add_to_scene=True, noise_amount=0, trim_outliers=True,
612608
bounding_mesh=None, ibl_flip_yz=True, **kwargs):
613609
"""
614610
Add new spheres
615611
:param positions: 3D array of coordinates
616612
:param radius: List same length as positions of radii. The default size is 5um, or 5 pixels
617613
in case as_spheres is False.
618614
:param values: 1D array of values, one per neuron or a time series of such 1D arrays (numpy format)
619-
:param color_map: A color map, it can be a color map built by IBLViewer or
615+
:param color_map: A color map, it can be a color map built by IBLViewer or
620616
a color map name (see vedo documentation), or a list of values, etc.
621617
:param name: All point neurons are grouped into one object, you can give it a custom name
622618
:param use_origin: Whether the origin is added as offset to the given positions
@@ -637,7 +633,7 @@ def add_spheres(self, positions, radius=10, values=None, color_map='Accent', nam
637633
if noise_amount is not None:
638634
positions += np.random.rand(len(positions), 3) * noise_amount
639635
link = True if add_to_scene and not trim_outliers else False
640-
spheres = super().add_spheres(positions, radius, values, color_map,
636+
spheres = super().add_spheres(positions, radius, values, color_map,
641637
name, use_origin, link, **kwargs)
642638
spheres.axes = axes
643639
if bounding_mesh is None:
@@ -650,19 +646,19 @@ def add_spheres(self, positions, radius=10, values=None, color_map='Accent', nam
650646
return spheres
651647

652648
def add_points(self, positions, radius=10, values=None, color_map='Accent', name='Points', screen_space=False,
653-
use_origin=True, add_to_scene=True, noise_amount=0, trim_outliers=True, bounding_mesh=None,
649+
use_origin=True, add_to_scene=True, noise_amount=0, trim_outliers=True, bounding_mesh=None,
654650
ibl_flip_yz=True, **kwargs):
655651
"""
656652
Add new points
657653
:param positions: 3D array of coordinates
658654
:param radius: List same length as positions of radii. The default size is 5um, or 5 pixels
659655
in case as_spheres is False.
660656
:param values: 1D array of values, one per neuron or a time series of such 1D arrays (numpy format)
661-
:param color_map: A color map, it can be a color map built by IBLViewer or
657+
:param color_map: A color map, it can be a color map built by IBLViewer or
662658
a color map name (see vedo documentation), or a list of values, etc.
663659
:param name: All point neurons are grouped into one object, you can give it a custom name
664660
:param screen_space: Type of point, if True then the points are static screen-space points.
665-
If False, then the points are made to scale in 3D, ie you see them larger when you
661+
If False, then the points are made to scale in 3D, ie you see them larger when you
666662
zoom closer to them, while this is not the case with screen-space points. Defaults to False.
667663
:param use_origin: Whether the origin is added as offset to the given positions
668664
:param add_to_scene: Whether the new lines are added to scene/plot and rendered
@@ -682,7 +678,7 @@ def add_points(self, positions, radius=10, values=None, color_map='Accent', name
682678
if noise_amount is not None:
683679
positions += np.random.rand(len(positions), 3) * noise_amount
684680
link = True if add_to_scene and not trim_outliers else False
685-
points = super().add_points(positions, radius, values, color_map, name,
681+
points = super().add_points(positions, radius, values, color_map, name,
686682
screen_space, use_origin, link, **kwargs)
687683
points.axes = axes
688684
if bounding_mesh is None:
@@ -694,24 +690,24 @@ def add_points(self, positions, radius=10, values=None, color_map='Accent', name
694690
self.plot.add(points)
695691
return points
696692

697-
def add_segments(self, points, end_points=None, line_width=2, values=None, color_map='Accent',
698-
name='Segments', use_origin=True, add_to_scene=True, relative_end_points=False,
699-
spherical_angles=None, radians=True, trim_outliers=True, bounding_mesh=None,
693+
def add_segments(self, points, end_points=None, line_width=2, values=None, color_map='Accent',
694+
name='Segments', use_origin=True, add_to_scene=True, relative_end_points=False,
695+
spherical_angles=None, radians=True, trim_outliers=True, bounding_mesh=None,
700696
ibl_flip_yz=True):
701697
"""
702698
Add a set of segments
703699
:param points: 3D numpy array of points of length n
704700
:param end_points: 3D numpy array of points of length n
705701
:param line_width: Line width, defaults to 2px
706702
:param values: 1D list of length n, for one scalar value per line
707-
:param color_map: A color map, it can be a color map built by IBLViewer or
703+
:param color_map: A color map, it can be a color map built by IBLViewer or
708704
a color map name (see vedo documentation), or a list of values, etc.
709705
:param name: Name to give to the object
710706
:param use_origin: Whether the current origin (not necessarily absolute 0) is used as offset
711707
:param add_to_scene: Whether the new lines are added to scene/plot and rendered
712708
:param relative_end_points: Whether the given end point is relative to the start point. False by default,
713709
except is spherical coordinates are given
714-
:param spherical_angles: 3D numpy array of spherical angle data of length n
710+
:param spherical_angles: 3D numpy array of spherical angle data of length n
715711
In case end_points is None, this replaces end_points by finding the relative
716712
coordinate to each start point with the given radius/depth, theta and phi
717713
:param radians: Whether the given spherical angle data is in radians or in degrees
@@ -729,8 +725,8 @@ def add_segments(self, points, end_points=None, line_width=2, values=None, color
729725
if end_points is not None:
730726
end_points = np.array(end_points) * axes
731727
pre_add = True if add_to_scene and not trim_outliers else False
732-
733-
#lines = super().add_segments(points, end_points, line_width, values, color_map, name, use_origin,
728+
729+
#lines = super().add_segments(points, end_points, line_width, values, color_map, name, use_origin,
734730
#pre_add, relative_end_points, spherical_angles, radians)
735731
'''
736732
Crazy python stuff here [WARNING]
@@ -764,14 +760,14 @@ def add_segments(self, points, end_points=None, line_width=2, values=None, color
764760
self.plot.add(lines)
765761
return lines
766762

767-
def add_lines(self, points, line_width=2, values=None, color_map='Accent', name='Lines',
763+
def add_lines(self, points, line_width=2, values=None, color_map='Accent', name='Lines',
768764
use_origin=True, add_to_scene=True, trim_outliers=True, bounding_mesh=None, ibl_flip_yz=True):
769765
"""
770766
Create a set of lines with given point sets
771767
:param points: List of lists of 3D coordinates
772768
:param line_width: Line width, defaults to 2px
773769
:param values: 1D list of length n, for one scalar value per line
774-
:param color_map: A color map, it can be a color map built by IBLViewer or
770+
:param color_map: A color map, it can be a color map built by IBLViewer or
775771
a color map name (see vedo documentation), or a list of values, etc.
776772
:param name: Name to give to the object
777773
:param use_origin: Whether the current origin (not necessarily absolute 0) is used as offset
@@ -811,7 +807,7 @@ def add_lines(self, points, line_width=2, values=None, color_map='Accent', name=
811807
points = all_points
812808
if values is None:
813809
values = indices
814-
810+
815811
pre_add = True if add_to_scene and not trim_outliers else False
816812
lines = super().add_lines(points, line_width, values, color_map, name, False, pre_add)
817813

@@ -827,7 +823,7 @@ def add_lines(self, points, line_width=2, values=None, color_map='Accent', name=
827823
self.plot.add(lines)
828824
return lines
829825

830-
def add_volume(self, data=None, resolution=None, file_path=None, color_map='viridis',
826+
def add_volume(self, data=None, resolution=None, file_path=None, color_map='viridis',
831827
alpha_map=None, select=False, add_to_scene=True, transpose=None):
832828
"""
833829
Add a volume to the viewer with box clipping and slicing enabled by default
@@ -840,14 +836,14 @@ def add_volume(self, data=None, resolution=None, file_path=None, color_map='viri
840836
are transparent and maximum values are opaque
841837
:param select: Whether the volume is selected
842838
:param add_to_scene: Whether the volume is added to scene
843-
:param transpose: Transposition parameter. If None. nothing happens. If True,
839+
:param transpose: Transposition parameter. If None. nothing happens. If True,
844840
then the default IBL transposition is applied. You can provide your own, that is,
845841
a list of 3 elements to reorder the volume as desired.
846842
:return: VolumeController
847843
"""
848844
if transpose == True:
849845
transpose = self.ibl_transpose
850-
return super().add_volume(data, resolution, file_path, color_map,
846+
return super().add_volume(data, resolution, file_path, color_map,
851847
alpha_map, select, add_to_scene, transpose)
852848

853849
def set_left_view(self):

setup.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#import iblviewer.launcher
33

44
setup(
5-
name = 'iblviewer',
5+
name='iblviewer',
66
version='2.4.6',
77
description='An interactive GPU-accelerated 3D viewer based on VTK',
88
url='https://github.com/int-brain-lab/iblviewer',
@@ -19,6 +19,7 @@
1919
'vtk>=9.0',
2020
'ipywebrtc',
2121
#'ibllib>=1.6.0', # This optional dependency is huge (100MB)!
22+
'iblutil',
2223
'vedo>=2021.0.3',
2324
'ipyvtklink',
2425
'PyQt5',
@@ -42,9 +43,9 @@
4243
classifiers=[
4344
'Development Status :: 5 - Production/Stable',
4445
'Intended Audience :: Science/Research',
45-
'License :: OSI Approved :: MIT License',
46+
'License :: OSI Approved :: MIT License',
4647
'Operating System :: POSIX :: Linux',
4748
'Operating System :: MacOS',
4849
'Programming Language :: Python :: 3.8',
4950
]
50-
)
51+
)

0 commit comments

Comments
 (0)