Merge branch 'master' into auto-exposure-gain-awb
This commit is contained in:
commit
1f1a75c02a
13 changed files with 1848 additions and 167 deletions
|
|
@ -6,12 +6,12 @@ stages:
|
|||
- deploy
|
||||
|
||||
# Re-usable block to install (and cache) Poetry and openflexure-microscope-server
|
||||
.poetry-install-template: &poetry-install
|
||||
.python-install-template: &python-install
|
||||
before_script:
|
||||
- curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
|
||||
- source $HOME/.poetry/env
|
||||
- poetry config virtualenvs.in-project true
|
||||
- poetry install -vv
|
||||
- python3 -m venv .venv # NB this does not overwrite an existing cached venv
|
||||
- source .venv/bin/activate
|
||||
- pip install pipenv # Should be cached after first run
|
||||
- pipenv install --dev # Should be cached after first run - will just check packages are present
|
||||
cache:
|
||||
key: "${CI_COMMIT_REF_SLUG}"
|
||||
paths:
|
||||
|
|
@ -34,10 +34,10 @@ pylint:
|
|||
image: python:3.7
|
||||
retry: 1
|
||||
|
||||
<<: *poetry-install
|
||||
<<: *python-install
|
||||
|
||||
script:
|
||||
- poetry run poe pylint
|
||||
- poe pylint
|
||||
|
||||
only:
|
||||
- branches
|
||||
|
|
@ -51,10 +51,10 @@ mypy:
|
|||
image: python:3.7
|
||||
retry: 1
|
||||
|
||||
<<: *poetry-install
|
||||
<<: *python-install
|
||||
|
||||
script:
|
||||
- poetry run poe mypy
|
||||
- poe mypy
|
||||
|
||||
artifacts:
|
||||
reports:
|
||||
|
|
@ -73,11 +73,11 @@ black:
|
|||
retry: 1
|
||||
allow_failure: true
|
||||
|
||||
<<: *poetry-install
|
||||
<<: *python-install
|
||||
|
||||
script:
|
||||
# Run static build script
|
||||
- poetry run poe black_check
|
||||
- poe black_check
|
||||
|
||||
only:
|
||||
- branches
|
||||
|
|
@ -91,10 +91,10 @@ pytest:
|
|||
image: python:3.7
|
||||
retry: 1
|
||||
|
||||
<<: *poetry-install
|
||||
<<: *python-install
|
||||
|
||||
script:
|
||||
- poetry run poe test
|
||||
- poe test
|
||||
|
||||
only:
|
||||
- branches
|
||||
|
|
@ -153,8 +153,10 @@ package:
|
|||
# Build distribution archive
|
||||
- mkdir -p dist
|
||||
- tar -c --exclude-vcs --exclude-from .tarignore -vzf dist/openflexure-microscope-server-${CI_COMMIT_REF_NAME}.tar.gz .
|
||||
- tar -c --exclude-vcs --exclude-from .tarignore -vzf dist/openflexure-microscope-webapp-${CI_COMMIT_REF_NAME}.tar.gz ./openflexure_microscope/api/static/dist/
|
||||
- cd dist/
|
||||
- sha256sum openflexure-microscope-server-${CI_COMMIT_REF_NAME}.tar.gz > openflexure-microscope-server-${CI_COMMIT_REF_NAME}.tar.gz.sha256
|
||||
- sha256sum openflexure-microscope-webapp-${CI_COMMIT_REF_NAME}.tar.gz > openflexure-microscope-webapp-${CI_COMMIT_REF_NAME}.tar.gz.sha256
|
||||
|
||||
artifacts:
|
||||
name: "dist"
|
||||
|
|
@ -162,6 +164,8 @@ package:
|
|||
paths:
|
||||
- "./dist/openflexure-microscope-server-${CI_COMMIT_REF_NAME}.tar.gz"
|
||||
- "./dist/openflexure-microscope-server-${CI_COMMIT_REF_NAME}.tar.gz.sha256"
|
||||
- "./dist/openflexure-microscope-webapp-${CI_COMMIT_REF_NAME}.tar.gz"
|
||||
- "./dist/openflexure-microscope-webapp-${CI_COMMIT_REF_NAME}.tar.gz.sha256"
|
||||
|
||||
only:
|
||||
- merge_requests
|
||||
|
|
|
|||
18
Pipfile
Normal file
18
Pipfile
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[[source]]
|
||||
url = "https://pypi.python.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[[source]]
|
||||
url = "https://www.piwheels.org/simple"
|
||||
verify_ssl = true
|
||||
name = "piwheels"
|
||||
|
||||
[requires]
|
||||
python_version = '3.7'
|
||||
|
||||
[packages]
|
||||
openflexure-microscope-server = {editable = true, path = "."}
|
||||
|
||||
[dev-packages]
|
||||
openflexure-microscope-server = {editable = true, path = ".", extras = ["dev"]}
|
||||
1612
Pipfile.lock
generated
Normal file
1612
Pipfile.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
118
README.md
118
README.md
|
|
@ -1,47 +1,40 @@
|
|||
# OpenFlexure Microscope Software
|
||||
|
||||
## Quickstart
|
||||
The "server" is the main component of the OpenFlexure Microscope's software. It is responsible for controlling microscope hardware, data management, and allowing it to be controlled locally and over a network.
|
||||
This repository now includes the web client, which is served from the root of the Python web server.
|
||||
This software runs on [Python-LabThings](https://github.com/labthings/python-labthings/), and so most non-microscope functionality is handled by that library.
|
||||
|
||||
## Getting started
|
||||
|
||||
A general user-guide on setting up your microscope can be found [**here on our website**](https://www.openflexure.org/projects/microscope/).
|
||||
This includes basic installation instructions suitable for most users.
|
||||
The simplest way to set up a microscope is to download the pre-built Raspberry Pi SD card image, which has this server already installed, along with all of its dependencies.
|
||||
There are instructions on how to [use the microscope](https://openflexure.org/projects/microscope/control) once you have installed the software, either from OpenFlexure Connect, or through a web browser.
|
||||
The web server starts on port 5000 by default, and the microscope SD image uses the hostname "microscope" so you can usually access the web interface at <http://microscope.local:5000/>.
|
||||
|
||||
Full developer documentation can be found on [**ReadTheDocs**](https://openflexure-microscope-software.readthedocs.io/).
|
||||
This includes installing the server in a mode better suited for active development.
|
||||
Full developer documentation can be found on [**ReadTheDocs**](https://openflexure-microscope-software.readthedocs.io/), including some installation notes.
|
||||
More information is also available in the [handbook](https://gitlab.com/openflexure/microscope-handbook/), and in the "development instructions" below.
|
||||
|
||||
## Key info
|
||||
## Settings
|
||||
|
||||
* Responsible for actually controlling microscope hardware, data management, and creating the API server.
|
||||
Also now includes the web client, which is served from the server root.
|
||||
* Server starts on port 5000 by default.
|
||||
* Runs on [Python-LabThings](https://github.com/labthings/python-labthings/), and so basically all non-microscope functionality is handled by that library.
|
||||
|
||||
### Server settings
|
||||
|
||||
https://openflexure-microscope-software.readthedocs.io/en/master/config.html
|
||||
|
||||
There are 2 important settings files:
|
||||
There are 2 important settings files, described in the [docs](https://openflexure-microscope-software.readthedocs.io/en/master/config.html). The paths given below are for the Raspberry Pi installation on our pre-built SD card, and will change if you run on another system:
|
||||
* `/var/openflexure/settings/microscope_configuration.json`
|
||||
* Boot-time microscope configuration. Things like the type of camera connected, the stage board, geometry etc.
|
||||
*Anything that needs to be loaded once as the server starts, and usually doesn't need to be re-written while the server is running
|
||||
* Anything that needs to be loaded once as the server starts, and usually doesn't need to be re-written while the server is running
|
||||
* This configuration file does not change often, and usually only needs to be updated when you change the physical hardware.
|
||||
* `/var/openflexure/settings/microscope_settings.json`
|
||||
* Every other persistent setting. Camera settings, calibration data, default capture settings, stream resolution etc.
|
||||
* This file changes very regularly, and if you need to reset your settings, it's usually this file that you should remove or reset.
|
||||
|
||||
# Developer guidelines
|
||||
|
||||
## Creating releases
|
||||
|
||||
* Update the applications internal version number
|
||||
* `poetry version X.y.z` (replace X.y.z with a semantic version number)
|
||||
* or `poetry version {patch/minor/major}` (see https://python-poetry.org/docs/cli/#version)
|
||||
* Git commit and git push
|
||||
* Create a new version tag on GitLab (e.g. V2.6.11)
|
||||
* Make sure you prefix a lower case 'v', otherwise it won't be recognised as a release!
|
||||
* This tagging will trigger a CI pipeline that builds the JS client, tarballs up the server, and deploys it
|
||||
* Note: This also updates the build server's nginx redirect map file
|
||||
|
||||
## Local installation
|
||||
|
||||
The Raspberry Pi image we use currently ships with Python 3.7.3. For local development, please use PyEnv or similar to make sure you're running on this version. For example, Windows users can use [Scoop](https://scoop.sh/) to install specific Python versions.
|
||||
The Raspberry Pi image we use currently ships with Python 3.7.3. For local development on a different platform, please use PyEnv or similar to make sure you're running on this version. For example, Windows users can use [Scoop](https://scoop.sh/) to install specific Python versions. This repository contains two closely related parts; a web server written in Python, that handles hardware control, and a web application using Vue.js that provides a graphical control interface. It is possible to work on either of these in isolation, but bear in mind that if you only set up Python development, you will need to host the web application elsewhere.
|
||||
|
||||
Most of our core team don't run the Javascript development on the Raspberry Pi, as npm can be quite slow to build the application. Instead, we set up the Python part of the project on a Raspberry Pi, and run the Javascript part on your development machine. You can then connect to the web application served from your local machine, and enter the address of the Raspberry Pi when the interface first loads.
|
||||
|
||||
To set up a development version of the software (most likely using emulated camera and stage if you're not running on a Raspberry Pi):
|
||||
|
||||
### Clone the repository
|
||||
* `git clone https://gitlab.com/openflexure/openflexure-microscope-server.git`
|
||||
|
|
@ -52,18 +45,19 @@ The Raspberry Pi image we use currently ships with Python 3.7.3. For local devel
|
|||
* `pyenv init` (this may or may not be required, depending on how you installed `pyenv`)
|
||||
* `pyenv install 3.7.3`
|
||||
* `pyenv local 3.7.3`
|
||||
* Ensure you have a working installation of `poetry` (see the [Poetry website](https://python-poetry.org/)).
|
||||
* We usually set up `poetry` to place virtual environments in the project directory, as this is more easily detected by editors, including VSCode. To do this, you can run:
|
||||
* ``poetry config virtualenvs.in-project true`` will use a folder called ``.venv`` rather than keeping your environments in a central location.
|
||||
* `poetry install` will install the server, and all dependencies, into the virtual environment. This step can take a while, especially on the Pi, bring a cup of tea!
|
||||
* Create a virtual environment and activate it:
|
||||
* `python -m venv .venv`
|
||||
* `source .venv/bin/activate` (on Linux) or `.venv/Scripts/activate` (on Windows)
|
||||
* `pip install pipenv`
|
||||
* `pipenv install --dev` (This will install development dependencies. If you don't need these, `pipenv install` will get you just the dependencies needed to run the server, which takes about half the time.)
|
||||
* Finally, run the server:
|
||||
* You can use `ofm serve` or `ofm restart` on the Raspberry Pi to manage the server.
|
||||
* To run the server locally, with dummy hardware, you can use ``poetry run python -m openflexure_microscope.api.app`` to start a development-mode Flask server on ``localhost:5000``
|
||||
* To run the server locally, with dummy hardware, you can use `python -m openflexure_microscope.api.app` to start a development-mode Flask server on `localhost:5000`
|
||||
|
||||
### Set up the Javascript environment and build
|
||||
* The Flask web application, written in Python, serves a web application written in ``Vue.js``. This is distributed as part of the built version of the server, hosted on our [build server](https://build.openflexure.org/openflexure-microscope-server/).
|
||||
* The Flask web application, written in Python, serves a web application written in `Vue.js`. This is distributed as part of the built version of the server, hosted on our [build server](https://build.openflexure.org/openflexure-microscope-server/).
|
||||
* You could extract the pre-built web app from this tarball, which saves you having to set up Node.js. However, it also means you're not able to change the interface, and it's possible your interface will get out of sync with your server.
|
||||
* Building the web interface will require a valid Node.js installation. If you don't have Node.js (including ``npm``) the [Node.js website](https://nodejs.org/en/) offers downloads for all platforms, though see the instructions below for Raspberry Pi.
|
||||
* Building the web interface will require a valid Node.js installation. If you don't have Node.js (including `npm`) the [Node.js website](https://nodejs.org/en/) offers downloads for all platforms, though see the instructions below for Raspberry Pi.
|
||||
* To install Node.js on a Raspberry Pi:
|
||||
* `curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -`
|
||||
* `sudo apt install nodejs`
|
||||
|
|
@ -73,29 +67,25 @@ The Raspberry Pi image we use currently ships with Python 3.7.3. For local devel
|
|||
* `npm run build`
|
||||
* To create a Node.js development server (this will help various development tools to display more information, and auto-rebuilds when you change the source files)
|
||||
* `npm run serve`
|
||||
* You access the development server on a different port (it's printed on the command line when you run the above command). This means that when it starts up you will need to tell it where the microscope server is, using the "override API origin" field in the page that pops up. If you are running a test server on your computer, this is most likely ``http://localhost:5000/``.
|
||||
* You access the development server on a different port (it's printed on the command line when you run the above command). This means that when it starts up you will need to tell it where the microscope server is, using the "override API origin" field in the page that pops up. If you are running a test server on your computer, this is most likely `http://localhost:5000/`.
|
||||
|
||||
## Formatting, linting, and tests
|
||||
All of the commands below assume that you are running in the OFM virtual environment, i.e. you have run `ofm activate` on an OpenFlexure SD card, or `source .venv/bin/activate` on Linux, or `.venv/Scripts/activate`on Windows.
|
||||
|
||||
### Tl;dr
|
||||
**Before committing** you should auto-format your code:
|
||||
|
||||
**Before committing**
|
||||
|
||||
* To auto-format the Python code run `poetry run poe format`
|
||||
* To auto-format the Python code run `poe format`
|
||||
* To auto-format the Javascript code, run
|
||||
* ``cd openflexure_microscope/api/static``
|
||||
* ``npm run lint``
|
||||
* `cd openflexure_microscope/api/static`
|
||||
* `npm run lint`
|
||||
|
||||
Auto-formats the code
|
||||
**Before submitting a merge request/merging** please auto-format your code and also run the quality checks (linting, static analysis, and unit tests)
|
||||
|
||||
**Before submitting a merge request/merging**
|
||||
|
||||
* To auto-format and type-check the Python code run `poetry run poe check`
|
||||
* To auto-format and type-check the Python code run `poe check`
|
||||
* To auto-format the Javascript code, run
|
||||
* ``cd openflexure_microscope/api/static``
|
||||
* ``npm run lint``
|
||||
* `cd openflexure_microscope/api/static`
|
||||
* `npm run lint`
|
||||
|
||||
Formats code, lints, runs static analysis, and runs unit tests.
|
||||
|
||||
### Details
|
||||
|
||||
|
|
@ -106,28 +96,45 @@ Our CI will check each of these automatically, so ensuring they pass locally wil
|
|||
* **Black** - Code formatting with minimal configuration.
|
||||
* While sometimes it's not perfect, its fine 90% of the time and prevents arguments about formatting.
|
||||
* Automatically formats your code
|
||||
* `poetry run poe black`
|
||||
* This will rewrite your files in-place, so if you want to be able to revert, make a backup first!
|
||||
* `poe black`
|
||||
* **Pylint** - Static code analysis
|
||||
* Analyses your code, failing if issues are detected.
|
||||
* We've disabled some less severe warnings, so _if anything fails your merge request will be blocked_
|
||||
* `poetry run poe pylint`
|
||||
* `poe pylint`
|
||||
* **Mypy** - Type checking
|
||||
* Analyses your type hints and annotations to flag up potential bugs
|
||||
* Where possible, use type hints in your code. Even if dependencies don't support it, it'll help identify issues.
|
||||
* `poetry run poe mypy`
|
||||
* `poe mypy`
|
||||
* **Pytest** - Unit testing
|
||||
* While unit testing is of limited use due to our dependence on real hardware, some simple isolated functions can (and should) be unit tested.
|
||||
* `poetry run poe test`
|
||||
* `poe test`
|
||||
|
||||
Though not in the CI, our `format` script also runs isort:
|
||||
|
||||
* **Isort** - Import sorting
|
||||
* Automatically organises your imports to stop things getting out of hand
|
||||
* `poetry run poe isort`
|
||||
* `poe isort`
|
||||
|
||||
## Build-system
|
||||
## Python environment, build, and dependencies
|
||||
|
||||
As of 1.0.0b0, we're using [Poetry](https://github.com/sdispater/poetry) to manage dependencies, build, and distribute the package. All package information and dependencies are found in `pyproject.toml`, in line with [PEP 518](https://www.python.org/dev/peps/pep-0518/). If you're developing this package, make use of `poetry.lock` to ensure you're using the latest locked dependency list.
|
||||
As of `2.10.0b0` we have switched to using `pipenv` for managing dependencies, and a standard `setuptools` based build system. See "local installation" above for instructions on how to install the project. Earlier versions of the project used `poetry` but we moved away because of [difficulties](https://gitlab.com/openflexure/openflexure-microscope-server/-/merge_requests/124) getting it to work both on the Raspberry Pi and in our CI pipeline. The new arrangement for configuration files is:
|
||||
|
||||
* Dependencies, and dev-dependencies, are specified in `setup.py` in the usual way (using `install_requires` and `extra_requires[dev]`).
|
||||
* Package metadata is specified in `setup.py` in the usual way.
|
||||
* `pyproject.toml` is retained, but *no longer includes package metadata or dependencies* and does not have a `[tool.poetry]` table. It does define the build system as per PEP517, which is `setuptools`, and it also contains settings for `black`, `poe` and `isort`.
|
||||
* `Pipfile` is very minimal, and only declares dependencies on the current module, i.e. the dependencies declared in `setup.py`. It also specifies the Python version. This allows us to single-source dependency information from `setup.py` but use the dependency resolution/locking functionality of `pipenv`
|
||||
* `Pipfile.lock` locks the dependency versions in the same way as `poetry.lock` used to, i.e. it specifies exact versions of everything, derived from the looser specifications in `setup.py`.
|
||||
|
||||
## Creating releases
|
||||
|
||||
* Update the application's internal version number
|
||||
* Edit `setup.py` to update the version number
|
||||
* Git commit and git push
|
||||
* Create a new version tag on GitLab (e.g. `v2.6.11`)
|
||||
* Make sure you prefix a lower case 'v', otherwise it won't be recognised as a release!
|
||||
* This tagging will trigger a CI pipeline that builds the JS client, tarballs up the server, and deploys it
|
||||
* Note: This also updates the build server's nginx redirect map file
|
||||
|
||||
## Changelog generation
|
||||
|
||||
|
|
@ -137,3 +144,4 @@ As of 1.0.0b0, we're using [Poetry](https://github.com/sdispater/poetry) to mana
|
|||
## Microscope extensions
|
||||
|
||||
The Microscope module, and Flask app, both support plugins for extending lower-level functionality not well suited to web API calls. The current documentation can be found [here](https://openflexure-microscope-software.readthedocs.io/en/latest/plugins.html).
|
||||
If you want to add functions to the microscope software, this is probably the best mechanism to use if it works for you.
|
||||
|
|
|
|||
|
|
@ -218,10 +218,16 @@ def cleanup():
|
|||
|
||||
atexit.register(cleanup)
|
||||
|
||||
# Start the app
|
||||
if __name__ == "__main__":
|
||||
|
||||
def ofm_serve():
|
||||
# Start a debug server
|
||||
from labthings import Server
|
||||
|
||||
logging.info("Starting OpenFlexure Microscope Server...")
|
||||
server: Server = Server(app)
|
||||
server.run(host="0.0.0.0", port=5000, debug=debug_app, zeroconf=True)
|
||||
|
||||
|
||||
# Start the app if the module is run directly
|
||||
if __name__ == "__main__":
|
||||
ofm_serve()
|
||||
|
|
|
|||
|
|
@ -127,20 +127,20 @@ def monitor_sharpness(microscope: Microscope):
|
|||
m.stop()
|
||||
|
||||
|
||||
def sharpness_sum_lap2(rgb_image: np.ndarray) -> np.float:
|
||||
def sharpness_sum_lap2(rgb_image: np.ndarray) -> float:
|
||||
"""Return an image sharpness metric: sum(laplacian(image)**")"""
|
||||
image_bw: np.float = np.mean(rgb_image, 2)
|
||||
image_lap: np.float = ndimage.filters.laplace(image_bw)
|
||||
return np.mean(image_lap.astype(np.float) ** 4)
|
||||
image_bw = np.mean(rgb_image, 2)
|
||||
image_lap = ndimage.filters.laplace(image_bw)
|
||||
return float(np.mean(image_lap.astype(float) ** 4))
|
||||
|
||||
|
||||
def sharpness_edge(image: np.ndarray) -> np.float:
|
||||
def sharpness_edge(image: np.ndarray) -> float:
|
||||
"""Return a sharpness metric optimised for vertical lines"""
|
||||
gray: np.float = np.mean(image.astype(float), 2)
|
||||
gray = np.mean(image.astype(float), 2)
|
||||
n: int = 20
|
||||
edge: np.ndarray = np.array([[-1] * n + [1] * n])
|
||||
return np.sum(
|
||||
[np.sum(ndimage.filters.convolve(gray, W) ** 2) for W in [edge, edge.T]]
|
||||
return float(
|
||||
np.sum([np.sum(ndimage.filters.convolve(gray, W) ** 2) for W in [edge, edge.T]])
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ class AutofocusExtension(BaseExtension):
|
|||
|
||||
def measure_sharpness(
|
||||
self, microscope: Microscope, metric_fn: Callable = sharpness_sum_lap2
|
||||
) -> np.float:
|
||||
) -> float:
|
||||
"""Measure the sharpness of the camera's current view."""
|
||||
|
||||
if hasattr(microscope.camera, "array") and callable(
|
||||
|
|
@ -185,7 +185,7 @@ class AutofocusExtension(BaseExtension):
|
|||
dz: List[int],
|
||||
settle: float = 0.5,
|
||||
metric_fn: Callable = sharpness_sum_lap2,
|
||||
) -> Tuple[List[int], List[np.float]]:
|
||||
) -> Tuple[List[int], List[float]]:
|
||||
"""Perform a simple autofocus routine.
|
||||
The stage is moved to z positions (relative to current position) in dz,
|
||||
and at each position an image is captured and the sharpness function
|
||||
|
|
@ -197,7 +197,7 @@ class AutofocusExtension(BaseExtension):
|
|||
stage: BaseStage = microscope.stage
|
||||
|
||||
with set_properties(stage, backlash=256), stage.lock, camera.lock:
|
||||
sharpnesses: List[np.float] = []
|
||||
sharpnesses: List[float] = []
|
||||
positions: List[int] = []
|
||||
|
||||
# Some cameras may not have annotate_text. Reset if it does
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ def lst_from_channels(channels: np.ndarray) -> np.ndarray:
|
|||
|
||||
logging.info("Generating a lens shading table at %sx%s", *lst_resolution)
|
||||
lens_shading: np.ndarray = np.zeros(
|
||||
[channels.shape[0]] + lst_resolution, dtype=np.float
|
||||
[channels.shape[0]] + lst_resolution, dtype=float
|
||||
)
|
||||
for i in range(lens_shading.shape[0]):
|
||||
image_channel: np.ndarray = channels[i, :, :]
|
||||
|
|
@ -297,7 +297,7 @@ def recalibrate_camera(camera: PiCamera):
|
|||
_ = rgb_image(camera)
|
||||
|
||||
# Fix the AWB gains so the image is neutral
|
||||
channel_means = np.mean(np.mean(rgb_image(camera), axis=0, dtype=np.float), axis=0)
|
||||
channel_means = np.mean(np.mean(rgb_image(camera), axis=0, dtype=float), axis=0)
|
||||
old_gains = camera.awb_gains
|
||||
camera.awb_gains = (
|
||||
channel_means[1] / channel_means[0] * old_gains[0],
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ export default {
|
|||
stride_size: [800, 600, 10],
|
||||
fast_autofocus: true,
|
||||
autofocus_dz: 2000,
|
||||
style: "raster",
|
||||
use_video_port: false
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ class JSONEncoder(LabThingsJSONEncoder):
|
|||
# Numpy integers
|
||||
elif isinstance(o, np.integer):
|
||||
return int(o)
|
||||
# Numpy floats
|
||||
elif isinstance(o, np.float):
|
||||
# Numpy floats are just Python floats
|
||||
elif isinstance(o, float):
|
||||
return float(o)
|
||||
# Numpy arrays
|
||||
elif isinstance(o, np.ndarray):
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class MissingStage(BaseStage):
|
|||
)
|
||||
displacement = move
|
||||
|
||||
initial_move = np.array(displacement, dtype=np.int)
|
||||
initial_move = np.array(displacement, dtype=np.integer)
|
||||
|
||||
self._position = list(np.array(self._position) + np.array(initial_move))
|
||||
logging.debug(np.array(self._position) + np.array(initial_move))
|
||||
|
|
|
|||
|
|
@ -277,13 +277,11 @@ class SangaDeltaStage(SangaStage):
|
|||
logging.debug(self.R_camera)
|
||||
|
||||
# Transformation matrix converting delta into cartesian
|
||||
x_fac: np.float = -1 * np.multiply(
|
||||
x_fac: float = -1 * np.multiply(
|
||||
np.divide(2, np.sqrt(3)), np.divide(self.flex_b, self.flex_h)
|
||||
)
|
||||
y_fac: np.float = -1 * np.divide(self.flex_b, self.flex_h)
|
||||
z_fac: np.float = np.multiply(
|
||||
np.divide(1, 3), np.divide(self.flex_b, self.flex_a)
|
||||
)
|
||||
y_fac: float = -1 * np.divide(self.flex_b, self.flex_h)
|
||||
z_fac: float = np.multiply(np.divide(1, 3), np.divide(self.flex_b, self.flex_a))
|
||||
|
||||
self.Tvd: np.ndarray = np.array(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -1,81 +1,17 @@
|
|||
[build-system]
|
||||
requires = ["poetry>=0.12"]
|
||||
build-backend = "poetry.masonry.api"
|
||||
requires = ["setuptools", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.poetry]
|
||||
name = "openflexure-microscope-server"
|
||||
version = "2.9.3"
|
||||
description = "Python module, and Flask-based web API, to run the OpenFlexure Microscope."
|
||||
|
||||
authors = [
|
||||
"Joel Collins <j.collins@bath.ac.uk>",
|
||||
"Richard Bowman <r.w.bowman@bath.ac.uk",
|
||||
"Julian Stirling <j.stirling@bath.ac.uk>"
|
||||
]
|
||||
|
||||
readme = 'README.md'
|
||||
|
||||
repository = "https://gitlab.com/openflexure/openflexure-microscope-server"
|
||||
homepage = "https://www.openflexure.org"
|
||||
|
||||
keywords = ['raspberry pi', 'arduino', 'microscope']
|
||||
|
||||
license = "GPL-3.0"
|
||||
|
||||
exclude = ["**/node_modules/"]
|
||||
|
||||
packages = [
|
||||
{ include = "openflexure_microscope" },
|
||||
]
|
||||
|
||||
# Installing numpy/scipy/etc. from source is unlikely to work.
|
||||
# The block below forces Poetry to use piwheels.
|
||||
# We can add other repositories if we need them.
|
||||
# Setting default=true disables fallback to PyPI. I have removed
|
||||
# this for now, because it will prevent installation on non-Pi
|
||||
# platforms.
|
||||
|
||||
[[tool.poetry.source]]
|
||||
name = "piwheels"
|
||||
url = "https://www.piwheels.org/simple"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7.3"
|
||||
Flask = "^1.0"
|
||||
# let scipy specify numpy?? numpy = "1.19.2" # Exact version so we can guarantee a wheel
|
||||
Pillow = "^7.2.0"
|
||||
scipy = "^1.6.1" # Exact version so we can guarantee a wheel
|
||||
"RPi.GPIO" = { version = "^0.7.0", optional = true }
|
||||
python-dateutil = "^2.8"
|
||||
psutil = "^5.6.7" # Autostorage extension
|
||||
opencv-python-headless = "4.5.1.48"
|
||||
sangaboard = "^0.2"
|
||||
expiringdict = "^1.2.1"
|
||||
camera-stage-mapping = "0.1.4"
|
||||
picamerax = ">=20.9.1"
|
||||
pyyaml = "^5.4.0" # pyyaml 5.4.1 is broken in piwheels
|
||||
pytest-cov = "^2.10.1"
|
||||
piexif = "^1.1.3"
|
||||
labthings = "^1.2.2"
|
||||
typing-extensions = "^3.7.4" # Needed for some type-hints in Python < 3.8 (e.g. Literal)
|
||||
numpy-stubs = {git = "https://github.com/numpy/numpy-stubs.git"} # Needed for Numpy < 1.20
|
||||
|
||||
[tool.poetry.extras]
|
||||
rpi = ["RPi.GPIO"]
|
||||
|
||||
[tool.poetry.scripts]
|
||||
rescue = 'openflexure_microscope.rescue.auto:main'
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
sphinxcontrib-httpdomain = "^1.7"
|
||||
rope = "^0.14.0"
|
||||
pylint = "^2.3"
|
||||
black = {version = "^18.3-alpha.0",allow-prereleases = true}
|
||||
pytest = "^6.1.2"
|
||||
mypy = "^0.790"
|
||||
poethepoet = "^0.9.0"
|
||||
freezegun = "^1.0.0"
|
||||
lxml = "^4.6.2" # Fix version so piwheels works
|
||||
# The [tool.poetry] metadata has been removed from this file, because
|
||||
# we have switched to Pipenv for dependency management and setuptools
|
||||
# for the build system. All metadata has been moved either to
|
||||
# Pipfile or setup.py.
|
||||
# The one key that doesn't map over nicely is the exclusion of
|
||||
# the node_modules folder, i.e. the line below:
|
||||
#exclude = ["**/node_modules/"] # I've tried to put this in the "packages" key but not sure it works.
|
||||
# I have left it here in case we ever switch back to Poetry, but I
|
||||
# don't believe it's critical at present, because we don't use
|
||||
# the Python package - we distribute a tarball directly.
|
||||
|
||||
[tool.black]
|
||||
exclude = '(\.eggs|\.git|\.venv|\venv|node_modules/)'
|
||||
|
|
@ -92,6 +28,10 @@ line_length = 88
|
|||
disable = "fixme,C,R"
|
||||
max-line-length = 88
|
||||
|
||||
[tool.poe.executor]
|
||||
type = "virtualenv"
|
||||
location = ".venv"
|
||||
|
||||
[tool.poe.tasks]
|
||||
black = "black ."
|
||||
black_check = "black --check ."
|
||||
|
|
|
|||
94
setup.py
Normal file
94
setup.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
"""A setuptools based setup module for the OpenFlexure Microscope server
|
||||
|
||||
This file was prepared according to:
|
||||
https://packaging.python.org/guides/distributing-packages-using-setuptools/
|
||||
|
||||
|
||||
"""
|
||||
|
||||
# the following imports, from the guide above, prefer `setuptools` to `distutils`
|
||||
from setuptools import setup, find_packages
|
||||
from os import path
|
||||
|
||||
here = path.abspath(path.dirname(__file__))
|
||||
|
||||
# Get the long description from the README file
|
||||
with open(path.join(here, "README.md"), encoding="utf-8") as f:
|
||||
long_description = f.read()
|
||||
|
||||
# Not all arguments to `setup()` are required for upload to PyPI.
|
||||
# See the tutorial linked to at the top for which ones are needed.
|
||||
|
||||
setup(
|
||||
name="openflexure-microscope-server",
|
||||
version="2.10.0b0",
|
||||
description="Python module, and Flask-based web API, to run the OpenFlexure Microscope.",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://www.openflexure.org", # "home-page" metadata field
|
||||
author="Joel Collins, Richard Bowman, Julian Stirling",
|
||||
author_email="contact@openflexure.org",
|
||||
# For a list of valid classifiers, see https://pypi.org/classifiers/
|
||||
# NB declaring Python versions here doesn't affect dependency resolution - it's for info only.
|
||||
classifiers=["License :: OSI Approved :: GNU General Public License v3 (GPLv3)"],
|
||||
keywords="raspberry pi arduino microscope", # Optional
|
||||
packages=find_packages(exclude=["contrib", "docs", "tests", "*node_modules*"]),
|
||||
python_requires="== 3.7.*",
|
||||
# This field lists other packages that your project depends on to run.
|
||||
# Any package you put here will be installed by pip when your project is
|
||||
# installed, so they must be valid existing projects.
|
||||
#
|
||||
# These dependencies specify relatively flexible versions; Pipenv then resolves these
|
||||
# to specific versions, and locks those versions in ``Pipfile``. Usually, when you
|
||||
# set up the project for development, you use those specific packages, rather than
|
||||
# the looser specifications given here.
|
||||
install_requires=[
|
||||
"Flask ~= 1.0",
|
||||
"Pillow ~= 7.2.0",
|
||||
"numpy ~= 1.20",
|
||||
"scipy ~= 1.6.1",
|
||||
"python-dateutil ~= 2.8",
|
||||
"psutil ~= 5.6.7", # Autostorage extension
|
||||
"opencv-python-headless ~= 4.5.1",
|
||||
"sangaboard ~= 0.2",
|
||||
"expiringdict ~= 1.2.1",
|
||||
"camera-stage-mapping == 0.1.4",
|
||||
"picamerax ~= 20.9.1",
|
||||
"pyyaml ~= 5.4.0",
|
||||
"pytest-cov ~= 2.10.1",
|
||||
"piexif ~= 1.1.3",
|
||||
"labthings ~= 1.2.2",
|
||||
"typing-extensions ~= 3.7.4", # Needed for some type-hints in Python < 3.8 (e.g. Literal)
|
||||
"RPi.GPIO ~= 0.7.0; platform_machine == 'armv7l'",
|
||||
],
|
||||
# "dev" specifies extra packages used for development (linting, testing, etc.)
|
||||
# As with install_requires, these are relatively loose versions - Pipfile will then lock
|
||||
# them to specific versions to enable consistent builds and testing.
|
||||
extras_require={
|
||||
"dev": [
|
||||
"sphinxcontrib-httpdomain ~= 1.7",
|
||||
"rope ~= 0.14.0",
|
||||
"pylint ~= 2.3",
|
||||
"pytest ~= 6.1.2",
|
||||
"mypy ~= 0.790",
|
||||
"poethepoet ~= 0.10.0",
|
||||
"freezegun ~= 1.0.0",
|
||||
"lxml ~= 4.6",
|
||||
"black == 18.9b0", # Because black is in prerelease, giving a flexible version
|
||||
# specifier causes all manner of problems. A fixed version
|
||||
# avoids issues with prereleases (which are normally not
|
||||
# allowed by pipenv) but can be a bit of a pain sometimes!
|
||||
]
|
||||
},
|
||||
dependency_links=[],
|
||||
# We create some "entry points" to make it easier to run important modules
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"ofm-serve=openflexure_microscope.api.app:ofm_serve",
|
||||
"ofm-rescue=openflexure_microscope.rescue.auto:main",
|
||||
]
|
||||
},
|
||||
project_urls={
|
||||
"Source": "https://gitlab.com/openflexure/openflexure-microscope-server"
|
||||
},
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue