Repository: mehta-lab/recOrder (language: python)

Issue:
Native support for Apple Silicon
**Problem**
`recOrder` does not currently support Apple Silicon (M1, M2, etc.) platforms natively due to the incompatibility between `pip` and PyQt5 (PyQt5 does not have a wheel for `arm_64` on PyPI). Native installation would be beneficial for both performance and potential GPU-accelerated processing/ML with a Metal backend.

**Proposed solution**
Closely track [napari's progress on supporting Qt6](https://github.com/napari/napari/issues/3880), since PyQt6/PySide6 have wheels available for the Apple Silicon platform on PyPI. And we can upgrade `recOrder` accordingly when napari makes the move. (They already have initial support merged into the main branch).
This may evolve into a broader set of [1.0.0](https://github.com/mehta-lab/recOrder/milestone/3) issues if napari starts supporting Qt 6 in a stable release soon enough.

**Alternatives**
- Offer a conda environment file that installs PyQt5 from `conda-forge`. This would require the removal of explicit dependency on `napari` in `setup.cfg`. #187 


Discussion / hints:
napari 0.4.17 has added experimental support for Qt6. `pip install napari pyqt6` now works on macOS_arm64. 

The only blocking factor is now the `napari[all]` line in `recOrder`'s `setup.cfg`, which really is an alias for `napari pyqt5 scikit-image`. Changing to `napari` allows for editable install of `recOrder` on Apple Silicon with `pip install -e <dir-to-recOrder>`:

<img width="1260" alt="recOrder-napari_arm64" src="https://user-images.githubusercontent.com/67518483/202587161-b13242fd-745d-4f67-822e-dea330f3f35f.png">

The glitching in style sheet rendering is [a known issue](https://github.com/napari/napari/pull/3707#issuecomment-1152997251) for napari with Qt6.
@ziw-liu I am trying to setup an environment for mantis project on my osx_arm64 laptop. I have been able to install all dependencies, including `nidaqmax`, `dexp`, `pyqt6`, `napari`, `pycromanager`. But, when I try `pip install -e <dir-to-recOrder>` in the main branch, pip still tries to build a pyqt5 wheel and fails. 

How do I bypass pyqt5 dependency when setting up recOrder? 

Here is the pip output.
```
Collecting PyQt5!=5.15.0,>=5.12.3
  Using cached PyQt5-5.15.9.tar.gz (3.2 MB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... -
```

As suggested in https://github.com/mehta-lab/recOrder/issues/193#issuecomment-1319382740, for the current `recOrder` you would need to manually delete this line:
https://github.com/mehta-lab/recOrder/blob/7e10ae59a1ed28cf28052b97404a2c0eba4369ff/setup.cfg#L47
before installing. And then install napari with Qt6:
```sh
pip install napari pyqt6
```

Fix patch:
diff --git a/setup.cfg b/setup.cfg
index b2191912..57daeb28 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -34,7 +34,6 @@ packages = find:
 include_package_data = True
 python_requires = >=3.9
 setup_requires = setuptools_scm
-# add your package requirements here
 install_requires =
 	waveorder==2.0.0rc1
 	pycromanager==0.27.2
@@ -43,11 +42,9 @@ install_requires =
 	colorspacious>=1.1.2
 	pyqtgraph>=0.12.3
 	napari-ome-zarr>=0.3.2 # drag and drop convenience
-	napari[all];'arm64' not in platform_machine # with Qt5 and skimage
-	napari;'arm64' in platform_machine # without Qt and skimage
-	PyQt6;'arm64' in platform_machine
+	napari[pyqt6_experimental]
 	importlib-metadata
-	iohub==0.1.0.dev3
+	iohub==0.1.0.dev4
 	
 [options.extras_require]
 dev =


Test patch:
diff --git a/recOrder/tests/widget_tests/test_dock_widget.py b/recOrder/tests/widget_tests/test_dock_widget.py
index b7f90546..5dacda10 100644
--- a/recOrder/tests/widget_tests/test_dock_widget.py
+++ b/recOrder/tests/widget_tests/test_dock_widget.py
@@ -1,17 +1,8 @@
-import sys
-import os
-
-import pytest
 from napari.viewer import ViewerModel
 
 from recOrder.plugin.main_widget import MainWidget
 
 
-# FIXME: Linux Qt platform in GitHub actions
-@pytest.mark.skipif(
-    bool("linux" in sys.platform and os.environ.get("CI")),
-    reason="Qt on Linux CI runners does not work",
-)
 def test_dock_widget(make_napari_viewer):
     viewer: ViewerModel = make_napari_viewer()
     viewer.window.add_dock_widget(MainWidget(viewer))