Skip to content

nilearn

tit.plotting.nilearn

TI-Toolbox Nilearn plotting helpers.

This package contains "basic" neuroimaging plotting utilities (non-blender), including: - Slice PDF exports - Glass brain exports - Interactive HTML views

NilearnVisualizer

NilearnVisualizer(subject_id: str | None = None)

Main visualization class for electric field distributions.

Provides methods for creating both static PDF visualizations and interactive HTML plots. Uses PathManager for consistent path handling and supports multiple atlas overlays.

Initialize the visualizer.

Parameters:

Name Type Description Default
subject_id str | None

Subject ID (optional, will use PathManager detection if not provided)

None
Source code in tit/plotting/nilearn/visualizer.py
def __init__(self, subject_id: str | None = None):
    """
    Initialize the visualizer.

    Args:
        subject_id: Subject ID (optional, will use PathManager detection if not provided)
    """
    self.pm = get_path_manager()
    self.subject_id = subject_id
    self.output_dir = None

    # Set up output directory
    self._setup_output_directory()

create_pdf_visualization

create_pdf_visualization(subject_id: str, simulation_name: str, min_cutoff: float = 0.3, max_cutoff: float = None, atlas_name: str = 'harvard_oxford_sub', selected_regions: list[int] | None = None) -> str | None

Create PDF visualization with multiple surface views and atlas contours.

Parameters:

Name Type Description Default
subject_id str

Subject ID

required
simulation_name str

Name of the simulation

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3
max_cutoff float

Maximum cutoff for visualization (V/m), if None uses 99.9th percentile

None
atlas_name str

Name of atlas to overlay

'harvard_oxford_sub'
selected_regions list[int] | None

List of region indices to include (0-indexed), if None includes all

None

Returns:

Type Description
str | None

Path to saved PDF file or None if failed

Source code in tit/plotting/nilearn/visualizer.py
def create_pdf_visualization(
    self,
    subject_id: str,
    simulation_name: str,
    min_cutoff: float = 0.3,
    max_cutoff: float = None,
    atlas_name: str = "harvard_oxford_sub",
    selected_regions: list[int] | None = None,
) -> str | None:
    """
    Create PDF visualization with multiple surface views and atlas contours.

    Args:
        subject_id: Subject ID
        simulation_name: Name of the simulation
        min_cutoff: Minimum cutoff for visualization (V/m)
        max_cutoff: Maximum cutoff for visualization (V/m), if None uses 99.9th percentile
        atlas_name: Name of atlas to overlay
        selected_regions: List of region indices to include (0-indexed), if None includes all

    Returns:
        Path to saved PDF file or None if failed
    """
    print(f"=== Creating PDF Visualization for {subject_id}/{simulation_name} ===")

    # Get simulation files
    sim_files = self._get_simulation_files(subject_id)
    if simulation_name not in sim_files:
        print(
            f"Error: Simulation '{simulation_name}' not found for subject {subject_id}"
        )
        return None

    ef_filepath = sim_files[simulation_name]
    ef_img = self._load_electric_field_data(ef_filepath)
    if ef_img is None:
        return None

    # Load and analyze data
    data = ef_img.get_fdata()
    data_nonzero = data[data > 0]
    if len(data_nonzero) == 0:
        print("Warning: No non-zero field values found")
        return None

    max_value = np.max(data)
    percentile_999 = np.percentile(data_nonzero, 99.9)
    min_value = np.min(data_nonzero)

    # Use provided max_cutoff or default to 99.9th percentile
    if max_cutoff is None:
        max_cutoff = percentile_999

    print(f"Electric field statistics:")
    print(f"  Absolute maximum: {max_value:.2f} V/m")
    print(f"  99.9th percentile: {percentile_999:.2f} V/m")
    print(f"  Minimum (non-zero): {min_value:.2f} V/m")
    print(f"  Visualization range: {min_cutoff:.2f} - {max_cutoff:.2f} V/m")

    # Create output filename
    pdf_filename = f"{subject_id}_{simulation_name}_multiple_views.pdf"
    pdf_filepath = os.path.join(self.output_dir, pdf_filename)

    # Load atlas for contours
    atlas_img, atlas_display_name = self._load_atlas(atlas_name, selected_regions)

    # Create multi-slice plot with atlas contours
    self._create_multi_slice_plot_with_atlas(
        ef_img, atlas_img, atlas_display_name, pdf_filepath, min_cutoff, max_cutoff
    )

    print(f"✓ Saved: {pdf_filepath}")
    print(f"  Colorbar range: {min_cutoff:.2f} - {max_cutoff:.2f} V/m")

    return pdf_filepath

create_html_visualization

create_html_visualization(subject_id: str, simulation_name: str, min_cutoff: float = 0.3) -> str | None

Create interactive HTML visualization.

Parameters:

Name Type Description Default
subject_id str

Subject ID

required
simulation_name str

Name of the simulation

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3

Returns:

Type Description
str | None

Path to saved HTML file or None if failed

Source code in tit/plotting/nilearn/visualizer.py
def create_html_visualization(
    self, subject_id: str, simulation_name: str, min_cutoff: float = 0.3
) -> str | None:
    """
    Create interactive HTML visualization.

    Args:
        subject_id: Subject ID
        simulation_name: Name of the simulation
        min_cutoff: Minimum cutoff for visualization (V/m)

    Returns:
        Path to saved HTML file or None if failed
    """
    print(f"=== Creating HTML Visualization for {subject_id}/{simulation_name} ===")

    # Get simulation files
    sim_files = self._get_simulation_files(subject_id)
    if simulation_name not in sim_files:
        print(
            f"Error: Simulation '{simulation_name}' not found for subject {subject_id}"
        )
        return None

    ef_filepath = sim_files[simulation_name]
    ef_img = self._load_electric_field_data(ef_filepath)
    if ef_img is None:
        return None

    # Analyze data for thresholds
    data = ef_img.get_fdata()
    data_nonzero = data[data > 0]
    if len(data_nonzero) == 0:
        print("Warning: No non-zero field values found")
        return None

    percentile_999 = np.percentile(data_nonzero, 99.9)

    # Create output filename
    html_filename = f"{subject_id}_{simulation_name}_interactive.html"
    html_filepath = os.path.join(self.output_dir, html_filename)

    # Create interactive visualization
    view = view_img_on_surf(
        stat_map=ef_img,
        threshold=min_cutoff,
        vmax=percentile_999,
        cmap="hot",
        symmetric_cmap=False,
        bg_on_data=True,
        title=f"Electric Field - {subject_id}/{simulation_name}",
    )

    # Save as HTML
    view.save_as_html(html_filepath)
    print(f"✓ Saved interactive HTML: {html_filepath}")

    return html_filepath

create_pdf_visualization_group

create_pdf_visualization_group(averaged_img, base_filename: str, output_dir: str, min_cutoff: float = 0.3, max_cutoff: float = None, atlas_name: str = 'harvard_oxford_sub', selected_regions: list[int] | None = None) -> str | None

Create PDF visualization with pre-averaged nifti data.

Parameters:

Name Type Description Default
averaged_img

Pre-averaged nibabel Nifti1Image

required
base_filename str

Base filename for output (without extension)

required
output_dir str

Output directory path

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3
max_cutoff float

Maximum cutoff for visualization (V/m), if None uses 99.9th percentile

None
atlas_name str

Name of atlas to overlay

'harvard_oxford_sub'
selected_regions list[int] | None

List of region indices to include (0-indexed), if None includes all

None

Returns:

Type Description
str | None

Path to saved PDF file or None if failed

Source code in tit/plotting/nilearn/visualizer.py
def create_pdf_visualization_group(
    self,
    averaged_img,
    base_filename: str,
    output_dir: str,
    min_cutoff: float = 0.3,
    max_cutoff: float = None,
    atlas_name: str = "harvard_oxford_sub",
    selected_regions: list[int] | None = None,
) -> str | None:
    """
    Create PDF visualization with pre-averaged nifti data.

    Args:
        averaged_img: Pre-averaged nibabel Nifti1Image
        base_filename: Base filename for output (without extension)
        output_dir: Output directory path
        min_cutoff: Minimum cutoff for visualization (V/m)
        max_cutoff: Maximum cutoff for visualization (V/m), if None uses 99.9th percentile
        atlas_name: Name of atlas to overlay
        selected_regions: List of region indices to include (0-indexed), if None includes all

    Returns:
        Path to saved PDF file or None if failed
    """
    print(f"=== Creating PDF Visualization for Group Averaged Data ===")

    # Load and analyze data
    data = averaged_img.get_fdata()
    data_nonzero = data[data > 0]
    if len(data_nonzero) == 0:
        print("Warning: No non-zero field values found")
        return None

    max_value = np.max(data)
    percentile_999 = np.percentile(data_nonzero, 99.9)
    min_value = np.min(data_nonzero)

    # Use provided max_cutoff or default to 99.9th percentile
    if max_cutoff is None:
        max_cutoff = percentile_999

    print(f"Electric field statistics (averaged data):")
    print(f"  Absolute maximum: {max_value:.2f} V/m")
    print(f"  99.9th percentile: {percentile_999:.2f} V/m")
    print(f"  Minimum (non-zero): {min_value:.2f} V/m")
    print(f"  Visualization range: {min_cutoff:.2f} - {max_cutoff:.2f} V/m")

    # Create output filename
    pdf_filename = f"{base_filename}_multiple_views.pdf"
    pdf_filepath = os.path.join(output_dir, pdf_filename)

    # Load atlas for contours
    atlas_img, atlas_display_name = self._load_atlas(atlas_name, selected_regions)

    # Create multi-slice plot with atlas contours
    self._create_multi_slice_plot_with_atlas(
        averaged_img,
        atlas_img,
        atlas_display_name,
        pdf_filepath,
        min_cutoff,
        max_cutoff,
    )

    print(f"✓ Saved: {pdf_filepath}")
    print(f"  Colorbar range: {min_cutoff:.2f} - {max_cutoff:.2f} V/m")

    return pdf_filepath

create_glass_brain_visualization

create_glass_brain_visualization(subject_id: str, simulation_name: str, min_cutoff: float = 0.3, max_cutoff: float = None, cmap: str = 'hot') -> str | None

Create glass brain visualization using nilearn's plot_glass_brain.

Parameters:

Name Type Description Default
subject_id str

Subject ID

required
simulation_name str

Name of the simulation

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3
max_cutoff float

Maximum cutoff for visualization (V/m), if None uses 99.9th percentile

None
cmap str

Colormap name for visualization

'hot'

Returns:

Type Description
str | None

Path to saved PNG file or None if failed

Source code in tit/plotting/nilearn/visualizer.py
def create_glass_brain_visualization(
    self,
    subject_id: str,
    simulation_name: str,
    min_cutoff: float = 0.3,
    max_cutoff: float = None,
    cmap: str = "hot",
) -> str | None:
    """
    Create glass brain visualization using nilearn's plot_glass_brain.

    Args:
        subject_id: Subject ID
        simulation_name: Name of the simulation
        min_cutoff: Minimum cutoff for visualization (V/m)
        max_cutoff: Maximum cutoff for visualization (V/m), if None uses 99.9th percentile
        cmap: Colormap name for visualization

    Returns:
        Path to saved PNG file or None if failed
    """
    print(
        f"=== Creating Glass Brain Visualization for {subject_id}/{simulation_name} ==="
    )

    # Get simulation files
    sim_files = self._get_simulation_files(subject_id)
    if simulation_name not in sim_files:
        print(
            f"Error: Simulation '{simulation_name}' not found for subject {subject_id}"
        )
        return None

    ef_filepath = sim_files[simulation_name]
    ef_img = self._load_electric_field_data(ef_filepath)
    if ef_img is None:
        return None

    # Load and analyze data
    data = ef_img.get_fdata()
    data_nonzero = data[data > 0]
    if len(data_nonzero) == 0:
        print("Warning: No non-zero field values found")
        return None

    max_value = np.max(data)
    percentile_999 = np.percentile(data_nonzero, 99.9)
    min_value = np.min(data_nonzero)

    # Use provided max_cutoff or default to 99.9th percentile
    if max_cutoff is None:
        max_cutoff = percentile_999

    print(f"Electric field statistics:")
    print(f"  Absolute maximum: {max_value:.2f} V/m")
    print(f"  99.9th percentile: {percentile_999:.2f} V/m")
    print(f"  Minimum (non-zero): {min_value:.2f} V/m")
    print(f"  Visualization range: {min_cutoff:.2f} - {max_cutoff:.2f} V/m")

    # Create output filename
    png_filename = f"{subject_id}_{simulation_name}_glass_brain.png"
    png_filepath = os.path.join(self.output_dir, png_filename)

    # Create glass brain visualization
    plotting.plot_glass_brain(
        stat_map_img=ef_img,
        threshold=min_cutoff,
        vmax=max_cutoff,
        cmap=cmap,
        colorbar=True,
        plot_abs=False,
        symmetric_cbar=False,
        title=f"Electric Field - {subject_id}/{simulation_name}\n{min_cutoff:.2f}-{max_cutoff:.2f} V/m",
        output_file=png_filepath,
    )

    print(f"✓ Saved glass brain visualization: {png_filepath}")

    return png_filepath

create_pdf_entry_point

create_pdf_entry_point(subject_id: str, simulation_name: str, min_cutoff: float = 0.3, max_cutoff: float = None, atlas_name: str = 'harvard_oxford_sub', selected_regions: list = None, output_callback=None)

Entry point for PDF visualization creation.

Parameters:

Name Type Description Default
subject_id str

Subject ID

required
simulation_name str

Simulation name

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3
max_cutoff float

Maximum cutoff for visualization (V/m), if None uses 99.9th percentile

None
atlas_name str

Atlas name for contours

'harvard_oxford_sub'
selected_regions list

List of region indices to include (0-indexed), if None includes all

None
output_callback

Optional callback function for output (for GUI integration)

None
Source code in tit/plotting/nilearn/img_slices.py
def create_pdf_entry_point(
    subject_id: str,
    simulation_name: str,
    min_cutoff: float = 0.3,
    max_cutoff: float = None,
    atlas_name: str = "harvard_oxford_sub",
    selected_regions: list = None,
    output_callback=None,
):
    """
    Entry point for PDF visualization creation.

    Args:
        subject_id: Subject ID
        simulation_name: Simulation name
        min_cutoff: Minimum cutoff for visualization (V/m)
        max_cutoff: Maximum cutoff for visualization (V/m), if None uses 99.9th percentile
        atlas_name: Atlas name for contours
        selected_regions: List of region indices to include (0-indexed), if None includes all
        output_callback: Optional callback function for output (for GUI integration)
    """
    # Redirect stdout if callback provided (for GUI integration)
    import sys
    from contextlib import redirect_stdout
    import io

    if output_callback:
        # Capture stdout and send to callback
        captured_output = io.StringIO()
        with redirect_stdout(captured_output):
            visualizer = NilearnVisualizer()
            result = visualizer.create_pdf_visualization(
                subject_id,
                simulation_name,
                min_cutoff,
                max_cutoff,
                atlas_name,
                selected_regions,
            )

        # Send captured output to callback line by line
        output_text = captured_output.getvalue()
        for line in output_text.split("\n"):
            if line.strip():
                output_callback(line)

        if result:
            output_callback(f"✓ PDF visualization completed: {result}")
            return result
        else:
            output_callback("✗ PDF visualization failed")
            return None
    else:
        # Normal operation - print to stdout
        visualizer = NilearnVisualizer()
        result = visualizer.create_pdf_visualization(
            subject_id,
            simulation_name,
            min_cutoff,
            max_cutoff,
            atlas_name,
            selected_regions,
        )
        if result:
            print(f"\n✓ PDF visualization completed: {result}")
            return result
        else:
            print("\n✗ PDF visualization failed")
            return None

create_pdf_entry_point_group

create_pdf_entry_point_group(averaged_img, base_filename: str, output_dir: str, min_cutoff: float = 0.3, max_cutoff: float = None, atlas_name: str = 'harvard_oxford_sub', selected_regions: list = None, output_callback=None)

Entry point for PDF visualization creation with pre-averaged nifti data.

Parameters:

Name Type Description Default
averaged_img

Pre-averaged nibabel Nifti1Image

required
base_filename str

Base filename for output (without extension)

required
output_dir str

Output directory path

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3
max_cutoff float

Maximum cutoff for visualization (V/m), if None uses 99.9th percentile

None
atlas_name str

Atlas name for contours

'harvard_oxford_sub'
selected_regions list

List of region indices to include (0-indexed), if None includes all

None
output_callback

Optional callback function for output (for GUI integration)

None
Source code in tit/plotting/nilearn/img_slices.py
def create_pdf_entry_point_group(
    averaged_img,
    base_filename: str,
    output_dir: str,
    min_cutoff: float = 0.3,
    max_cutoff: float = None,
    atlas_name: str = "harvard_oxford_sub",
    selected_regions: list = None,
    output_callback=None,
):
    """
    Entry point for PDF visualization creation with pre-averaged nifti data.

    Args:
        averaged_img: Pre-averaged nibabel Nifti1Image
        base_filename: Base filename for output (without extension)
        output_dir: Output directory path
        min_cutoff: Minimum cutoff for visualization (V/m)
        max_cutoff: Maximum cutoff for visualization (V/m), if None uses 99.9th percentile
        atlas_name: Atlas name for contours
        selected_regions: List of region indices to include (0-indexed), if None includes all
        output_callback: Optional callback function for output (for GUI integration)
    """
    # Redirect stdout if callback provided (for GUI integration)
    import sys
    from contextlib import redirect_stdout
    import io

    if output_callback:
        # Capture stdout and send to callback
        captured_output = io.StringIO()
        with redirect_stdout(captured_output):
            visualizer = NilearnVisualizer()
            result = visualizer.create_pdf_visualization_group(
                averaged_img,
                base_filename,
                output_dir,
                min_cutoff,
                max_cutoff,
                atlas_name,
                selected_regions,
            )

        # Send captured output to callback line by line
        output_text = captured_output.getvalue()
        for line in output_text.split("\n"):
            if line.strip():
                output_callback(line)

        if result:
            output_callback(f"✓ PDF visualization completed: {result}")
            return result
        else:
            output_callback("✗ PDF visualization failed")
            return None
    else:
        # Normal operation - print to stdout
        visualizer = NilearnVisualizer()
        result = visualizer.create_pdf_visualization_group(
            averaged_img,
            base_filename,
            output_dir,
            min_cutoff,
            max_cutoff,
            atlas_name,
            selected_regions,
        )
        if result:
            print(f"\n✓ PDF visualization completed: {result}")
            return result
        else:
            print("\n✗ PDF visualization failed")
            return None

create_glass_brain_entry_point

create_glass_brain_entry_point(subject_id: str, simulation_name: str, min_cutoff: float = 0.3, max_cutoff: float = None, cmap: str = 'hot', output_callback=None)

Entry point for glass brain visualization creation.

Parameters:

Name Type Description Default
subject_id str

Subject ID

required
simulation_name str

Simulation name

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3
max_cutoff float

Maximum cutoff for visualization (V/m), if None uses 99.9th percentile

None
cmap str

Colormap name for visualization

'hot'
output_callback

Optional callback function for output (for GUI integration)

None
Source code in tit/plotting/nilearn/img_glass.py
def create_glass_brain_entry_point(
    subject_id: str,
    simulation_name: str,
    min_cutoff: float = 0.3,
    max_cutoff: float = None,
    cmap: str = "hot",
    output_callback=None,
):
    """
    Entry point for glass brain visualization creation.

    Args:
        subject_id: Subject ID
        simulation_name: Simulation name
        min_cutoff: Minimum cutoff for visualization (V/m)
        max_cutoff: Maximum cutoff for visualization (V/m), if None uses 99.9th percentile
        cmap: Colormap name for visualization
        output_callback: Optional callback function for output (for GUI integration)
    """
    # Redirect stdout if callback provided (for GUI integration)
    import sys
    from contextlib import redirect_stdout
    import io

    if output_callback:
        # Capture stdout and send to callback
        captured_output = io.StringIO()
        with redirect_stdout(captured_output):
            visualizer = NilearnVisualizer()
            result = visualizer.create_glass_brain_visualization(
                subject_id, simulation_name, min_cutoff, max_cutoff, cmap
            )

        # Send captured output to callback line by line
        output_text = captured_output.getvalue()
        for line in output_text.split("\n"):
            if line.strip():
                output_callback(line)

        if result:
            output_callback(f"✓ Glass brain visualization completed: {result}")
            return result
        else:
            output_callback("✗ Glass brain visualization failed")
            return None
    else:
        # Normal operation - print to stdout
        visualizer = NilearnVisualizer()
        result = visualizer.create_glass_brain_visualization(
            subject_id, simulation_name, min_cutoff, max_cutoff, cmap
        )
        if result:
            print(f"\n✓ Glass brain visualization completed: {result}")
            return result
        else:
            print("\n✗ Glass brain visualization failed")
            return None

create_glass_brain_entry_point_group

create_glass_brain_entry_point_group(averaged_img, base_filename: str, output_dir: str, min_cutoff: float = 0.3, max_cutoff: float = None, cmap: str = 'hot', output_callback=None)

Entry point for glass brain visualization creation with pre-averaged nifti data.

Parameters:

Name Type Description Default
averaged_img

Pre-averaged nibabel Nifti1Image

required
base_filename str

Base filename for output (without extension)

required
output_dir str

Output directory path

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3
max_cutoff float

Maximum cutoff for visualization (V/m), if None uses 99.9th percentile

None
cmap str

Colormap name for visualization

'hot'
output_callback

Optional callback function for output (for GUI integration)

None
Source code in tit/plotting/nilearn/img_glass.py
def create_glass_brain_entry_point_group(
    averaged_img,
    base_filename: str,
    output_dir: str,
    min_cutoff: float = 0.3,
    max_cutoff: float = None,
    cmap: str = "hot",
    output_callback=None,
):
    """
    Entry point for glass brain visualization creation with pre-averaged nifti data.

    Args:
        averaged_img: Pre-averaged nibabel Nifti1Image
        base_filename: Base filename for output (without extension)
        output_dir: Output directory path
        min_cutoff: Minimum cutoff for visualization (V/m)
        max_cutoff: Maximum cutoff for visualization (V/m), if None uses 99.9th percentile
        cmap: Colormap name for visualization
        output_callback: Optional callback function for output (for GUI integration)
    """
    # Redirect stdout if callback provided (for GUI integration)
    import sys
    from contextlib import redirect_stdout
    import io
    import os
    import numpy as np
    import matplotlib.pyplot as plt
    from nilearn import plotting

    if output_callback:
        # Capture stdout and send to callback
        captured_output = io.StringIO()
        with redirect_stdout(captured_output):
            # Load and analyze data
            data = averaged_img.get_fdata()
            data_nonzero = data[data > 0]
            if len(data_nonzero) == 0:
                print("Warning: No non-zero field values found")
                return None

            max_value = np.max(data)
            percentile_999 = np.percentile(data_nonzero, 99.9)
            min_value = np.min(data_nonzero)

            # Use provided max_cutoff or default to 99.9th percentile
            if max_cutoff is None:
                max_cutoff = percentile_999

            print(f"Electric field statistics (averaged data):")
            print(f"  Absolute maximum: {max_value:.2f} V/m")
            print(f"  99.9th percentile: {percentile_999:.2f} V/m")
            print(f"  Minimum (non-zero): {min_value:.2f} V/m")
            print(f"  Visualization range: {min_cutoff:.2f} - {max_cutoff:.2f} V/m")

            # Create output filename
            pdf_filename = f"{base_filename}_glass_brain.pdf"
            pdf_filepath = os.path.join(output_dir, pdf_filename)

            # Create glass brain visualization
            plotting.plot_glass_brain(
                stat_map_img=averaged_img,
                threshold=min_cutoff,
                vmax=max_cutoff,
                cmap=cmap,
                colorbar=True,
                plot_abs=False,
                symmetric_cbar=False,
                display_mode="lyrz",
                title=f"Electric Field - Group Average\n{min_cutoff:.2f}-{max_cutoff:.2f} V/m",
                output_file=pdf_filepath,
            )

            print(f"✓ Saved glass brain visualization: {pdf_filepath}")
            result = pdf_filepath

        # Send captured output to callback line by line
        output_text = captured_output.getvalue()
        for line in output_text.split("\n"):
            if line.strip():
                output_callback(line)

        if result:
            output_callback(f"✓ Glass brain visualization completed: {result}")
            return result
        else:
            output_callback("✗ Glass brain visualization failed")
            return None
    else:
        # Normal operation - print to stdout
        # Load and analyze data
        data = averaged_img.get_fdata()
        data_nonzero = data[data > 0]
        if len(data_nonzero) == 0:
            print("Warning: No non-zero field values found")
            return None

        max_value = np.max(data)
        percentile_999 = np.percentile(data_nonzero, 99.9)
        min_value = np.min(data_nonzero)

        # Use provided max_cutoff or default to 99.9th percentile
        if max_cutoff is None:
            max_cutoff = percentile_999

        print(f"Electric field statistics (averaged data):")
        print(f"  Absolute maximum: {max_value:.2f} V/m")
        print(f"  99.9th percentile: {percentile_999:.2f} V/m")
        print(f"  Minimum (non-zero): {min_value:.2f} V/m")
        print(f"  Visualization range: {min_cutoff:.2f} - {max_cutoff:.2f} V/m")

        # Create output filename
        pdf_filename = f"{base_filename}_glass_brain.pdf"
        pdf_filepath = os.path.join(output_dir, pdf_filename)

        # Create glass brain visualization
        plotting.plot_glass_brain(
            stat_map_img=averaged_img,
            threshold=min_cutoff,
            vmax=max_cutoff,
            cmap=cmap,
            colorbar=True,
            plot_abs=False,
            symmetric_cbar=False,
            display_mode="lyrz",
            title=f"Electric Field - Group Average\n{min_cutoff:.2f}-{max_cutoff:.2f} V/m",
            output_file=pdf_filepath,
        )

        print(f"✓ Saved glass brain visualization: {pdf_filepath}")
        result = pdf_filepath

        if result:
            print(f"\n✓ Glass brain visualization completed: {result}")
            return result
        else:
            print("\n✗ Glass brain visualization failed")
            return None

create_html_entry_point

create_html_entry_point(subject_id: str, simulation_name: str, min_cutoff: float = 0.3)

Entry point for HTML visualization creation.

Parameters:

Name Type Description Default
subject_id str

Subject ID

required
simulation_name str

Simulation name

required
min_cutoff float

Minimum cutoff for visualization (V/m)

0.3
Source code in tit/plotting/nilearn/html_report.py
def create_html_entry_point(
    subject_id: str, simulation_name: str, min_cutoff: float = 0.3
):
    """
    Entry point for HTML visualization creation.

    Args:
        subject_id: Subject ID
        simulation_name: Simulation name
        min_cutoff: Minimum cutoff for visualization (V/m)
    """
    visualizer = NilearnVisualizer()
    result = visualizer.create_html_visualization(
        subject_id, simulation_name, min_cutoff
    )
    if result:
        print(f"\n✓ HTML visualization completed: {result}")
        return 0
    else:
        print("\n✗ HTML visualization failed")
        return 1