|
2 | 2 |
|
3 | 3 | import re |
4 | 4 | import traceback |
| 5 | +from ast import literal_eval |
5 | 6 | from importlib.metadata import EntryPoint # type hinting only |
6 | 7 | from logging import getLogger |
7 | 8 | from pathlib import Path |
8 | | -from typing import Optional, Type, Union |
| 9 | +from typing import Literal, Optional, Type, Union |
9 | 10 |
|
10 | 11 | from backports.entry_points_selectable import entry_points |
11 | 12 | from fastapi import APIRouter |
| 13 | +from pydantic import BaseModel, validator |
12 | 14 | from sqlalchemy.exc import NoResultFound |
13 | 15 | from sqlmodel import Session, select |
14 | 16 |
|
|
23 | 25 | CLEMTIFFFile, |
24 | 26 | ) |
25 | 27 | from murfey.util.db import Session as MurfeySession |
26 | | -from murfey.util.models import TIFFSeriesInfo |
27 | 28 |
|
28 | 29 | # Set up logger |
29 | 30 | logger = getLogger("murfey.server.api.clem") |
@@ -624,7 +625,7 @@ def register_image_stack( |
624 | 625 | "/sessions/{session_id}/clem/preprocessing/process_raw_lifs" |
625 | 626 | ) # API posts to this URL |
626 | 627 | def process_raw_lifs( |
627 | | - session_id: int, # Used by the decorator |
| 628 | + session_id: int, |
628 | 629 | lif_file: Path, |
629 | 630 | db: Session = murfey_db, |
630 | 631 | ): |
@@ -656,9 +657,15 @@ def process_raw_lifs( |
656 | 657 | return True |
657 | 658 |
|
658 | 659 |
|
| 660 | +class TIFFSeriesInfo(BaseModel): |
| 661 | + series_name: str |
| 662 | + tiff_files: list[Path] |
| 663 | + series_metadata: Path |
| 664 | + |
| 665 | + |
659 | 666 | @router.post("/sessions/{session_id}/clem/preprocessing/process_raw_tiffs") |
660 | 667 | def process_raw_tiffs( |
661 | | - session_id: int, # Used by the decorator |
| 668 | + session_id: int, |
662 | 669 | tiff_info: TIFFSeriesInfo, |
663 | 670 | db: Session = murfey_db, |
664 | 671 | ): |
@@ -689,3 +696,72 @@ def process_raw_tiffs( |
689 | 696 | messenger=_transport_object, |
690 | 697 | ) |
691 | 698 | return True |
| 699 | + |
| 700 | + |
| 701 | +class AlignAndMergeParams(BaseModel): |
| 702 | + # Processing parameters |
| 703 | + series_name: str |
| 704 | + images: list[Path] |
| 705 | + metadata: Path |
| 706 | + # Optional processing parameters |
| 707 | + crop_to_n_frames: Optional[int] = None |
| 708 | + align_self: Literal["enabled", ""] = "" |
| 709 | + flatten: Literal["mean", "min", "max", ""] = "" |
| 710 | + align_across: Literal["enabled", ""] = "" |
| 711 | + |
| 712 | + @validator( |
| 713 | + "images", |
| 714 | + pre=True, |
| 715 | + ) |
| 716 | + def parse_stringified_list(cls, value): |
| 717 | + if isinstance(value, str): |
| 718 | + try: |
| 719 | + eval_result = literal_eval(value) |
| 720 | + if isinstance(eval_result, list): |
| 721 | + parent_tiffs = [Path(p) for p in eval_result] |
| 722 | + return parent_tiffs |
| 723 | + except (SyntaxError, ValueError): |
| 724 | + raise ValueError("Unable to parse input") |
| 725 | + # Return value as-is; if it fails, it fails |
| 726 | + return value |
| 727 | + |
| 728 | + |
| 729 | +@router.post("/sessions/{session_id}/clem/processing/align_and_merge_stacks") |
| 730 | +def align_and_merge_stacks( |
| 731 | + session_id: int, |
| 732 | + align_and_merge_params: AlignAndMergeParams, |
| 733 | + db: Session = murfey_db, |
| 734 | +): |
| 735 | + try: |
| 736 | + # Try and load relevant Murfey workflow |
| 737 | + workflow: EntryPoint = list( |
| 738 | + entry_points().select(group="murfey.workflows", name="clem.align_and_merge") |
| 739 | + )[0] |
| 740 | + except IndexError: |
| 741 | + raise RuntimeError("The relevant Murfey workflow was not found") |
| 742 | + |
| 743 | + # Get instrument name from the database to load the correct config file |
| 744 | + session_row: MurfeySession = db.exec( |
| 745 | + select(MurfeySession).where(MurfeySession.id == session_id) |
| 746 | + ).one() |
| 747 | + instrument_name = session_row.instrument_name |
| 748 | + |
| 749 | + # Pass arguments to correct workflow |
| 750 | + workflow.load()( |
| 751 | + # Match the arguments found in murfey.workflows.clem.align_and_merge |
| 752 | + # Session parameters |
| 753 | + session_id=session_id, |
| 754 | + instrument_name=instrument_name, |
| 755 | + # Processing parameters |
| 756 | + series_name=align_and_merge_params.series_name, |
| 757 | + images=align_and_merge_params.images, |
| 758 | + metadata=align_and_merge_params.metadata, |
| 759 | + # Optional processing parameters |
| 760 | + crop_to_n_frames=align_and_merge_params.crop_to_n_frames, |
| 761 | + align_self=align_and_merge_params.align_self, |
| 762 | + flatten=align_and_merge_params.flatten, |
| 763 | + align_across=align_and_merge_params.align_across, |
| 764 | + # Optional session parameters |
| 765 | + messenger=_transport_object, |
| 766 | + ) |
| 767 | + return True |
0 commit comments