Source code for napari_dmc_brainmap.params.params

"""
DMC-BrainMap widget for creating params.json file.

params.json is used to track experimental parameters for animals
and maintain a history of preprocessing operations performed.

2024 - FJ, XC
"""

# Import modules
import json
from pathlib import Path
from typing import Optional

from napari_dmc_brainmap.utils.params_utils import clean_params_dict, update_params_dict
from napari_dmc_brainmap.utils.general_utils import get_animal_id
from napari_dmc_brainmap.utils.dropdown_utils import get_atlas_dropdown
from napari_dmc_brainmap.utils.atlas_utils import get_xyz
from qtpy.QtWidgets import QPushButton, QWidget, QVBoxLayout, QMessageBox
from magicgui import magicgui
from magicgui.widgets import FunctionGui
from bg_atlasapi import BrainGlobeAtlas
from napari.utils.notifications import show_info
from napari_dmc_brainmap.utils.gui_utils import check_input_path


[docs] def initialize_widget() -> FunctionGui: """ Initialize the params widget for creating experimental parameter files. Returns: FunctionGui: A widget for user input fields to collect experimental parameters. """ @magicgui(layout='vertical', input_path=dict(widget_type='FileEdit', label='Input Path (animal_id): ', mode='d', tooltip='Directory containing subfolders with raw data, images, or segmentation results.'), inj_side=dict(widget_type='ComboBox', label='Injection Site', choices=['', 'left', 'right'], value='', tooltip='Select the injection hemisphere (if applicable).'), geno=dict(widget_type='LineEdit', label='Genotype', tooltip='Enter the genotype of the animal (if applicable).'), group=dict(widget_type='LineEdit', label='Experimental Group', tooltip='Enter the experimental group of the animal (if applicable).'), chans_imaged=dict(widget_type='Select', label='Imaged Channels', choices=['dapi', 'green', 'n3', 'cy3', 'cy5'], value=['green', 'cy3'], tooltip='Select all imaged channels. Use ctrl/shift for multiple selections.'), section_orient=dict(widget_type='ComboBox', label='Orientation of Sectioning', choices=['coronal', 'sagittal', 'horizontal'], value='coronal', tooltip='Select the brain slicing orientation.'), atlas=dict(label='Reference Atlas', tooltip='Select the reference atlas for registration.'), call_button=False) def params_widget(input_path: Path, inj_side: str, geno: str, group: str, chans_imaged: list, section_orient: str, atlas: get_atlas_dropdown()): """ Create the params widget for collecting experimental parameter inputs. Parameters: input_path (Path): Path to the folder containing experimental data. inj_side (str): Injection hemisphere ('left', 'right', or ''). geno (str): Genotype of the animal. group (str): Experimental group of the animal. chans_imaged (list): Channels imaged during the experiment. section_orient (str): Orientation of sectioning (coronal, sagittal, horizontal). atlas (Enum): Reference atlas used for registration. """ pass return params_widget
[docs] class ParamsWidget(QWidget): """ QWidget for creating the params.json file for an experiment. """ def __init__(self, napari_viewer): """ Initialize the ParamsWidget. Parameters: napari_viewer: The napari viewer instance where the widget will be added. """ super().__init__() self.viewer = napari_viewer self.setLayout(QVBoxLayout()) self.params = initialize_widget() btn = QPushButton("Create params.json File") btn.clicked.connect(self._create_params_file) self.layout().addWidget(self.params.native) self.layout().addWidget(btn) def _create_params_file(self) -> None: """ Create the params.json file based on user input and save it to the specified location. """ input_path: Optional[Path] = self.params.input_path.value # Check if user provided a valid input_path if not check_input_path(input_path): return animal_id = get_animal_id(input_path) injection_site = self.params.inj_side.value genotype = self.params.geno.value group = self.params.group.value chans_imaged = self.params.chans_imaged.value atlas_name = self.params.atlas.value.value orientation = self.params.section_orient.value try: show_info(f'Checking existence of local version of {atlas_name} atlas...') show_info(f'Loading reference atlas {atlas_name}...') atlas = BrainGlobeAtlas(atlas_name) xyz_dict = get_xyz(atlas, orientation) resolution_tuple = (xyz_dict['x'][1], xyz_dict['y'][1]) # Basic structure of params.json dictionary params_dict = { "general": { "animal_id": animal_id, "injection_site": injection_site, "genotype": genotype, "group": group, "chans_imaged": chans_imaged }, "atlas_info": { "atlas": atlas_name, "orientation": orientation, "resolution": resolution_tuple, 'xyz_dict': xyz_dict } } # Clean params dictionary to remove empty keys params_dict = clean_params_dict(params_dict, "general") params_fn = input_path / 'params.json' params_dict = update_params_dict(input_path, params_dict, create=True) with open(params_fn, 'w') as fn: json.dump(params_dict, fn, indent=4) msg_box = QMessageBox() msg_box.setIcon(QMessageBox.Information) msg_box.setText(f"params.json file for {animal_id} created successfully!") msg_box.setWindowTitle("Success") msg_box.exec_() except Exception as e: # Show an error message box if any error occurs msg_box = QMessageBox() msg_box.setIcon(QMessageBox.Critical) msg_box.setText(f"An error occurred: {str(e)}") msg_box.setWindowTitle("Processing Error") msg_box.exec_()