{"name":"napari-myelin-quantifier","display_name":"Myelin Quantifier","visibility":"public","icon":"","categories":[],"schema_version":"0.2.1","on_activate":null,"on_deactivate":null,"contributions":{"commands":[{"id":"napari-myelin-quantifier.myelin_quantifier_widget","title":"Myelin Rings: Quantify","python_name":"napari_myelin_quantifier._widget:myelin_quantifier_widget","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-myelin-quantifier.myelin_quantifier_dashboard","title":"Myelin Rings: Locate by ID","python_name":"napari_myelin_quantifier._widget:myelin_locator_dashboard","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-myelin-quantifier.csv_quantification_widget","title":"CSV Quantification","python_name":"napari_myelin_quantifier._widget:csv_quantification_widget","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-myelin-quantifier.csv_study_analysis_widget","title":"CSV Study Analysis","python_name":"napari_myelin_quantifier._widget:csv_study_analysis_widget","short_title":null,"category":null,"icon":null,"enablement":null}],"readers":null,"writers":null,"widgets":[{"command":"napari-myelin-quantifier.myelin_quantifier_widget","display_name":"Myelin Rings: Quantify","autogenerate":false},{"command":"napari-myelin-quantifier.myelin_quantifier_dashboard","display_name":"Myelin Rings: Locate by ID","autogenerate":false},{"command":"napari-myelin-quantifier.csv_quantification_widget","display_name":"CSV Quantification","autogenerate":false},{"command":"napari-myelin-quantifier.csv_study_analysis_widget","display_name":"CSV Study Analysis","autogenerate":false}],"sample_data":null,"themes":null,"menus":{"napari/plugins":[{"command":"napari-myelin-quantifier.myelin_quantifier_widget","when":"True","group":null,"alt":null},{"command":"napari-myelin-quantifier.myelin_quantifier_dashboard","when":"True","group":null,"alt":null},{"command":"napari-myelin-quantifier.csv_quantification_widget","when":"True","group":null,"alt":null},{"command":"napari-myelin-quantifier.csv_study_analysis_widget","when":"True","group":null,"alt":null}]},"submenus":null,"keybindings":null,"configuration":[]},"package_metadata":{"metadata_version":"2.4","name":"napari-myelin-quantifier","version":"1.3.1","dynamic":["license-file"],"platform":null,"supported_platform":null,"summary":"Myelinated Axon Quantification with Label Tracking","description":"# napari-myelin-quantifier\n\n[![License MIT](https://img.shields.io/pypi/l/napari-myelin-quantifier.svg?color=green)](https://github.com/wulinteousa2-hash/napari-myelin-quantifier/raw/main/LICENSE)\n[![PyPI](https://img.shields.io/pypi/v/napari-myelin-quantifier.svg?color=green)](https://pypi.org/project/napari-myelin-quantifier)\n[![Python Version](https://img.shields.io/pypi/pyversions/napari-myelin-quantifier.svg?color=green)](https://python.org)\n[![napari hub](https://img.shields.io/endpoint?url=https://api.napari-hub.org/shields/napari-myelin-quantifier)](https://napari-hub.org/plugins/napari-myelin-quantifier)\n\n`napari-myelin-quantifier` is a napari plugin for 2D myelinated axon analysis. It supports three related workflows:\n\n- Detect and quantify myelin rings from binary mask layers in napari.\n- Import raw label/object measurement CSV files and calculate myelin morphometric features into Excel workbooks.\n- Build study-level analyses from raw CSV or calculated Excel files, compare blinded/final groups, and export combined study results.\n\nCurrent version: `1.3.1`\n\nVersion `1.3.1` adds study-level CSV/Excel analysis, filename-based sample IDs for blinded files such as `119.csv`, resumable imports from `calculated_*.xlsx`, direct two- or three-way comparison plots, PCA/k-means, and user-selected output folders.\n\n## Installation\n\nInstall from PyPI:\n\n```bash\npip install napari-myelin-quantifier\n```\n\nIf napari is not already installed:\n\n```bash\npip install \"napari-myelin-quantifier[all]\"\n```\n\nInstall the development version from GitHub:\n\n```bash\npip install git+https://github.com/wulinteousa2-hash/napari-myelin-quantifier.git\n```\n\n## Plugin Panels\n\nThe plugin contributes four napari widgets:\n\n- `Myelin Rings: Quantify`\n- `Myelin Rings: Locate by ID`\n- `CSV Quantification`\n- `CSV Study Analysis`\n\nOpen them from the napari menu:\n\n```text\nPlugins -> Myelin Quantifier\n```\n\n## Mask Quantification Workflow\n\nUse `Myelin Rings: Quantify` when you have a 2D binary mask layer.\n\nExpected mask semantics:\n\n- Myelin ring pixels are foreground, non-zero, or `True`.\n- Background is `0` or `False`.\n- Intact ring-shaped objects are recommended. Broken rings, solid objects, and border objects can be filtered or flagged.\n\nIf your mask is stored as RGB/RGBA or grayscale, use `Quick Mask Prep` in the quantification panel to create a binary Labels layer before running quantification.\n\n### Quick Mask Prep\n\nAvailable quick actions:\n\n- `1-Channel`: create a single-channel image layer.\n- `Invert`: create an inverted single-channel image layer.\n- `Binary (Otsu)`: convert the selected layer into a binary Labels layer.\n\nThe prepared binary layer is automatically selected in the quantifier mask-layer field.\n\nExample binary mask:\n\n![Binary Mask](https://github.com/wulinteousa2-hash/napari-myelin-quantifier/blob/main/docs/images/1_mask.PNG)\n\n*Image courtesy of Bo Hu Lab, Houston Methodist Research Institute.*\n\n### Ring Detection and Labeling\n\nEach detected myelin ring is:\n\n- assigned a unique `ring_id`,\n- localized using centroid coordinates,\n- measured for bounding box and area values,\n- evaluated for topology using Euler characteristic.\n\nExample labeled output:\n\n![MultiROI](https://github.com/wulinteousa2-hash/napari-myelin-quantifier/blob/main/docs/images/2_multiROI_connected_components.PNG)\n\n![MultiROI_ring_ID](https://github.com/wulinteousa2-hash/napari-myelin-quantifier/blob/main/docs/images/3_result_labels.PNG)\n\n### Topological Validation\n\nEuler number is used to distinguish ring-like structures from likely artifacts:\n\n- `Euler = 0`: ring-like object with one hole.\n- `Euler != 0`: solid object, fragmented object, or object with unexpected topology.\n\nTopology illustration:\n\n![Euler = 0 and != 0](https://github.com/wulinteousa2-hash/napari-myelin-quantifier/blob/main/docs/images/4_2D_euler_number_0.PNG)\n\n### Mask CSV Output\n\nThe mask workflow can export a CSV with one row per detected ring. Columns include:\n\n- `ring_id`\n- `centroid_x`, `centroid_y`\n- `bbox_x0`, `bbox_y0`, `bbox_x1`, `bbox_y1`\n- `ring_area_px`\n- `lumen_area_px`\n- `filled_area_px`\n- `euler`\n- `touches_border`\n- optional `ring_area_um2`, `lumen_area_um2`, and `filled_area_um2` when pixel size is set\n\nExample:\n\n```csv\nring_id,centroid_x,centroid_y,bbox_x0,bbox_y0,bbox_x1,bbox_y1,ring_area_px,lumen_area_px,filled_area_px,euler,touches_border\n1,873.8658,34.4421,857,18,890,52,380,556,936,0,False\n```\n\n## CSV Quantification Workflow\n\nUse `CSV Quantification` when you already have raw object measurement CSV files from a label/object measurement tool.\n\nThe importer supports common CSV variants, including comma-delimited files and semicolon-delimited UTF-8 files with a byte-order mark.\n\nRequired input columns, using either naming format:\n\n- `2D Area (µm²)`\n- `2D Filled Area (µm²)`\n\nor:\n\n- `ring_area_um2`\n- `filled_area_um2`\n\nor a mask export without pixel size:\n\n- `ring_area_px`\n- `filled_area_px`\n\nWhen mask area columns are used, the CSV workflow copies them into the standard `2D Area (µm²)` and `2D Filled Area (µm²)` columns before calculating features. If micrometer-squared and pixel-area mask columns are both present, the calibrated micrometer-squared columns are preferred.\n\nOther columns, such as `Time Step`, `Label Index`, `Name (NA)`, and `2D Euler Number`, are preserved in the processed output.\n\n### CSV UI Steps\n\n1. Open `Plugins -> Myelin Quantifier -> CSV Quantification`.\n2. Click `Import CSV`.\n3. Select one CSV file or multiple CSV files.\n4. Review the file table for row count, required-column detection, and processing status.\n5. Click `Process CSV`.\n6. Select a processed row in the table to view the quick summary and generate plots.\n\nFor each processed input file, the plugin writes an Excel workbook next to the original CSV:\n\n```text\ncalculated_<original_filename_without_extension>.xlsx\n```\n\nExample:\n\n```text\n117.csv -> calculated_117.xlsx\n```\n\nWhen multiple files are processed together, the plugin also writes:\n\n```text\ncombined_myelin_quantification_summary.xlsx\n```\n\n### Calculated Columns\n\nThe CSV workflow assumes:\n\n- `2D Filled Area (µm²)` is the outer filled fiber area.\n- `2D Area (µm²)` is the myelin ring area.\n- `AxonArea` is the inner axon area.\n\nCalculated columns:\n\n```text\nMyelinatedArea = 2D Filled Area (µm²)\nAxonArea = MyelinatedArea - 2D Area (µm²)\nRout µm = sqrt(MyelinatedArea / pi)\nRin µm = sqrt(AxonArea / pi)\nthickness (Myelin) = Rout µm - Rin µm\nG-ratio = Rin µm / Rout µm\nAxon Diameter µm = Rin µm * 2\n```\n\nMyelin thickness is the radius difference, not the diameter difference.\n\n### Validity Checks\n\nEach row is marked with:\n\n- `Valid Measurement`\n- `Validity Note`\n\nA row is valid only when:\n\n- `2D Filled Area (µm²) > 2D Area (µm²)`\n- `AxonArea > 0`\n- `Rout µm > 0`\n- `Rin µm >= 0`\n- `G-ratio` is finite\n- `G-ratio` is between `0` and `1`\n\nInvalid rows are kept in the output and annotated with the reason in `Validity Note`.\n\n### Axon Size Classes\n\nThe CSV workflow adds `Axon Size Class`:\n\n- `Thin`: `Axon Diameter µm < 1.0`\n- `Medium`: `1.0 <= Axon Diameter µm < 3.0`\n- `Thick`: `Axon Diameter µm >= 3.0`\n- `Invalid`: invalid measurements\n\n### Excel Output\n\nEach processed workbook contains:\n\n- `Processed_Data`: original CSV columns plus calculated columns.\n- `Summary`: one-row summary statistics for the source file.\n\nSummary statistics include total, valid, and invalid object counts; mean, median, standard deviation, minimum, and maximum G-ratio; mean and median myelin thickness; and mean, median, minimum, and maximum axon diameter.\n\n### Plots\n\nThe CSV panel can generate:\n\n- G-ratio histogram\n- Axon diameter histogram\n- Myelin thickness histogram\n- G-ratio vs axon diameter scatter plot\n- G-ratio vs myelin thickness scatter plot\n- G-ratio by axon size class boxplot\n\n## CSV Study Analysis Workflow\n\nUse `CSV Study Analysis` when you want to compare multiple samples, assign blind and final group labels, resume from calculated Excel files, make group plots, run PCA/k-means, or export one study workbook.\n\nSupported inputs:\n\n- raw measurement `.csv` files\n- processed `calculated_*.xlsx` workbooks from this plugin\n- compatible Excel workbooks containing a `Processed_Data` sheet with calculated columns\n\nThis means you can reopen a study later by importing the already calculated Excel files instead of processing raw CSV files again.\n\n### Study Setup\n\n1. Open `Plugins -> Myelin Quantifier -> CSV Study Analysis`.\n2. Click `Import CSV / Excel`.\n3. Select raw CSV files, calculated Excel files, or a mix of both.\n4. Optionally click `Set Output Folder` to choose where newly calculated Excel files and study exports should be saved.\n5. Review or edit sample metadata in the import table:\n   - `Sample ID`\n   - `Animal ID`\n   - `Image ID`\n   - `Blind Group`\n   - `Final Group`\n6. Use the `Include` checkbox to control which samples enter summaries, plots, PCA, and exports.\n7. Click `Process Selected` or `Process All`.\n\nCalculated Excel files are loaded as already processed samples. Raw CSV files are processed into `calculated_<name>.xlsx` in the selected output folder, or next to the source CSV if no output folder is set.\n\nBy default, `Sample ID` is taken from the filename so existing blinded sample codes are preserved. For example, `119.csv` becomes `119`, `S119.csv` becomes `S119`, and `calculated_119.xlsx` becomes `119`. Enable `Prefix numeric IDs with S` if you prefer numeric filenames such as `119.csv` to display as `S119`.\n\n### Traditional Comparisons\n\nThe `Compare` tab is for direct two- or three-way comparisons without PCA.\n\nYou can compare by:\n\n- `Sample ID`\n- `Blind Group`\n- `Final Group`\n\nChoose comparison values A, B, and optionally C, then generate:\n\n- overlay histograms\n- boxplots\n- G-ratio vs axon diameter scatter overlays\n- G-ratio vs myelin thickness scatter overlays\n\nThis is intended for straightforward subject-vs-subject, blind-group, or final-group comparisons with overlapping plots.\n\n### Study Outputs\n\nThe `Export` tab can write:\n\n- full study workbook\n- combined object-level CSV\n- sample-level summary CSV\n- PCA/cluster results CSV\n\nThe study workbook contains object-level data, sample-level summaries, PCA/cluster results when available, and analysis metadata.\n\n## Typical Mask Workflow\n\n1. Load your mask into napari.\n2. If needed, use `Quick Mask Prep`.\n3. Open `Plugins -> Myelin Rings: Quantify`.\n4. Adjust filtering parameters, such as minimum ring area, minimum lumen area, and border exclusion.\n5. Run quantification.\n6. Optionally open `Plugins -> Myelin Rings: Locate by ID` to jump to a specific `ring_id`.\n7. Export the mask measurement CSV.\n8. Optionally process compatible CSV measurements with `CSV Quantification`.\n\nInterface:\n\n![Interface](https://github.com/wulinteousa2-hash/napari-myelin-quantifier/blob/main/docs/images/interface.PNG)\n\n## Notes\n\nArea-derived diameter, radius, thickness, and G-ratio values assume approximately circular cross-sections. For highly irregular axons, inspect area-based values and validity notes before interpreting derived morphometrics.\n\n## Development\n\nRun tests from the repository root:\n\n```bash\nPYTHONPATH=src python -m pytest\n```\n\n## Acknowledgements\n\nExample microscopy data used in documentation were generated by the **Bo Hu Lab**, Houston Methodist Research Institute.\n\nImaging hardware and infrastructure support were provided by the **Electron Microscopy Core**, directed by **István Katona**, Houston Methodist Research Institute.\n\n## Contributing\n\nContributions are welcome. Please ensure tests pass before submitting pull requests.\n\n## License\n\nMIT License.\n","description_content_type":"text/markdown","keywords":null,"home_page":null,"download_url":null,"author":"Wulin Teo","author_email":"wulinteo.usa2@gmail.com","maintainer":null,"maintainer_email":null,"license":"The MIT License (MIT)\n\nCopyright (c) 2026 Wulin Teo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","classifier":["Development Status :: 2 - Pre-Alpha","Framework :: napari","Intended Audience :: Developers","License :: OSI Approved :: MIT 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","pandas","openpyxl","xlrd","matplotlib","magicgui","qtpy","scikit-image","scikit-learn","napari[all]; extra == \"all\""],"requires_python":">=3.10","requires_external":null,"project_url":["Bug Tracker, https://github.com/wulinteousa2-hash/napari-myelin-quantifier/issues","Documentation, https://github.com/wulinteousa2-hash/napari-myelin-quantifier#README.md","Source Code, https://github.com/wulinteousa2-hash/napari-myelin-quantifier","User Support, https://github.com/wulinteousa2-hash/napari-myelin-quantifier/issues"],"provides_extra":["all"],"provides_dist":null,"obsoletes_dist":null},"npe1_shim":false}