.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples\04_designs\plot_02_inside_each_subject.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_04_designs_plot_02_inside_each_subject.py: Defining habitats inside each subject ====================================== **Background.** In the one-step design each tumour is clustered on its own voxels: no supervoxels, no pooling, and no model shared by the cohort. **Purpose.** You get one private habitat model and one habitat map per subject, plus their volume fractions, drawn side by side. **When to use.** You want to describe how heterogeneous each tumour is by itself (e.g. how many habitats, how fragmented). Skip it if habitat ids must mean the same thing across patients; use :doc:`/auto_examples/04_designs/plot_01_two_step` instead. **Key terms.** * **one-step** -- ``fit`` and ``assign`` run inside each subject, so every subject gets its own centroids. * **label switching** -- independent clusterings number the same habitat differently, so ids must be matched before comparing subjects. Input: one subject at a time. Output: a :class:`~habit.contracts.HabitatMap` whose integer ids belong to that subject only. The stage list has no ``pool``, so ``fit`` runs inside each subject instead of on the cohort. ``one_step_habitat(...)`` is a shortcut that builds the same stage list. Habitat 1 in the first subject is not habitat 1 in the second. Match labels before comparing people: :doc:`/auto_examples/06_matching/plot_07_match_labels`. .. GENERATED FROM PYTHON SOURCE LINES 35-39 Load the cohort --------------- Change ``DATA`` / ``MODALITIES`` / ``ROI`` to your preprocessed layout. sphinx_gallery_thumbnail_number = 1 .. GENERATED FROM PYTHON SOURCE LINES 39-57 .. code-block:: Python from pathlib import Path import matplotlib.pyplot as plt import numpy as np from habit.contracts import cohort_from_directory from habit.datasets import fetch_demo from habit.recipes import Study from habit.spec import HabitatSpec, Spec, Stage from habit.viz import plot_habitat_overlay DATA = fetch_demo() # Three DCE phases: unenhanced, arterial, and portal-venous. MODALITIES = ("pre_contrast", "LAP", "PVP") ROI = "LAP" cohort = cohort_from_directory(DATA, modalities=MODALITIES, roi=ROI)[:3] print(f"Cohort: {list(cohort.subject_ids)}") .. rst-class:: sphx-glr-script-out .. code-block:: none HABIT demo data (cached) DATA (preprocessed root): C:\Users\dongm\.habit_data\demo-data-v1\preprocessed On-disk inventory of this folder: subjects (5): subj001, subj002, subj003, subj004, subj005 image series: LAP, PVP, delay_3min, pre_contrast mask keys: LAP, PVP, delay_3min, pre_contrast example image: images/subj001/delay_3min/WATER__BH_Ax_LAVA_Flex_3min_Series0012.nrrd example mask: masks/subj001/delay_3min/WATER__BH_Ax_LAVA_Flex_10min_Series0017_mask.nrrd Your own data must use the same folder tree (change IDs / series names): DATA/ images/// masks/// Then load it with the same call the demos use: cohort = cohort_from_directory(DATA, modalities=("LAP",), roi="LAP") Swap DATA / modalities / roi to match your tree. Mask key is often the same as one image series (here LAP). Cohort: ['subj001', 'subj002', 'subj003'] .. GENERATED FROM PYTHON SOURCE LINES 58-63 Fit a private model inside each subject --------------------------------------- No ``partition`` and no ``pool``: each subject's ROI voxels are clustered on their own. Habitat 1 in the first subject is not habitat 1 in the second. There is no shared centroid. .. GENERATED FROM PYTHON SOURCE LINES 63-88 .. code-block:: Python spec = HabitatSpec( name="one_step", stages=( # extract: one intensity column per DCE phase, inside the ROI. Stage("extract", Spec("raw", {"modalities": list(MODALITIES), "roi": ROI})), # No partition and no pool: fit runs on this subject's voxels only. Stage("fit", Spec("kmeans", {"n_habitats": 3, "n_init": 10})), # assign: nearest centroid of THIS subject's model, not a shared one. Stage("assign", Spec("nearest_centroid")), Stage("volume", Spec("volume")), ), random_seed=0, ) # Without pool, fit_predict keeps one model per subject (subject_models) # instead of a single cohort habitat_model. result = Study(spec).fit_predict(cohort) print(f"Per-subject models: {list(result.subject_models)}") for habitat_map in result.habitat_maps: present = sorted( int(v) for v in np.unique(habitat_map.label_array) if int(v) != 0 ) print(habitat_map.subject_id, present) print(result.features.frame) result.features.frame .. rst-class:: sphx-glr-script-out .. code-block:: none Cohort.map[_DefineAndLabelWithinSubject]: 0%| | 0/3 [00:00
subject habitat_1_voxel_count habitat_1_volume_fraction habitat_2_voxel_count habitat_2_volume_fraction habitat_3_voxel_count habitat_3_volume_fraction
0 subj001 14235.0 0.410301 13813.0 0.398138 6646.0 0.191561
1 subj002 3585.0 0.363664 2515.0 0.255123 3758.0 0.381213
2 subj003 1303.0 0.211663 2680.0 0.435348 2173.0 0.352989


.. GENERATED FROM PYTHON SOURCE LINES 89-91 Show each subject's habitat map on its own anatomy. No comparison -- just the three maps side by side. .. GENERATED FROM PYTHON SOURCE LINES 91-105 .. code-block:: Python Path("out").mkdir(exist_ok=True) for subject, habitat_map in zip(cohort, result.habitat_maps): fig = plot_habitat_overlay( subject.image(ROI), habitat_map, title=f"habitats ({habitat_map.subject_id})", crop_to="labels", ) fig.savefig( f"out/one_step_{habitat_map.subject_id}.png", dpi=150, bbox_inches="tight", ) plt.show() .. rst-class:: sphx-glr-horizontal * .. image-sg:: /auto_examples/04_designs/images/sphx_glr_plot_02_inside_each_subject_001.png :alt: habitats (subj001), Axis 0 (axial-like) @ 96, Axis 1 (coronal-like) @ 165, Axis 2 (sagittal-like) @ 71 :srcset: /auto_examples/04_designs/images/sphx_glr_plot_02_inside_each_subject_001.png :class: sphx-glr-multi-img * .. image-sg:: /auto_examples/04_designs/images/sphx_glr_plot_02_inside_each_subject_002.png :alt: habitats (subj002), Axis 0 (axial-like) @ 86, Axis 1 (coronal-like) @ 233, Axis 2 (sagittal-like) @ 69 :srcset: /auto_examples/04_designs/images/sphx_glr_plot_02_inside_each_subject_002.png :class: sphx-glr-multi-img * .. image-sg:: /auto_examples/04_designs/images/sphx_glr_plot_02_inside_each_subject_003.png :alt: habitats (subj003), Axis 0 (axial-like) @ 46, Axis 1 (coronal-like) @ 121, Axis 2 (sagittal-like) @ 200 :srcset: /auto_examples/04_designs/images/sphx_glr_plot_02_inside_each_subject_003.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none F:\work\habit_project\habit\viz\habitat_overlay.py:806: UserWarning: Display geometry conflict: image/anatomy direction does not match mask/label direction. Using the mask/label direction so coronal/sagittal superior-up follows the labelled anatomy. Pass direction= to override. resolved_direction, resolved_spacing = resolve_display_geometry( F:\work\habit_project\habit\viz\habitat_overlay.py:806: UserWarning: Display geometry conflict: image/anatomy direction does not match mask/label direction. Using the mask/label direction so coronal/sagittal superior-up follows the labelled anatomy. Pass direction= to override. resolved_direction, resolved_spacing = resolve_display_geometry( F:\work\habit_project\habit\viz\habitat_overlay.py:806: UserWarning: Display geometry conflict: image/anatomy direction does not match mask/label direction. Using the mask/label direction so coronal/sagittal superior-up follows the labelled anatomy. Pass direction= to override. resolved_direction, resolved_spacing = resolve_display_geometry( .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 7.516 seconds) .. _sphx_glr_download_auto_examples_04_designs_plot_02_inside_each_subject.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_inside_each_subject.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_inside_each_subject.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_inside_each_subject.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_