{"name":"napari-resview","display_name":"Resview","visibility":"public","icon":null,"categories":[],"schema_version":"0.3.0","on_activate":null,"on_deactivate":null,"contributions":{"commands":[{"id":"napari-resview.make_resview_widget","title":"Resview","python_name":"napari_resview.resview_widget:ResviewDockWidget","short_title":null,"category":null,"icon":null,"enablement":null}],"readers":null,"writers":null,"widgets":[{"command":"napari-resview.make_resview_widget","display_name":"Resview","autogenerate":false}],"sample_data":null,"themes":null,"menus":{"napari/layers/segment":[{"command":"napari-resview.make_resview_widget","when":null,"group":null,"alt":null}]},"submenus":null,"keybindings":null,"configurations":{}},"package_metadata":{"metadata_version":"2.4","name":"napari-resview","version":"0.1.6","dynamic":["license-file"],"platform":null,"supported_platform":null,"summary":"A napari plugin for 3D reciprocal space mapping","description":"# napari-resview\n\n[![License BSD-3](https://img.shields.io/pypi/l/napari-resview.svg?color=green)](https://github.com/XYangXRay/napari-resview/raw/main/LICENSE)\n[![PyPI](https://img.shields.io/pypi/v/napari-resview.svg?color=green)](https://pypi.org/project/napari-resview)\n[![Python Version](https://img.shields.io/pypi/pyversions/napari-resview.svg?color=green)](https://python.org)\n[![tests](https://github.com/XYangXRay/napari-resview/workflows/tests/badge.svg)](https://github.com/XYangXRay/napari-resview/actions)\n[![codecov](https://codecov.io/gh/XYangXRay/napari-resview/branch/main/graph/badge.svg)](https://codecov.io/gh/XYangXRay/napari-resview)\n[![napari hub](https://img.shields.io/endpoint?url=https://api.napari-hub.org/shields/napari-resview)](https://napari-hub.org/plugins/napari-resview)\n[![npe2](https://img.shields.io/badge/plugin-npe2-blue?link=https://napari.org/stable/plugins/index.html)](https://napari.org/stable/plugins/index.html)\n[![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-purple.json)](https://github.com/copier-org/copier)\n\n**A tool of 3D reciprocal space mapping (RSM) for X-ray diffraction experiments with interactive data processing, visualization and analysis built on Napari platfom.**\n\n---\n\n## Installation\n\nYou can install `napari-resview` via [pip]:\n\n```\npip install napari-resview\n```\n\nIf napari is not already installed, you can install `napari-resview` with napari and Qt via:\n\n```\npip install \"napari-resview[all]\"\n```\n\nTo install latest development version:\n\n```\npip install git+https://github.com/XYangXRay/napari-resview.git\n```\n\n---\n\n## Overview\n\n`napari-resview` is a comprehensive processing, visualization and analysis tool designed for synchrotron X-ray diffraction experiments. Built as a [napari] plugin, it enables researchers to interactively explore, process, and visualize 3D reciprocal space maps with advanced features for data loading, ROI selection, and crystallographic analysis.\n\n### Key Features\n\n- **📊 3D Visualization**: Interactive 3D rendering of reciprocal space maps using napari's powerful volume rendering\n- **✂️ ROI-Based Cropping**: Define and apply regions of interest with visual feedback\n- **🏗️ RSM Construction Pipeline**: Complete workflow from raw SPEC/TIFF data to 3D reciprocal space\n- **📐 UB Matrix Management**: Tools for orientation matrix setup, refinement, and validation\n- **⚡ Asynchronous Processing**: Non-blocking data loading with progress tracking\n- **💾 Multiple Export Formats**: Export to VTR (VTK) format for use with ParaView and other tools\n- **🎛️ Profile-Based Workflow**: Save and restore experimental configurations\n- **📈 Real-time Data Integration**: Merge SPEC metadata with TIFF intensity frames on-the-fly\n\n### Use Cases\n\n- **Synchrotron Beamline Analysis**: Real-time and offline data processing at NSLS-II beamlines\n- **Crystal Structure Studies**: Reciprocal space reconstruction for structural analysis\n- **Strain Mapping**: Analyze crystal strain and deformation through reciprocal space features\n- **Quality Control**: Quick visualization and validation of diffraction data quality\n- **Research & Education**: Interactive tool for teaching crystallography and X-ray diffraction concepts\n\n---\n\n## Quick Start\n\n### Launching the Plugin\n\nAfter installation, launch napari and open the ResView widget:\n\n```bash\nnapari\n```\n\nThen in napari: **Plugins → napari-resview: ResView Widget**\n\n### Basic Workflow\n\n1. **Configure Loader Profile**\n\n   - Select beamline profile (ISR or CMS)\n   - If ISR beamline, specify SPEC file, setup YAML, and TIFF directory\n   - If CMS beamline, specify rotation angles\n   - Configure any additional loader parameters\n2. **Load Data**\n\n   - Click \"Load\" to asynchronously load and merge data\n   - Monitor progress in the status panel\n   - View intensity frames in the napari viewer\n3. **Apply ROI Cropping (Optional)**\n\n   - Draw ROI shapes on the intensity viewer\n   - Click \"Crop from ROI\" to apply cropping\n   - Cropped data is used for all subsequent operations\n4. **Build RSM**\n\n   - Configure UB matrix parameters\n   - Set resolution and bounds\n   - Click \"Build\" to construct reciprocal space map\n5. **Visualize**\n\n   - Adjust visualization settings (colormap, opacity, contrast)\n   - Add grid overlays and axis markers\n   - Export slices or subvolumes\n6. **Export**\n\n   - Save RSM volume to .tiff, .npz, or .vtr format as you like\n   - Export for use in ParaView or other visualization tools\n\n---\n\n## Detailed Usage\n\n### Data Loading\n\nThe plugin supports two main beamline configurations:\n\n#### ISR Loader\n\n```python\nfrom napari_resview.data_io import RSMDataLoader_ISR\n\nloader = RSMDataLoader_ISR(\n    spec_file=\"path/to/scan.spec\",\n    setup_file=\"path/to/setup.yaml\",\n    tiff_dir=\"path/to/tiff_images/\",\n    use_dask=False,\n    process_hklscan_only=True,\n    selected_scans=[21, 22, 23]\n)\nsetup, ub, df = loader.load()\n```\n\n#### CMS Loader\n\n```python\nfrom napari_resview.data_io import RSMDataloader_CMS\n\nloader = RSMDataloader_CMS(\n    spec_file=\"path/to/scan.spec\",\n    setup_file=\"path/to/setup.yaml\",\n    ub_file=\"path/to/ub.txt\",\n    use_dask=False\n)\nsetup, ub, df = loader.load()\n```\n\n### Building Reciprocal Space Maps\n\n```python\nfrom napari_resview.rsm3d import RSMBuilder\n\n# Initialize builder with loaded data\nbuilder = RSMBuilder(\n    setup,\n    ub,\n    df,\n    ub_includes_2pi=True,\n    center_is_one_based=False\n)\n\n# Build RSM with specified resolution and bounds\nrsm_grid, rsm_axes = builder.build(\n    resolution=200,\n    bounds={'qx': (-2, 2), 'qy': (-2, 2), 'qz': (-2, 2)}\n)\n```\n\n### Visualization\n\n```python\nfrom napari_resview.data_viz import RSMNapariViewer\nimport napari\n\n# Create viewer\nrsm_viewer = RSMNapariViewer(\n    grid=rsm_grid,\n    axes=rsm_axes,\n    axes_names=['qx', 'qy', 'qz']\n)\n\n# Launch in napari\nviewer = rsm_viewer.launch()\n\n# Add grid overlay\nrsm_viewer.add_grid_overlay(step=0.5, viewer=viewer)\n```\n\n### Configuration Files\n\n#### Setup YAML Example\n\n```yaml\nbeamline: ISR\nenergy: 10.0  # keV\nwavelength: 1.2398  # Angstroms\ndetector:\n  pixel_size: 55e-6  # meters\n  distance: 0.5  # meters\n  beam_center: [257, 515]\n  size: [514, 1030]\nangles:\n  omega: 0.0\n  chi: 90.0\n  phi: 0.0\n  tth: 20.0\n```\n\n#### Profile Persistence\n\nThe plugin automatically saves and restores your configuration in `rsm3d_defaults.yaml`, including:\n\n- Active profile (ISR/CMS)\n- File paths and directories\n- UB matrix values\n- Resolution and bounds settings\n- Visualization preferences\n\n---\n\n## Key Components\n\n### Data I/O (`data_io.py`)\n\n- `RSMDataLoader_ISR`: Load ISR beamline SPEC + TIFF data\n- `RSMDataloader_CMS`: Load CMS beamline data with HDF5 support\n- `ExperimentSetup`: Manage experimental configuration\n- `write_rsm_volume_to_vtr()`: Export RSM to VTK format\n\n### RSM Builder (`rsm3d.py`)\n\n- `RSMBuilder`: Construct 3D reciprocal space maps from experimental data\n- Supports xrayutilities coordinate transformations\n- Flexible motor mapping and axis configuration\n- Gridding and interpolation options\n\n### Visualization (`data_viz.py`)\n\n- `RSMNapariViewer`: 3D volume rendering of RSM\n- `IntensityNapariViewer`: 2D intensity frame viewer with ROI tools\n- Grid overlays and coordinate displays\n- Interactive slice extraction\n\n### Widget (`resview_widget.py`)\n\n- `ResviewDockWidget`: Main napari dock widget\n- Tabbed interface: Data, Build, View, Export\n- Profile management with YAML persistence\n- Asynchronous data loading with progress tracking\n\n---\n\n## API Reference\n\n### Main Classes\n\n#### RSMDataLoader_ISR\n\n```python\nloader = RSMDataLoader_ISR(\n    spec_file: str,          # Path to SPEC file\n    setup_file: str,         # Path to setup YAML\n    tiff_dir: str,           # Directory containing TIFF images\n    use_dask: bool = False,  # Use Dask for large datasets\n    process_hklscan_only: bool = False,  # Filter hklscan only\n    selected_scans: list = None  # List of scan numbers to process\n)\nsetup, ub, df = loader.load()\n```\n\n#### RSMBuilder\n\n```python\nbuilder = RSMBuilder(\n    setup,                   # ExperimentSetup object\n    UB,                      # UB orientation matrix (3x3)\n    df,                      # DataFrame with intensity data\n    ub_includes_2pi: bool = True,  # UB includes 2π factor\n    center_is_one_based: bool = False,  # Beam center indexing\n    sample_axes: list = None,  # xrayutilities sample axes\n    detector_axes: list = None  # xrayutilities detector axes\n)\n\ngrid, axes = builder.build(\n    resolution: int = 200,   # Grid resolution\n    bounds: dict = None      # {'qx': (min, max), 'qy': (min, max), 'qz': (min, max)}\n)\n```\n\n#### RSMNapariViewer\n\n```python\nviewer = RSMNapariViewer(\n    grid: np.ndarray,        # 3D intensity array\n    axes,                    # Coordinate axes (list of 3 arrays)\n    axes_names: list = ['qx', 'qy', 'qz']  # Axis labels\n)\n\nnapari_viewer = viewer.launch()  # Open in napari\nviewer.add_grid_overlay(step=0.5, viewer=napari_viewer)\nviewer.add_slices(positions={'qx': 0, 'qy': 0, 'qz': 0})\n```\n\n---\n\n## Development\n\n### Setting Up Development Environment\n\n```bash\ngit clone https://github.com/NSLS2/napari-resview.git\ncd napari-resview\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=napari_resview --cov-report=html\n\n# Run specific test file\npytest tests/test_resview_widget.py\n```\n\n### Code Quality\n\n```bash\n# Format code with black\nblack src/\n\n# Sort imports\nisort src/\n\n# Type checking\nmypy src/\n```\n\n### Using tox\n\nThe project includes tox configuration for automated testing:\n\n```bash\n# Run all tox environments\ntox\n\n# Run specific environment\ntox -e py310\n```\n\n---\n\n## Contributing\n\nContributions are very welcome! We appreciate bug reports, feature requests, documentation improvements, and code contributions.\n\n### How to Contribute\n\n1. **Fork the repository** on GitHub\n2. **Clone your fork** locally:\n   ```bash\n   git clone https://github.com/YOUR_USERNAME/napari-resview.git\n   cd napari-resview\n   ```\n3. **Create a branch** for your changes:\n   ```bash\n   git checkout -b feature/your-feature-name\n   ```\n4. **Make your changes** and add tests if applicable\n5. **Run tests** to ensure everything works:\n   ```bash\n   pytest\n   ```\n6. **Commit your changes** with clear commit messages:\n   ```bash\n   git commit -m \"Add: description of your changes\"\n   ```\n7. **Push to your fork**:\n   ```bash\n   git push origin feature/your-feature-name\n   ```\n8. **Submit a pull request** on GitHub\n\n### Contribution Guidelines\n\n- Follow PEP 8 style guidelines\n- Add tests for new features\n- Update documentation as needed\n- Ensure the test coverage stays the same or improves\n- Write clear commit messages\n- Keep pull requests focused on a single feature or fix\n\n### Reporting Issues\n\nIf you encounter bugs or have feature requests, please [file an issue] with:\n\n- A clear, descriptive title\n- Steps to reproduce (for bugs)\n- Expected vs. actual behavior\n- Your environment (OS, Python version, napari version)\n- Relevant error messages or screenshots\n\n---\n\n## Troubleshooting\n\n### Common Issues\n\n**Plugin doesn't appear in napari menu**\n\n- Ensure napari-resview is installed in the same environment as napari\n- Restart napari after installation\n- Check: `napari --plugin-info` to verify plugin is detected\n\n**Data loading fails**\n\n- Verify file paths are correct\n- Check that TIFF files match SPEC scan numbers\n- Ensure setup YAML has correct format\n- Review error messages in napari's terminal/console\n\n**Memory errors with large datasets**\n\n- Enable `use_dask=True` for lazy loading\n- Reduce resolution in Build settings\n- Apply ROI cropping to reduce data size\n- Close other memory-intensive applications\n\n**Visualization appears empty or black**\n\n- Adjust contrast limits in napari layer controls\n- Check data range with `print(grid.min(), grid.max())`\n- Ensure data is non-zero\n- Try different colormaps or opacity settings\n\n**UB matrix errors**\n\n- Verify UB matrix dimensions (3×3)\n- Check `ub_includes_2pi` setting matches your data\n- Ensure proper motor mapping in configuration\n\n### Getting Help\n\n- Check the [napari documentation](https://napari.org/stable/)\n- Browse [existing issues](https://github.com/NSLS2/napari-resview/issues)\n- Ask questions in napari [community forum](https://forum.image.sc/tag/napari)\n- Contact the development team at yangxg@bnl.gov\n\n---\n\n## Citation\n\nIf you use napari-resview in your research, please cite:\n\n```bibtex\n@software{napari_resview,\n  title = {napari-resview: A napari plugin for 3D reciprocal space mapping},\n  author = {Yang, Xiaogang and contributors},\n  year = {2024},\n  url = {https://github.com/NSLS2/napari-resview},\n  note = {Developed at Brookhaven National Laboratory, NSLS-II}\n}\n```\n\nAlso consider citing the underlying tools:\n\n- [napari](https://napari.org/): Multi-dimensional image viewer\n- [xrayutilities](https://xrayutilities.sourceforge.io/): X-ray diffraction analysis\n\n---\n\n## Acknowledgments\n\n- Developed at **Brookhaven National Laboratory (BNL)**, National Synchrotron Light Source II (NSLS-II)\n- Built using the [napari] framework and [napari-plugin-template]\n- Powered by [xrayutilities] for crystallographic calculations\n- Thanks to the napari community for excellent documentation and support\n\n## License\n\nDistributed under the terms of the [BSD-3] license, \"napari-resview\" is free and open source software.\n\nSee [LICENSE](LICENSE) for full details.\n\n---\n\n## Issues\n\nIf you encounter any problems, please [file an issue] along with:\n\n- A detailed description of the problem\n- Steps to reproduce the issue\n- Your environment information (OS, Python version, package versions)\n- Relevant error messages or logs\n- Screenshots if applicable\n\n---\n\n## Changelog\n\n### Version History\n\nSee the [GitHub releases](https://github.com/NSLS2/napari-resview/releases) page for version history and changelog.\n\n---\n\n## Contact\n\n- **Maintainer**: Xiaogang Yang (yangxg@bnl.gov)\n- **Institution**: Brookhaven National Laboratory, NSLS-II\n- **Repository**: https://github.com/NSLS2/napari-resview\n- **Issues**: https://github.com/NSLS2/napari-resview/issues\n\n---\n\n[napari]: https://github.com/napari/napari\n[copier]: https://copier.readthedocs.io/en/stable/\n[xrayutilities]: https://xrayutilities.sourceforge.io/\n[@napari]: https://github.com/napari\n[MIT]: http://opensource.org/licenses/MIT\n[BSD-3]: http://opensource.org/licenses/BSD-3-Clause\n[GNU GPL v3.0]: http://www.gnu.org/licenses/gpl-3.0.txt\n[GNU LGPL v3.0]: http://www.gnu.org/licenses/lgpl-3.0.txt\n[Apache Software License 2.0]: http://www.apache.org/licenses/LICENSE-2.0\n[Mozilla Public License 2.0]: https://www.mozilla.org/media/MPL/2.0/index.txt\n[napari-plugin-template]: https://github.com/napari/napari-plugin-template\n[file an issue]: https://github.com/NSLS2/napari-resview/issues\n[tox]: https://tox.readthedocs.io/en/latest/\n[pip]: https://pypi.org/project/pip/\n[PyPI]: https://pypi.org/\n","description_content_type":"text/markdown","keywords":null,"home_page":null,"download_url":null,"author":"AUTHORS.rst","author_email":"yangxg@bnl.gov","maintainer":null,"maintainer_email":null,"license":"BSD 3-Clause License\n\nCopyright (c) 2026, Brookhaven National Laboratory\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n","classifier":["Development Status :: 2 - Pre-Alpha","Framework :: napari","Intended Audience :: Developers","License :: OSI Approved :: BSD License","Operating System :: OS Independent","Programming Language :: Python","Programming Language :: Python :: 3","Programming Language :: Python :: 3 :: Only","Programming Language :: Python :: 3.10","Programming Language :: Python :: 3.11","Programming Language :: Python :: 3.12","Programming Language :: Python :: 3.13","Topic :: Scientific/Engineering :: Image Processing"],"requires_dist":["numpy","magicgui>=0.10.1","qtpy>=2.4.3","xrayutilities==1.7.10","h5py","hdf5plugin","pyyaml>=6.0.3","vtk>=9.0.0","pandas>=2.3.3","dask>=2024.8.0","pyarrow>=21.0.0","tifffile","scipy","napari[all]; extra == \"all\"","tox; extra == \"testing\"","pytest; extra == \"testing\"","pytest-cov; extra == \"testing\"","pytest-qt; extra == \"testing\"","napari[qt]==0.7.0; extra == \"testing\""],"requires_python":"<3.14,>=3.10","requires_external":null,"project_url":["Bug Tracker, https://github.com/XYangXRay/napari-resview/issues","Documentation, https://github.com/XYangXRay/napari-resview#README.md","Source Code, https://github.com/XYangXRay/napari-resview","User Support, https://github.com/XYangXRay/napari-resview/issues"],"provides_extra":["all","testing"],"provides_dist":null,"obsoletes_dist":null},"npe1_shim":false}