|
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") |
@@ -622,7 +623,7 @@ def register_image_stack( |
622 | 623 | "/sessions/{session_id}/clem/preprocessing/process_raw_lifs" |
623 | 624 | ) # API posts to this URL |
624 | 625 | def process_raw_lifs( |
625 | | - session_id: int, # Used by the decorator |
| 626 | + session_id: int, |
626 | 627 | lif_file: Path, |
627 | 628 | db: Session = murfey_db, |
628 | 629 | ): |
@@ -654,9 +655,15 @@ def process_raw_lifs( |
654 | 655 | return True |
655 | 656 |
|
656 | 657 |
|
| 658 | +class TIFFSeriesInfo(BaseModel): |
| 659 | + series_name: str |
| 660 | + tiff_files: list[Path] |
| 661 | + series_metadata: Path |
| 662 | + |
| 663 | + |
657 | 664 | @router.post("/sessions/{session_id}/clem/preprocessing/process_raw_tiffs") |
658 | 665 | def process_raw_tiffs( |
659 | | - session_id: int, # Used by the decorator |
| 666 | + session_id: int, |
660 | 667 | tiff_info: TIFFSeriesInfo, |
661 | 668 | db: Session = murfey_db, |
662 | 669 | ): |
@@ -687,3 +694,72 @@ def process_raw_tiffs( |
687 | 694 | messenger=_transport_object, |
688 | 695 | ) |
689 | 696 | return True |
| 697 | + |
| 698 | + |
| 699 | +class AlignAndMergeParams(BaseModel): |
| 700 | + # Processing parameters |
| 701 | + series_name: str |
| 702 | + images: list[Path] |
| 703 | + metadata: Path |
| 704 | + # Optional processing parameters |
| 705 | + crop_to_n_frames: Optional[int] = None |
| 706 | + align_self: Literal["enabled", ""] = "" |
| 707 | + flatten: Literal["mean", "min", "max", ""] = "" |
| 708 | + align_across: Literal["enabled", ""] = "" |
| 709 | + |
| 710 | + @validator( |
| 711 | + "images", |
| 712 | + pre=True, |
| 713 | + ) |
| 714 | + def parse_stringified_list(cls, value): |
| 715 | + if isinstance(value, str): |
| 716 | + try: |
| 717 | + eval_result = literal_eval(value) |
| 718 | + if isinstance(eval_result, list): |
| 719 | + parent_tiffs = [Path(p) for p in eval_result] |
| 720 | + return parent_tiffs |
| 721 | + except (SyntaxError, ValueError): |
| 722 | + raise ValueError("Unable to parse input") |
| 723 | + # Return value as-is; if it fails, it fails |
| 724 | + return value |
| 725 | + |
| 726 | + |
| 727 | +@router.post("/sessions/{session_id}/clem/processing/align_and_merge_stacks") |
| 728 | +def align_and_merge_stacks( |
| 729 | + session_id: int, |
| 730 | + align_and_merge_params: AlignAndMergeParams, |
| 731 | + db: Session = murfey_db, |
| 732 | +): |
| 733 | + try: |
| 734 | + # Try and load relevant Murfey workflow |
| 735 | + workflow: EntryPoint = list( |
| 736 | + entry_points().select(group="murfey.workflows", name="clem.align_and_merge") |
| 737 | + )[0] |
| 738 | + except IndexError: |
| 739 | + raise RuntimeError("The relevant Murfey workflow was not found") |
| 740 | + |
| 741 | + # Get instrument name from the database to load the correct config file |
| 742 | + session_row: MurfeySession = db.exec( |
| 743 | + select(MurfeySession).where(MurfeySession.id == session_id) |
| 744 | + ).one() |
| 745 | + instrument_name = session_row.instrument_name |
| 746 | + |
| 747 | + # Pass arguments to correct workflow |
| 748 | + workflow.load()( |
| 749 | + # Match the arguments found in murfey.workflows.clem.align_and_merge |
| 750 | + # Session parameters |
| 751 | + session_id=session_id, |
| 752 | + instrument_name=instrument_name, |
| 753 | + # Processing parameters |
| 754 | + series_name=align_and_merge_params.series_name, |
| 755 | + images=align_and_merge_params.images, |
| 756 | + metadata=align_and_merge_params.metadata, |
| 757 | + # Optional processing parameters |
| 758 | + crop_to_n_frames=align_and_merge_params.crop_to_n_frames, |
| 759 | + align_self=align_and_merge_params.align_self, |
| 760 | + flatten=align_and_merge_params.flatten, |
| 761 | + align_across=align_and_merge_params.align_across, |
| 762 | + # Optional session parameters |
| 763 | + messenger=_transport_object, |
| 764 | + ) |
| 765 | + return True |
0 commit comments