mpi-dortmund / napari-boxmanager Goto Github PK
View Code? Open in Web Editor NEWLicense: Mozilla Public License 2.0
License: Mozilla Public License 2.0
I can at least reproduce this with filaments when picking tomograms.
If start picking on a new slice, this table gets not updated when "Slices: Occupied" is selected.
@mstabrin Could you have a look?
Its related to this:
One solution could be to replace the particle layers with a shape layer and use ellipses. However, the second issue is mentioning performance problems in this cases.
Data to reproduce: /mnt/billy/Transfer/napari_issues/issue_coords_linking
(not public)
napari_boxmanager tomo/.mrc coords/.coords
If you then press Link
in organize_layer
tab, no pairs are found.
Hi there,
I tried using the napari boxmanager to create training data later required for crYOLO on one of my own tomograms (.mrc format). I followed the tutorial for crYOLO but napari always throws the following error when I try to save my particle layer:
AxisError: axis 1 is out of bounds for array of dimension 1
So far, I've tried the installation recommended for crYOLO as well as the standalone version of napari + boxmanager.
What is the cause of this or how can I prevent this from happening? Thank you for the help and all the best,
Felix
When you try to save filaments as CBOX you get the following error:
File /opt/user_software/miniconda3_envs/napari-tomotwin/lib/python3.10/site-packages/box_manager/io/cbox.py:214, in _make_df_data_filament(coordinates=<class 'numpy.ndarray'> (20, 4) float64, box_size=<class 'numpy.ndarray'> (20,) int64, features= fid
0 0
0 0
0 0
0 0
0 0
1 1...
2 2
3 3
3 3
3 3
3 3
4 4
4 4, filament_spacing=0, **kwargs={'metadata': {'linked_image_layers': [140299350001552], 'skip_match': None, 'original_path': 'tomo_a15/d01t15_a15.mrc', 'is_2d_stack': False, 'is_filament_layer': True, 0: {'write': None}, 1: {'write': None}, 2: {'write': None}, 3: {'write': None}, 4: {'write': None}, ...}})
206 distance = filament_spacing
207 filaments[index_fil] = coordsio.resample_filament(
208 fil,
209 distance,
(...)
212 other_interpolation_col=other_interpolation_cols,
213 )
--> 214 verts = pd.DataFrame(
pd = <module 'pandas' from '/opt/user_software/miniconda3_envs/napari-tomotwin/lib/python3.10/site-packages/pandas/__init__.py'>
coordinates = <class 'numpy.ndarray'> (20, 4) float64
215 coordinates, columns=["_CoordinateY", "_CoordinateX", "_filamentid"]
216 )
217 verts["_Width"] = box_size
218 verts["_Height"] = box_size
File /opt/user_software/miniconda3_envs/napari-tomotwin/lib/python3.10/site-packages/pandas/core/frame.py:722, in DataFrame.__init__(self=UNRECOVERABLE REPR FAILURE, data=<class 'numpy.ndarray'> (20, 4) float64, index=None, columns=['_CoordinateY', '_CoordinateX', '_filamentid'], dtype=None, copy=False)
712 mgr = dict_to_mgr(
713 # error: Item "ndarray" of "Union[ndarray, Series, Index]" has no
714 # attribute "name"
(...)
719 typ=manager,
720 )
721 else:
--> 722 mgr = ndarray_to_mgr(
data = <class 'numpy.ndarray'> (20, 4) float64
index = None
columns = ['_CoordinateY', '_CoordinateX', '_filamentid']
dtype = None
copy = False
manager = 'block'
723 data,
724 index,
725 columns,
726 dtype=dtype,
727 copy=copy,
728 typ=manager,
729 )
731 # For data is list-like, or Iterable (will consume into list)
732 elif is_list_like(data):
File /opt/user_software/miniconda3_envs/napari-tomotwin/lib/python3.10/site-packages/pandas/core/internals/construction.py:349, in ndarray_to_mgr(values=<class 'numpy.ndarray'> (20, 4) float64, index=RangeIndex(start=0, stop=20, step=1), columns=Index(['_CoordinateY', '_CoordinateX', '_filamentid'], dtype='object'), dtype=None, copy=False, typ='block')
344 # _prep_ndarraylike ensures that values.ndim == 2 at this point
345 index, columns = _get_axes(
346 values.shape[0], values.shape[1], index=index, columns=columns
347 )
--> 349 _check_values_indices_shape_match(values, index, columns)
values = <class 'numpy.ndarray'> (20, 4) float64
index = RangeIndex(start=0, stop=20, step=1)
columns = Index(['_CoordinateY', '_CoordinateX', '_filamentid'], dtype='object')
351 if typ == "array":
353 if issubclass(values.dtype.type, str):
File /opt/user_software/miniconda3_envs/napari-tomotwin/lib/python3.10/site-packages/pandas/core/internals/construction.py:420, in _check_values_indices_shape_match(values=<class 'numpy.ndarray'> (20, 4) float64, index=RangeIndex(start=0, stop=20, step=1), columns=Index(['_CoordinateY', '_CoordinateX', '_filamentid'], dtype='object'))
418 passed = values.shape
419 implied = (len(index), len(columns))
--> 420 raise ValueError(f"Shape of passed values is {passed}, indices imply {implied}")
passed = (20, 4)
implied = (20, 3)
ValueError: Shape of passed values is (20, 4), indices imply (20, 3)
So, for tomograms we usally don't use stacks, we do
napari_boxmanager tomos/*.mrc coords/*.cbox
Now the linking is not working (#21), probably because it's made for stacks of micrographs (but linking also does not work if you open the tomograms as stacks).
Anyway, there should be an option that allows to match individual layers tomo/coordinate by name.
In the .coords files, could an additional column be added with the value of the width that has been pricked ?
Observed with tomos (but it probably also happens for micrographs):
This only happens if you first create the filament layer, add a filament and then apply a low pass filter. If you first low pass filter it and then create the filament layer it works.
Given a cbox filament file with filament verticis:
The BM ask to load filamet verts when you open the cbox like this:
napari_boxmanager coord/*.cbox
The BM DONT ask to load filamet verts when you open the cbox like this:
napari_boxmanager 'coord/*.cbox'
Hi @thorstenwagner ๐๐ผ
In working on conda-forge/napari-boxmanager-feedstock#5 I noticed that some packages that are being used explicitly (import package
) are not being listed as dependencies of the package. It still works as napari is bringing these deps, but that may not be always the case, plus we should list all dependencies we rely on explicitly.
The packages are:
- qtpy
- scipy
- tifffile
- tqdm
Could you update this for a future release?
Thanks ๐๐ผ
When you try to save coordinates as tloc the boxmanager crashes:
src/box_manager/_tests/test_organizelayer.py:84 (Test__run_save.test_save_tomo_particle_tloc)
self = <box_manager._tests.test_organizelayer.Test__run_save object at 0x7fba4576e350>
napari_viewer = Viewer(axes=Axes(visible=False, labels=True, colored=True, dashed=False, arrows=True), camera=Camera(center=(0.0, 249.... 0x7fba04c013f0>, 'Control-Shift-A': <function InteractionBoxMouseBindings._transform_active_layer at 0x7fba04c01510>})
organize_layer_widget_tomo = <box_manager._qt.OrganizeLayer.OrganizeLayerWidget object at 0x7fba04441e10>
def test_save_tomo_particle_tloc(self, napari_viewer, organize_layer_widget_tomo):
# generate random tomogram
organize_layer_widget_tomo._new_points()
organize_layer_widget_tomo.save_layers['format'].setCurrentIndex(1) #tloc
os.makedirs("/tmp/blub/", exist_ok=True)
points = [[77, 0, 0], [77, 100, 100], [77, 200, 200]]
napari_viewer.layers[1].add(points)
> organize_layer_widget_tomo._run_save()
/home/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_tests/test_organizelayer.py:92:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/OrganizeLayer.py:359: in _run_save
napari_get_writer(
/home/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_writer.py:28: in napari_get_writer
return writer(path, data, suffix, cur_spacing)
/home/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/io/tloc.py:279: in from_napari
path = coordsio.from_napari(
/home/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/io/io_utils.py:612: in from_napari
last_file = _write_particle_data(
/home/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/io/io_utils.py:527: in _write_particle_data
format_func(
/home/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/io/tloc.py:257: in _format_tloc
data_df["size"] = features["size"].to_numpy()
/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/pandas/core/frame.py:3761: in __getitem__
indexer = self.columns.get_loc(key)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = RangeIndex(start=0, stop=0, step=1), key = 'size'
@doc(Index.get_loc)
def get_loc(self, key):
if is_integer(key) or (is_float(key) and key.is_integer()):
new_key = int(key)
try:
return self._range.index(new_key)
except ValueError as err:
raise KeyError(key) from err
if isinstance(key, Hashable):
> raise KeyError(key)
E KeyError: 'size'
/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/pandas/core/indexes/range.py:349: KeyError
Its reproduced by this test:
https://github.com/MPI-Dortmund/napari-boxmanager/blob/reproduce-issues/src/box_manager/_tests/test_organizelayer.py#L85
Right now you can't load filaments as shape layer, which makes it hard to save some manual picking and restart again.
I will extend the CBOX format that it also saves the filament verticis and napari will than provide an dialog to load them either as points layer or as shape layer.
@fonsecareyna82 was also asking for it.
The PR #15 has broken the intended behavior that filtered layers are automatically linked and made visible. Markus is on it :-)
According the mailing list:
Hello Thorsten,
I mentioned before that coordinates visualised in Napari do not seem to match the visualisation in imod. IE filaments manually picked in imod appear to be offset in Napari.
I fixed this by applying an origin correction based on the origin that is displayed in the header of the tomograms from imod. In my case I have to adjust 15px in X and 16 in Y, based on a pixel size of 7.0184A, which shifts everything into place. Possibly Napari doesn't account for the origin when displaying coordinates?
Best regards,
Charlie
When you loaded a picking result from tomotwin (.tloc) and want to save it, it gives bad filenames like '*.coords' .
Hello team!
While working on conda-forge/napari-boxmanager-feedstock#12 we found a PyQt5 import.
See
from PyQt5.QtWidgets import QComboBox
The plugin documentation for napari has a set of best practices for developers, which includes a clause recommending not to depend directly on PyQt5 or PySide2 to allow end-users to choose their bindings freely. More details here.
Even if it is a test, it would be good to use qtpy, to avoid accidentally adding a direct dependency on PyQt5.
Cheers! ๐
Files to reproduce: /mnt/billy/Transfer/napari_issues/issue_linking/
(not public)
napari_boxmanager tomos/*.mrc coords/tomo02.cbox coords/tomo01.cbox
This happens when you try to open a folder via command line or via GUI:
Traceback (most recent call last):
File "/home/twagner/.conda/envs/napari-cryolo-test/bin/napari", line 10, in <module>
sys.exit(main())
File "/home/twagner/.local/lib/python3.10/site-packages/napari/__main__.py", line 561, in main
_run()
File "/home/twagner/.local/lib/python3.10/site-packages/napari/__main__.py", line 341, in _run
viewer._window._qt_viewer._qt_open(
File "/home/twagner/.local/lib/python3.10/site-packages/napari/_qt/qt_viewer.py", line 830, in _qt_open
self.viewer.open(
File "/home/twagner/.local/lib/python3.10/site-packages/napari/components/viewer_model.py", line 1014, in open
self._add_layers_with_plugins(
File "/home/twagner/.local/lib/python3.10/site-packages/napari/components/viewer_model.py", line 1216, in _add_layers_with_plugins
layer_data, hookimpl = read_data_with_plugins(
File "/home/twagner/.local/lib/python3.10/site-packages/napari/plugins/io.py", line 77, in read_data_with_plugins
res = _npe2.read(paths, plugin, stack=stack)
File "/home/twagner/.local/lib/python3.10/site-packages/napari/plugins/_npe2.py", line 55, in read
layer_data, reader = io_utils.read_get_reader(
File "/home/twagner/.local/lib/python3.10/site-packages/npe2/io_utils.py", line 66, in read_get_reader
return _read(
File "/home/twagner/.local/lib/python3.10/site-packages/npe2/io_utils.py", line 165, in _read
if layer_data := read_func(paths, stack=stack):
File "/home/twagner/.local/lib/python3.10/site-packages/npe2/manifest/contributions/_readers.py", line 60, in npe1_compat
return callable_(path) # type: ignore
File "/mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_reader.py", line 47, in get_dir
is_first_file_tomo=is_tomo(files[0],reader)
UnboundLocalError: local variable 'reader' referenced before assignment
Its not possible yet to write coordinates as cryosparc STAR file (Reading is already possible). This was for example requested by @AntonyLL in MPI-Dortmund/cryolo#15 .
Use case: Change box size in multiple coordinate of tomograms
So far you have to save each and every coordinate layer separately.
When you create training data of filaments, the filaments have flipped vertici coordinates in the cbox file. The other coordinates are fine.
This is fixed with #55 .
Observed that on 11k x 8k micrographs when picking particles manually.
On the non low pass filtered image stack it works fine. On the band pass filtered stack each pick takes 3-5 seconds to appear.
Any idea @mstabrin ? Could it be related to your proxy?
Data is here: agraunser/transfer/Thorsten/Oleg (not public)
How to reproduce the issue:
Let's say you open 3 tomograms A,B and C
The layer list is organized like this:
C
B
A
Now you create a filament picking layer A and for B.
When you now select in the boxmanager the filamant layer for A to add some picking it will always also make tomogram B visible, which makes it very almost impossible to pick.
@mstabrin
As you did the implementation for layer visibility, could you please have a look?
If you open a folder with tomograms with File -> Open Folder it opens it as separate channels (example with 2 tomograms):
This lets many functions fail afterwards
For example, steps to reproduce:
napari_boxmanager
Observer:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/OrganizeLayer.py:521, in OrganizeLayerWidget._new_shapes(self=<box_manager._qt.OrganizeLayer.OrganizeLayerWidget object>)
510 metadata["is_filament_layer"] = True
512 kwargs = {
513 "metadata": metadata,
514 "face_color": "transparent",
(...)
519 "shape_type": "path",
520 }
--> 521 shape = self.napari_viewer.add_shapes(
self = <box_manager._qt.OrganizeLayer.OrganizeLayerWidget object at 0x7ff36c1afd00>
self.napari_viewer = Viewer(axes=Axes(visible=False, labels=True, colored=True, dashed=False, arrows=True), camera=Camera(center=(0.0, 255.5, 255.5), zoom=1.8369140625000002, angles=(0.0, 0.0, 90.0), perspective=0.0, interactive=True), cursor=Cursor(position=(1.0, 100.0, 462.9130781499203, 603.3660287081341), scaled=True, size=1, style=<CursorStyle.STANDARD: 'standard'>), dims=Dims(ndim=4, ndisplay=2, last_used=0, range=((0.0, 2.0, 1.0), (0.0, 200.0, 1.0), (0.0, 512.0, 1.0), (0.0, 512.0, 1.0)), current_step=(1, 100, 256, 256), order=(0, 1, 2, 3), axis_labels=('0', '1', '2', '3')), grid=GridCanvas(stride=1, shape=(-1, -1), enabled=False), layers=[<Image layer 'images' at 0x7ff36c1eead0>, <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>], scale_bar=ScaleBar(visible=False, colored=False, color=<class 'numpy.ndarray'> (4,) float32, ticks=True, position=<Position.BOTTOM_RIGHT: 'bottom_right'>, font_size=10.0, box=False, box_color=<class 'numpy.ndarray'> (4,) float32, unit=None), text_overlay=TextOverlay(visible=False, color=<class 'numpy.ndarray'> (4,) float32, font_size=10.0, position=<TextOverlayPosition.TOP_LEFT: 'top_left'>, text=''), overlays=Overlays(interaction_box=InteractionBox(points=None, show=False, show_handle=False, show_vertices=False, selection_box_drag=None, selection_box_final=None, transform_start=<napari.utils.transforms.transforms.Affine object at 0x7ff3771808e0>, transform_drag=<napari.utils.transforms.transforms.Affine object at 0x7ff377180940>, transform_final=<napari.utils.transforms.transforms.Affine object at 0x7ff3771809a0>, transform=<napari.utils.transforms.transforms.Affine object at 0x7ff377180a00>, allow_new_selection=True, selected_vertex=None)), help='', status='', tooltip=Tooltip(visible=False, text=''), theme='dark', title='napari', mouse_over_canvas=False, mouse_move_callbacks=[<function InteractionBoxMouseBindings.initialize_mouse_events.<locals>.mouse_move at 0x7ff36c2db1c0>], mouse_drag_callbacks=[<function InteractionBoxMouseBindings.initialize_mouse_events.<locals>.mouse_drag at 0x7ff36c444820>], mouse_double_click_callbacks=[], mouse_wheel_callbacks=[<function dims_scroll at 0x7ff37bd29ab0>], _persisted_mouse_event={}, _mouse_drag_gen={}, _mouse_wheel_gen={}, keymap={'Shift': <function InteractionBoxMouseBindings.initialize_key_events.<locals>.hold_to_lock_aspect_ratio at 0x7ff36c444700>, 'Control-Shift-R': <function InteractionBoxMouseBindings._reset_active_layer_affine at 0x7ff36c31c790>, 'Control-Shift-A': <function InteractionBoxMouseBindings._transform_active_layer at 0x7ff36c31c670>})
kwargs = {'metadata': {'do_activate_on_insert': True, 'linked_image_layers': [140683467746000], 'skip_match': None, 'original_path': '/mnt/data/twagner/Projects/TomoTwin/results/202205_GeneralizationTomo/tomo/*.mrc', 'is_2d_stack': True, 0: {'path': '/mnt/data/twagner/Projects/TomoTwin/results/202205_GeneralizationTomo/tomo/tiltseries_rec.box', 'name': 'tiltseries_rec.box', 'image_name': 'tiltseries_rec.mrc', 'real': False, 'write': None}, 1: {'path': '/mnt/data/twagner/Projects/TomoTwin/results/202205_GeneralizationTomo/tomo/tiltseries_rec_lp60.box', 'name': 'tiltseries_rec_lp60.box', 'image_name': 'tiltseries_rec_lp60.mrc', 'real': False, 'write': None}, 'is_filament_layer': True}, 'face_color': 'transparent', 'edge_color': 'red', 'edge_width': 20, 'opacity': 0.4, 'name': 'filaments (tomo/*.mrc)', 'shape_type': 'path'}
522 ndim=max(self.napari_viewer.dims.ndim, 2),
523 scale=self.napari_viewer.layers.extent.step,
524 **kwargs,
525 )
526 shape.mode = Mode.ADD_PATH
File /opt/user_software/miniconda3/envs/napari-cryolo/lib/python3.10/site-packages/napari/components/viewer_model.py:5, in add_shapes(self=Viewer(axes=Axes(visible=False, labels=True, col...ings._transform_active_layer at 0x7ff36c31c670>}), data=None, ndim=4, features=None, properties=None, property_choices=None, text=None, shape_type='path', edge_width=20, edge_color='red', edge_color_cycle=None, edge_colormap='viridis', edge_contrast_limits=None, face_color='transparent', face_color_cycle=None, face_colormap='viridis', face_contrast_limits=None, z_index=0, name='filaments (tomo/*.mrc)', metadata={'do_activate_on_insert': True, 'linked_image_layers': [140683467746000], 'skip_match': None, 'original_path': '/mnt/data/twagner/Projects/TomoTwin/results/202205_GeneralizationTomo/tomo/*.mrc', 'is_2d_stack': True, 0: {'image_name': 'tiltseries_rec.mrc', 'name': 'tiltseries_rec.box', 'path': '/mnt/data/twagner/Projects/TomoTwin/results/202205_GeneralizationTomo/tomo/tiltseries_rec.box', 'real': False, 'write': None}, 1: {'image_name': 'tiltseries_rec_lp60.mrc', 'name': 'tiltseries_rec_lp60.box', 'path': '/mnt/data/twagner/Projects/TomoTwin/results/202205_GeneralizationTomo/tomo/tiltseries_rec_lp60.box', 'real': False, 'write': None}, 'is_filament_layer': True}, scale=<class 'numpy.ndarray'> (4,) float64, translate=None, rotate=None, shear=None, affine=None, opacity=0.4, blending='translucent', visible=True, cache=True, experimental_clipping_planes=None)
3 import inspect
4 import itertools
----> 5 import os
6 import warnings
7 from functools import lru_cache
File /opt/user_software/miniconda3/envs/napari-cryolo/lib/python3.10/_collections_abc.py:1128, in MutableSequence.append(self=[<Image layer 'images' at 0x7ff36c1eead0>, <Shap...ayer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>], value=<Shapes layer 'filaments (tomo/*.mrc)'>)
1126 def append(self, value):
1127 'S.append(value) -- append value to the end of the sequence'
-> 1128 self.insert(len(self), value)
value = <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>
self = [<Image layer 'images' at 0x7ff36c1eead0>, <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>]
File /opt/user_software/miniconda3/envs/napari-cryolo/lib/python3.10/site-packages/napari/components/layerlist.py:166, in LayerList.insert(self=[<Image layer 'images' at 0x7ff36c1eead0>, <Shap...ayer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>], index=1, value=<Shapes layer 'filaments (tomo/*.mrc)'>)
164 self._clean_cache()
165 new_layer.events.set_data.connect(self._clean_cache)
--> 166 super().insert(index, new_layer)
new_layer = <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>
index = 1
File /opt/user_software/miniconda3/envs/napari-cryolo/lib/python3.10/site-packages/napari/utils/events/containers/_selectable_list.py:66, in SelectableEventedList.insert(self=[<Image layer 'images' at 0x7ff36c1eead0>, <Shap...ayer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>], index=1, value=<Shapes layer 'filaments (tomo/*.mrc)'>)
65 def insert(self, index: int, value: _T):
---> 66 super().insert(index, value)
index = 1
value = <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>
67 if self._activate_on_insert:
68 # Make layer selected and unselect all others
69 self.selection.active = value
File /opt/user_software/miniconda3/envs/napari-cryolo/lib/python3.10/site-packages/napari/utils/events/containers/_evented_list.py:188, in EventedList.insert(self=[<Image layer 'images' at 0x7ff36c1eead0>, <Shap...ayer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>], index=1, value=<Shapes layer 'filaments (tomo/*.mrc)'>)
186 self.events.inserting(index=index)
187 super().insert(index, value)
--> 188 self.events.inserted(index=index, value=value)
index = 1
value = <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>
self.events.inserted = <napari.utils.events.event.EventEmitter object at 0x7ff377162a10>
self.events = <napari.utils.events.event.EmitterGroup object at 0x7ff377162800>
self = [<Image layer 'images' at 0x7ff36c1eead0>, <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>]
189 self._connect_child_emitters(value)
File /opt/user_software/miniconda3/envs/napari-cryolo/lib/python3.10/site-packages/napari/utils/events/event.py:757, in EventEmitter.__call__(self=<napari.utils.events.event.EventEmitter object>, *args=(), **kwargs={'index': 1, 'value': <Shapes layer 'filaments (tomo/*.mrc)'>})
754 self._block_counter.update([cb])
755 continue
--> 757 self._invoke_callback(cb, event if pass_event else None)
event = <Event blocked=False handled=False native=None source=None sources=[] type='inserted'>
self = <napari.utils.events.event.EventEmitter object at 0x7ff377162a10>
cb = <bound method SelectMetricWidget._handle_insert of <box_manager._qt.SelectMetric.SelectMetricWidget object at 0x7ff36c1af370>>
pass_event = True
758 if event.blocked:
759 break
File /opt/user_software/miniconda3/envs/napari-cryolo/lib/python3.10/site-packages/napari/utils/events/event.py:794, in EventEmitter._invoke_callback(self=<napari.utils.events.event.EventEmitter object>, cb=<bound method SelectMetricWidget._handle_insert ...ager._qt.SelectMetric.SelectMetricWidget object>>, event=<Event blocked=False handled=False native=None source=None sources=[] type='inserted'>)
792 self.disconnect(cb)
793 return
--> 794 _handle_exception(
self = <napari.utils.events.event.EventEmitter object at 0x7ff377162a10>
event = <Event blocked=False handled=False native=None source=None sources=[] type='inserted'>
cb = <bound method SelectMetricWidget._handle_insert of <box_manager._qt.SelectMetric.SelectMetricWidget object at 0x7ff36c1af370>>
(cb, event) = (<bound method SelectMetricWidget._handle_insert of <box_manager._qt.SelectMetric.SelectMetricWidget object at 0x7ff36c1af370>>, <Event blocked=False handled=False native=None source=None sources=[] type='inserted'>)
795 self.ignore_callback_errors,
796 self.print_callback_errors,
797 self,
798 cb_event=(cb, event),
799 )
File /opt/user_software/miniconda3/envs/napari-cryolo/lib/python3.10/site-packages/napari/utils/events/event.py:781, in EventEmitter._invoke_callback(self=<napari.utils.events.event.EventEmitter object>, cb=<bound method SelectMetricWidget._handle_insert ...ager._qt.SelectMetric.SelectMetricWidget object>>, event=<Event blocked=False handled=False native=None source=None sources=[] type='inserted'>)
779 try:
780 if event is not None:
--> 781 cb(event)
event = <Event blocked=False handled=False native=None source=None sources=[] type='inserted'>
cb = <bound method SelectMetricWidget._handle_insert of <box_manager._qt.SelectMetric.SelectMetricWidget object at 0x7ff36c1af370>>
782 else:
783 cb()
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/SelectMetric.py:723, in SelectMetricWidget._handle_insert(self=<box_manager._qt.SelectMetric.SelectMetricWidget object>, event=<Event blocked=False handled=False native=None source=None sources=[] type='inserted'>)
720 pass
722 prev_expansion = self.table_widget.get_expansion_state()
--> 723 self._add_remove_table(layer, ButtonActions.ADD)
layer = <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>
ButtonActions.ADD = <ButtonActions.ADD: 0>
self = <box_manager._qt.SelectMetric.SelectMetricWidget object at 0x7ff36c1af370>
724 if "set_lock" in layer.metadata and layer.metadata["set_lock"]:
725 layer.editable = False
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/SelectMetric.py:1318, in SelectMetricWidget._add_remove_table(self=<box_manager._qt.SelectMetric.SelectMetricWidget object>, layer=<Shapes layer 'filaments (tomo/*.mrc)'>, action=<ButtonActions.ADD: 0>)
1314 layer_name = layer.name
1316 if action == ButtonActions.ADD:
1317 if self.table_model.add_group(
-> 1318 layer_name, self._prepare_entries(layer, name=layer_name)[0]
self.table_model = <box_manager._qt.SelectMetric.GroupModel object at 0x7ff36c1af2e0>
self = <box_manager._qt.SelectMetric.SelectMetricWidget object at 0x7ff36c1af370>
layer_name = 'filaments (tomo/*.mrc)'
layer = <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>
1319 ):
1320 entries = self._prepare_entries(layer)
1321 for entry in entries:
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/SelectMetric.py:1129, in SelectMetricWidget._prepare_entries(self=<box_manager._qt.SelectMetric.SelectMetricWidget object>, layer=<Shapes layer 'filaments (tomo/*.mrc)'>, name='filaments (tomo/*.mrc)')
1127 features_copy["identifier"] = "" if name is not None else 0
1128 else:
-> 1129 assert False, layer.data
layer = <Shapes layer 'filaments (tomo/*.mrc)' at 0x7ff37719e050>
1131 range_list = [
1132 entry for entry in layer.metadata if isinstance(entry, int)
1133 ]
1134 full_range = np.arange(
1135 *self.napari_viewer.dims.range[0], dtype=int
1136 ).tolist()
AssertionError: []
Current main
Files: /mnt/billy/Transfer/napari_issues/
(not public accessible, sorry)
Steps to reproduce:
napari_boxmanager 'img/*.rec'
cbox
in coord
folder (Say "YES" in the dialog)It does not happen when you open it with:
napari_boxmanager 'img/*.rec' 'coord/*.cbox'
It does not happen if you open the napari_boxmanager
without additional arguments, and then select the cbox file.
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/SelectMetric.py:1105, in SelectMetricWidget._update_on_data(self=<box_manager._qt.SelectMetric.SelectMetricWidget object>, event=<Event blocked=False handled=False native=None source=None sources=[] type='set_data'>)
1103 self.prev_valid_layers[layer.name][1] = layer.data
1104 for current_slice in current_slices:
-> 1105 self._update_table(layer, int(np.round(current_slice, 0)))
layer = <Shapes layer '...ThickF_d01_00000_lp10.mrc.cbox' at 0x7f7c59756830>
self = <box_manager._qt.SelectMetric.SelectMetricWidget object at 0x7f7c60206440>
current_slice = 1519.0862723427674
np.round = <function round_ at 0x7f7cbfefd990>
np = <module 'numpy' from '/home/twagner/.local/lib/python3.10/site-packages/numpy/__init__.py'>
1106 self.update_hist(change_selection=False)
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/SelectMetric.py:1371, in SelectMetricWidget._update_table(self=<box_manager._qt.SelectMetric.SelectMetricWidget object>, layer=<Shapes layer '...ThickF_d01_00000_lp10.mrc.cbox'>, current_slice=1519)
1368 else:
1369 assert False, layer.data
-> 1371 parent_idx, child_idx = self.table_model.find_index(
self = <box_manager._qt.SelectMetric.SelectMetricWidget object at 0x7f7c60206440>
self.table_model = <box_manager._qt.SelectMetric.GroupModel object at 0x7f7c602063b0>
layer_name = '...ThickF_d01_00000_lp10.mrc.cbox'
str(current_slice) = '1519'
current_slice = 1519
1372 layer_name, str(current_slice)
1373 )
1374 do_sort = False
1375 if child_idx is None:
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/SelectMetric.py:266, in GroupModel.find_index(self=<box_manager._qt.SelectMetric.GroupModel object>, parent_name='...ThickF_d01_00000_lp10.mrc.cbox', slice_val='1519')
264 low = 0
265 high = root_item.rowCount()
--> 266 row_idx = binary_search(parent_idx, int(slice_val), low, high)
parent_idx = 0
low = 0
high = 1
int(slice_val) = 1519
slice_val = '1519'
268 return parent_idx, row_idx
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/SelectMetric.py:260, in GroupModel.find_index.<locals>.binary_search(parent_idx=0, search_val=1519, low=0, high=1)
258 return row_idx
259 elif search_val > cur_slice:
--> 260 return binary_search(parent_idx, search_val, row_idx + 1, high)
row_idx = 0
high = 1
search_val = 1519
parent_idx = 0
row_idx + 1 = 1
261 else:
262 return binary_search(parent_idx, search_val, low, row_idx - 1)
File /mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_qt/SelectMetric.py:253, in GroupModel.find_index.<locals>.binary_search(parent_idx=0, search_val=1519, low=1, high=1)
251 row_idx = (high + low) // 2
252 try:
--> 253 cur_slice = int(self.get_value(parent_idx, row_idx, "slice"))
row_idx = 1
parent_idx = 0
self = <box_manager._qt.SelectMetric.GroupModel object at 0x7f7c602063b0>
254 except AttributeError:
255 return None
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
In case you load the old cbox format, the boxmanager is crashing with:
Traceback (most recent call last):
File "/home/twagner/.conda/envs/napari-cryolo-test/bin/napari", line 10, in <module>
sys.exit(main())
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/napari/__main__.py", line 561, in main
_run()
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/napari/__main__.py", line 341, in _run
viewer._window._qt_viewer._qt_open(
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/napari/_qt/qt_viewer.py", line 830, in _qt_open
self.viewer.open(
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/napari/components/viewer_model.py", line 1014, in open
self._add_layers_with_plugins(
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/napari/components/viewer_model.py", line 1216, in _add_layers_with_plugins
layer_data, hookimpl = read_data_with_plugins(
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/napari/plugins/io.py", line 77, in read_data_with_plugins
res = _npe2.read(paths, plugin, stack=stack)
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/napari/plugins/_npe2.py", line 55, in read
layer_data, reader = io_utils.read_get_reader(
File "/home/twagner/.local/lib/python3.10/site-packages/npe2/io_utils.py", line 66, in read_get_reader
return _read(
File "/home/twagner/.local/lib/python3.10/site-packages/npe2/io_utils.py", line 160, in _read
read_func = rdr.exec(
File "/home/twagner/.local/lib/python3.10/site-packages/npe2/manifest/contributions/_readers.py", line 52, in exec
callable_ = super().exec(kwargs=kwargs)
File "/home/twagner/.local/lib/python3.10/site-packages/npe2/manifest/utils.py", line 63, in exec
return self.get_callable(reg)(*args, **kwargs)
File "/mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_reader.py", line 90, in napari_get_reader
return select_reader(path)
File "/mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/_reader.py", line 30, in select_reader
has_shapes = bm_readers.file_has_shape(file_ext, path)
File "/mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/io/__init__.py", line 36, in file_has_shape
return _VALID_IOS[key].has_shapes(path)
File "/mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/io/cbox.py", line 57, in has_shapes
read_filament_shapes(path)
File "/mnt/data/twagner/Projects/napari/src/napari-boxmanager-github/src/box_manager/io/cbox.py", line 94, in read_filament_shapes
return star.StarFile(path)["filament_vertices"]
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/pyStarDB/sp_pystardb.py", line 69, in __init__
self.analyse_star_file()
File "/home/twagner/.conda/envs/napari-cryolo-test/lib/python3.10/site-packages/pyStarDB/sp_pystardb.py", line 141, in analyse_star_file
raise TypeError("Star file not provided or corrupted")
TypeError: Star file not provided or corrupted
Data to reproduce it:
/mnt/billy/Transfer/tomotwin_bugs/
Run:
napari_boxmanager d01t15_a15_lp60.mrc located.tloc
Then go to organize layer tab and press "Save to dir". Select a directory an press save.
The filename will be just '*.coords'
It should rather use the layer filename it that case.
I believe Napari-boxmanager is reflecting tomograms along the Y-axis resulting in a mirrored image of what's actually in the tomogram.
Here's an example:
on the the left is a micrograph from the tilt series and on the right is a slice from the imod reconstruction visualized with imod. I had to rotate the tomogram 180 degrees along the Y-axis to make it match what's in the tilt series but no reflection is necessary.
Here's the same tomographic slice shown in napari. Note that the y-axis is reflected compared to the original micrograph.
As a result, any cellular structures would be shown as a mirror image which could lead to confusion.
I just loaded a finder grid into the krios and will check whether the handedness is in fact correct in the original micrograph. Assuming it is, we should change the boxmanager to display the correct handedness.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.