Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add endpoints for LIF to TIFF conversion #267

Merged
merged 84 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
bb5370f
Included explanation (with source) for why setup() is to be kept as-is.
Apr 4, 2024
16eaa73
Updated 'extras_require' section to include dependency options for cl…
Apr 4, 2024
f6ee2ed
Ported over settings from setup.cfg, allowing pyproject.toml to be us…
Apr 4, 2024
012fe1a
Added entry to search pyproject.toml file for version number and repl…
Apr 4, 2024
3f11daa
Ported flake8 entries from setup.cfg to pyproject.toml for completene…
tieneupin Apr 4, 2024
aa0f43b
Updated repos to latest stable versions (with links to where to find …
tieneupin Apr 4, 2024
6f6eaa5
Added Flake8-pyproject as a Flake8 dependency in the pre-commit-confi…
tieneupin Apr 5, 2024
2d670b8
Merge branch 'main' into setup-update
tieneupin Apr 5, 2024
a207ac8
Additional comments about potentially using Ruff as a long-term bridg…
tieneupin Apr 5, 2024
08b0188
Included link to documentation for .yaml formatting, and explanation …
tieneupin Apr 5, 2024
e600c7c
Addressed potential error identified by mypy: TransportManager could …
tieneupin Apr 5, 2024
59ce6d2
Addressed potential error found by mypy: Module murfey.client.tui has…
tieneupin Apr 5, 2024
ff3440d
Snapshot of environment before testing Ruff with pre-commit.
tieneupin Apr 5, 2024
86d834c
Modified settings to test ruff with.
tieneupin Apr 5, 2024
f47b950
Updated black and ruff settings in pre-commit-config and pyproject.to…
tieneupin Apr 8, 2024
d5e4a08
Reverted pre-commit settings to pre-ruff ones.
tieneupin Apr 8, 2024
2019169
Added key to disable non-error messages for MyPy checks.
tieneupin Apr 8, 2024
4da2677
Merge branch 'main' of github.com:DiamondLightSource/python-murfey in…
tieneupin Apr 8, 2024
6a51ea9
Mutiple files defining MyPy configuration settings. Standardised MyPy…
tieneupin Apr 8, 2024
c619b36
Updated pre-commit settings to install missing library stubs, ignore …
tieneupin Apr 8, 2024
0fa8dfa
Added more pre-commit hooks, improved printed messages.
tieneupin Apr 8, 2024
e56ca73
Install a stomp-py version below the most recent to stop workflows pi…
d-j-hatton Apr 8, 2024
7254b37
Try to avoid CodeQL complaint of mixed implicit and explicit returns …
d-j-hatton Apr 8, 2024
a7166a5
Updated installation requirements. stomp-py 8.1.1 breaks the package.…
tieneupin Apr 8, 2024
1e20821
Fixed type hinting syntax, using Python 3.9-comptable variant.
tieneupin Apr 8, 2024
7f6759c
Phased out setup.cfg now that pyproject.toml has been tested and conf…
tieneupin Apr 8, 2024
b6ef64e
Merged collaborative changes to branch.
tieneupin Apr 8, 2024
c2eab66
Reverted deletion of setup.cfg.
tieneupin Apr 8, 2024
db74639
Need flake8-pyproject for toml support
d-j-hatton Apr 8, 2024
8708441
Remove old setup files
d-j-hatton Apr 8, 2024
1d46b63
setup.py is back
d-j-hatton Apr 8, 2024
f2b8a21
Missing await
d-j-hatton Apr 8, 2024
6744e33
Updated comments to reflect current state of project.
tieneupin Apr 8, 2024
c5f98bd
Removed bump2version's search for setup.cfg, since we have committed …
tieneupin Apr 8, 2024
a68934a
Added pre-commit hook to restructure pyproject.toml file, along with …
tieneupin Apr 8, 2024
26b67a4
Disabled pyproject-fmt pre-commit hook. Formatting was too harsh, and…
tieneupin Apr 9, 2024
055df00
Moved 'werkzeug' to mandatory dependencies list, as it was found in b…
tieneupin Apr 9, 2024
f49eeb9
Re-enabled pyproject-fmt after experimenting with other TOML formatte…
tieneupin Apr 9, 2024
291b057
Merged changes from main branch. Bumped to version 0.11.8
tieneupin Apr 9, 2024
6e12353
Removed setup.cfg that was added after merge.
tieneupin Apr 9, 2024
a9b009b
Snapshot of environment before testing Prettier formatter.
tieneupin Apr 10, 2024
ace3b10
Rearranged order of pre-commit hooks. Tidied up comments and formatting.
tieneupin Apr 10, 2024
5bcb28f
Formatted files using Prettier pre-commit hook.
tieneupin Apr 10, 2024
3f47ff0
Merged recent updates from main branch.
tieneupin Apr 17, 2024
dd2825e
Removed setup.cfg introduced by merge.
tieneupin Apr 17, 2024
e1f637e
Created utility Python script to process .lif files for cryo-CLEM wor…
tieneupin Apr 17, 2024
7779bcb
Added cryo-CLEM file-related dependencies to developer section of pyp…
tieneupin Apr 17, 2024
fd80854
Created placeholder file for unit tests for lif.py.
tieneupin Apr 17, 2024
f3d6856
Added placeholder function to lif.py
tieneupin Apr 17, 2024
e742707
Merged changes from updated main branch
tieneupin Apr 18, 2024
07e1fc3
Wrote functions to inspect and reconstruct contents of .lif files
tieneupin Apr 18, 2024
f516e78
Experimenting with python-bioformats and readlif modules
tieneupin Apr 19, 2024
5d42ede
Investigating using built-in XML tools to handle .lif files
tieneupin Apr 19, 2024
2c9737c
Added functions to extract and save LIF file metadata as a formatted …
tieneupin Apr 22, 2024
92b9350
Added placeholder function for LIF image data extraction
tieneupin Apr 22, 2024
765a849
Phasing out python-bioformats due to lack of development on one of it…
tieneupin Apr 23, 2024
fea6e7d
Investigating effectiveness of readlif, bioio, and pyimagej for readi…
tieneupin Apr 24, 2024
4ff2097
Tidied up miscellaneous files from research into LIF plugins
tieneupin Apr 25, 2024
31b573f
Merge branch 'main' of github.com:DiamondLightSource/python-murfey in…
tieneupin Apr 25, 2024
c1398ac
Snapshot of progress on LIF to TIFF conversion
tieneupin Apr 26, 2024
76a2707
Added functions to rescale intensity distribution in channels as needed
tieneupin Apr 29, 2024
7f59d17
Wrote function to save individual channels from sub-images in LIF fil…
tieneupin Apr 30, 2024
b65a40b
Applied pre-commit corrections
tieneupin Apr 30, 2024
149d13a
Adjusted bit depth rescaling algorithms; addd more comments
tieneupin Apr 30, 2024
f676956
Merge remote-tracking branch 'origin' into cryo-clem-integration
tieneupin May 7, 2024
32f9d92
Updated XML parsing to recursively search for image metadata
tieneupin May 7, 2024
66f52ea
Merging recent changes from main branch
tieneupin May 7, 2024
57dfba9
Updated descriptions of functions and tidied up comments
tieneupin May 8, 2024
d31ee96
Added files needed for Murfey to process cryo-CLEM data
tieneupin May 8, 2024
8bab8f6
Applied pre-commit corrections
tieneupin May 8, 2024
7e241fc
Merge branch 'main' of github.com:DiamondLightSource/python-murfey in…
tieneupin May 8, 2024
b8522aa
Merged recent updates from main branch
tieneupin May 8, 2024
853a8aa
Updated dependencies for continuous integration tests
tieneupin May 9, 2024
063980b
Added pytest-cov back to CI dependencies list
tieneupin May 9, 2024
366beae
Allowed CLEM context to detect LIF files and get necessary variables …
tieneupin May 9, 2024
1a67b1d
If LIF files are seen then register as cryoCLEM context
d-j-hatton May 9, 2024
578c2fb
Get file sizes and timestamps
d-j-hatton May 9, 2024
6f4ebeb
Merged recent changes from main branch
tieneupin May 9, 2024
23c55e5
Used type hinting language compatible with Python 3.9
tieneupin May 9, 2024
a8f7e00
Merged recent changes to main branch
tieneupin May 9, 2024
25f79fb
Remove requirements_dev.txt
d-j-hatton May 9, 2024
5a3acf0
Explicit returns
d-j-hatton May 9, 2024
8dfcc95
Cleaner
d-j-hatton May 9, 2024
745ba29
Protection against log injection
d-j-hatton May 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ cicd = [
]
clem = [
# "matplotlib", # For visual statistical analysis of images
"readlif", # cryo-CLEM; open LIF files; part of bioio-lif
"readlif", # cryo-CLEM; open LIF files
"tifffile", # cryo-CLEM; for saving to to TIFF files
]
client = [
Expand Down
14 changes: 13 additions & 1 deletion src/murfey/client/analyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import Type

from murfey.client.context import Context
from murfey.client.contexts.clem import CLEMContext
from murfey.client.contexts.spa import SPAContext, SPAModularContext
from murfey.client.contexts.spa_metadata import SPAMetadataContext
from murfey.client.contexts.tomo import TomographyContext
Expand Down Expand Up @@ -92,8 +93,14 @@ def _find_extension(self, file_path: Path):
):
logger.info(f"File extension re-evaluated: {file_path.suffix}")
self._extension = file_path.suffix
elif file_path.suffix == ".lif":
self._extension = file_path.suffix

def _find_context(self, file_path: Path) -> bool:
if file_path.suffix == ".lif":
self._role = "detector"
self._context = CLEMContext("leica", self._basepath)
return True
split_file_name = file_path.name.split("_")
if split_file_name:
if split_file_name[0].startswith("FoilHole"):
Expand Down Expand Up @@ -333,7 +340,12 @@ def _analyse(self):
)
elif isinstance(
self._context,
(TomographyContext, SPAModularContext, SPAMetadataContext),
(
TomographyContext,
SPAModularContext,
SPAMetadataContext,
CLEMContext,
),
):
self.post_transfer(transferred_file)
self.queue.task_done()
Expand Down
107 changes: 107 additions & 0 deletions src/murfey/client/contexts/clem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""
Add a CLEM class context (refer to src/murfey/client/contexts/fib.py)

Provide a post transfer function to pass on:
- File path on the DLS file system
- Session ID (src/murfey/client/instance_environment.py)
"""

# import requests
import logging
from pathlib import Path
from typing import Optional

from murfey.client.context import Context
from murfey.client.instance_environment import MurfeyInstanceEnvironment
from murfey.util import capture_post, get_machine_config

# Create logger object
logger = logging.getLogger("murfey.client.contexts.clem")


def _file_transferred_to(
environment: MurfeyInstanceEnvironment, source: Path, file_path: Path
) -> Optional[Path]:
machine_config = get_machine_config(
str(environment.url.geturl()), demo=environment.demo
)
if environment.visit in environment.default_destinations[source]:
return (
Path(machine_config.get("rsync_basepath", ""))
/ Path(environment.default_destinations[source])
/ file_path.relative_to(source)
)
return (
Path(machine_config.get("rsync_basepath", ""))
/ Path(environment.default_destinations[source])
/ environment.visit
/ file_path.relative_to(source)
)


def _get_source(
file_path: Path, environment: MurfeyInstanceEnvironment
) -> Optional[Path]:
for s in environment.sources:
if file_path.is_relative_to(s):
return s
return None


class CLEMContext(Context):
def __init__(self, acquisition_software: str, basepath: Path):
super().__init__("CLEM", acquisition_software)
self._basepath = basepath

def post_transfer(
self,
transferred_file: Path,
role: str = "",
environment: Optional[MurfeyInstanceEnvironment] = None,
**kwargs,
) -> bool:
super().post_transfer(
transferred_file, role=role, environment=environment, **kwargs
)
# Check if file is a LIF file
if transferred_file.suffix == ".lif":
# Type checking to satisfy MyPy
if not environment:
logger.warning("No environment passed in")
return True

# Location of the file on the client PC
source = _get_source(transferred_file, environment)
# Type checking to satisfy MyPy
if not source:
logger.warning(f"No source found for file {transferred_file}")
return True

# Construct the URL for the Murfey server to communicate with
url = f"{str(environment.url.geturl())}/sessions/{environment.murfey_session}/lif_to_tiff"
# Type checking to satisfy MyPy
if not url:
logger.warning("No url found for the environment")
return True

# Get the Path on the DLS file system
file_path = _file_transferred_to(
environment=environment,
source=source,
file_path=transferred_file,
)

# Get the file size and timestamp from transferred_file
# Client PC cannot see file_path; that is for server PC

# Post the message and logs it if there's an error
capture_post(
url,
json={
"name": str(file_path),
"size": transferred_file.stat().st_size,
"timestamp": transferred_file.stat().st_ctime,
"description": "",
},
)
return True
Empty file.
18 changes: 18 additions & 0 deletions src/murfey/server/clem/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from __future__ import annotations

from fastapi import APIRouter

from murfey.util.lif import convert_lif_to_tiff
from murfey.util.models import LifFileInfo

# Create APIRouter class object
router = APIRouter()


# Allow function to be seen as an endpoint by the router
@router.post("/sessions/{session_id}/lif_to_tiff")
def lif_to_tiff(
session_id: int, # Used by the decorator
lif_info: LifFileInfo,
):
convert_lif_to_tiff(file=lif_info.name)
7 changes: 5 additions & 2 deletions src/murfey/server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import murfey.server
import murfey.server.bootstrap
import murfey.server.clem.api
import murfey.server.websocket
import murfey.util.models
from murfey.server import template_files

Expand Down Expand Up @@ -48,13 +50,14 @@ class Settings(BaseSettings):
app.mount("/static", StaticFiles(directory=template_files / "static"), name="static")
app.mount("/images", StaticFiles(directory=template_files / "images"), name="images")

# Add router endpoints to the API
app.include_router(router)
app.include_router(murfey.server.bootstrap.bootstrap)
app.include_router(murfey.server.bootstrap.cygwin)
app.include_router(murfey.server.bootstrap.pypi)
app.include_router(murfey.server.bootstrap.plugins)
app.include_router(murfey.server.clem.api.router)
app.include_router(murfey.server.websocket.ws)

app.include_router(router)

for r in importlib_metadata.entry_points(group="murfey.routers"):
app.include_router(r.load())
4 changes: 3 additions & 1 deletion src/murfey/util/lif.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from readlif.reader import LifFile
from tifffile import imwrite

from murfey.server.api import sanitise

# Create logger object to output messages with
logger = logging.getLogger("murfey.util.lif")

Expand Down Expand Up @@ -245,7 +247,7 @@ def convert_lif_to_tiff(file: Path):
logger.info(f"{folder} already exists")

# Load LIF file as a LifFile class
logger.info(f"Loading {file}")
logger.info(f"Loading {sanitise(file.name)}")
lif_file = LifFile(str(file)) # Stack of scenes
scene_list = list(lif_file.get_iter_image()) # List of scene names

Expand Down
7 changes: 7 additions & 0 deletions src/murfey/util/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ class File(BaseModel):
timestamp: float


class LifFileInfo(BaseModel):
name: Path
size: int
timestamp: float
description: str = ""


class SPAProcessingParameters(BaseModel):
job_id: int

Expand Down