diff --git a/frontend/src/components/Workspace/Visualize/VisualizeItem.tsx b/frontend/src/components/Workspace/Visualize/VisualizeItem.tsx index b37df80aa..8f9b03332 100644 --- a/frontend/src/components/Workspace/Visualize/VisualizeItem.tsx +++ b/frontend/src/components/Workspace/Visualize/VisualizeItem.tsx @@ -36,7 +36,7 @@ import { selectVisualizeDataFilePath, selectVisualizeDataNodeId, selectVisualizeDataType, - selectVisualizeImageItemIdList, + selectVisualizeImageAndRoiItemIdList, selectVisualizeItemHeight, selectVisualizeItemWidth, } from "store/slice/VisualizeItem/VisualizeItemSelectors" @@ -262,7 +262,7 @@ const RefImageItemIdSelect = memo(function RefImageItemIdSelect({ }: ItemIdProps) { const dispatch = useDispatch() const itemIdList = useSelector( - selectVisualizeImageItemIdList, + selectVisualizeImageAndRoiItemIdList, arrayEqualityFn, ) const onChangeRefImageItemId = (event: SelectChangeEvent) => { diff --git a/frontend/src/store/slice/VisualizeItem/VisualizeItemSelectors.ts b/frontend/src/store/slice/VisualizeItem/VisualizeItemSelectors.ts index 4bdd26f51..6feed9a3e 100644 --- a/frontend/src/store/slice/VisualizeItem/VisualizeItemSelectors.ts +++ b/frontend/src/store/slice/VisualizeItem/VisualizeItemSelectors.ts @@ -16,6 +16,7 @@ import { isHistogramItem, isLineItem, isPolarItem, + isRoiItem, } from "store/slice/VisualizeItem/VisualizeItemUtils" import { RootState } from "store/store" @@ -30,6 +31,14 @@ export const selectVisualizeImageItemIdList = (state: RootState) => return isImageItem(item) && !item.isWorkflowDialog }) +export const selectVisualizeImageAndRoiItemIdList = (state: RootState) => + Object.keys(state.visualaizeItem.items) + .map(Number) + .filter((itemId) => { + const item = selectVisualizeItemById(itemId)(state) + return !item.isWorkflowDialog && (isImageItem(item) || isRoiItem(item)) + }) + export const selectVisualizeItems = (state: RootState) => state.visualaizeItem.items diff --git a/studio/app/optinist/wrappers/optinist/visualize_utils/__init__.py b/studio/app/optinist/wrappers/optinist/visualize_utils/__init__.py index b6fe779b4..07629afea 100644 --- a/studio/app/optinist/wrappers/optinist/visualize_utils/__init__.py +++ b/studio/app/optinist/wrappers/optinist/visualize_utils/__init__.py @@ -4,6 +4,9 @@ from studio.app.optinist.wrappers.optinist.visualize_utils.microscope_to_img import ( microscope_to_img, ) +from studio.app.optinist.wrappers.optinist.visualize_utils.roi_fluo_from_hdf5 import ( + roi_fluo_from_hdf5, +) from studio.app.optinist.wrappers.optinist.visualize_utils.roi_from_hdf5 import ( roi_from_hdf5, ) @@ -21,4 +24,8 @@ "function": roi_from_hdf5, "conda_name": "optinist", }, + "roi_fluo_from_hdf5": { + "function": roi_fluo_from_hdf5, + "conda_name": "optinist", + }, } diff --git a/studio/app/optinist/wrappers/optinist/visualize_utils/params/roi_fluo_from_hdf5.yaml b/studio/app/optinist/wrappers/optinist/visualize_utils/params/roi_fluo_from_hdf5.yaml new file mode 100644 index 000000000..e16c76dff --- /dev/null +++ b/studio/app/optinist/wrappers/optinist/visualize_utils/params/roi_fluo_from_hdf5.yaml @@ -0,0 +1 @@ +"" diff --git a/studio/app/optinist/wrappers/optinist/visualize_utils/roi_fluo_from_hdf5.py b/studio/app/optinist/wrappers/optinist/visualize_utils/roi_fluo_from_hdf5.py new file mode 100644 index 000000000..3d9de2291 --- /dev/null +++ b/studio/app/optinist/wrappers/optinist/visualize_utils/roi_fluo_from_hdf5.py @@ -0,0 +1,70 @@ +import numpy as np + +from studio.app.common.core.logger import AppLogger +from studio.app.common.dataclass.image import ImageData +from studio.app.optinist.dataclass.fluo import FluoData +from studio.app.optinist.dataclass.iscell import IscellData +from studio.app.optinist.dataclass.roi import RoiData + + +def roi_fluo_from_hdf5( + cell_img: ImageData, + fluo: FluoData, + output_dir: str, + iscell: IscellData = None, + params: dict = None, + **kwargs, +) -> dict(): + """ + Processes ROI and fluorescence data, aligning them, and adds enriched metadata. + + Parameters: + cell_img (ImageData): Cell image data containing ROI information. + fluo (FluoData): Fluorescence data. + output_dir (str): Directory to save the output data. + iscell (IscellData): Binary data indicating cell regions (optional). + params (dict): Optional parameters for additional processing. + **kwargs: Additional keyword arguments. + + Returns: + dict: A dictionary containing processed ROI and fluorescence data. + """ + logger = AppLogger.get_logger() + logger.info("Starting ROI and fluorescence data processing") + + # Base output data + all_roi = RoiData( + np.nanmax(cell_img.data, axis=0), output_dir=output_dir, file_name="all_roi" + ) + fluorescence = FluoData(np.transpose(fluo.data), file_name="fluorescence") + + if iscell is None: + return {"all_roi": all_roi, "fluorescence": fluorescence} + + # Extract iscell data + iscell_data = iscell.data + + # Process ROI types + non_cell_roi = RoiData( + np.nanmax(cell_img.data[np.where(iscell_data == 0)], axis=0), + output_dir=output_dir, + file_name="noncell_roi", + ) + + cell_roi = RoiData( + np.nanmax(cell_img.data[np.where(iscell_data != 0)], axis=0), + output_dir=output_dir, + file_name="cell_roi", + ) + + # Construct output dictionary + output = { + "iscell": IscellData(iscell_data, file_name="iscell"), + "all_roi": all_roi, + "non_cell_roi": non_cell_roi, + "cell_roi": cell_roi, + "fluorescence": fluorescence, + } + + logger.info("Completed ROI and fluorescence data processing") + return output