Skip to main content

Python Scripting Fundamentals

The Volvicon Scripting API enables automation of repetitive tasks, creation of custom processing pipelines, and integration with external tools. This tutorial introduces the scripting environment and core API concepts.

Estimated time: 45 minutes

Prerequisites:

  • Basic Python programming knowledge
  • Familiarity with Volvicon's GUI operations
  • Custom Scripting feature enabled (available on Professional and above licenses)

The Scripting Environment

Opening the Script Editor

  1. Navigate to Advanced → Scripting.
  2. The Python scripting editor opens with:
    • Code editor pane — Syntax-highlighted editor
    • Output console — Shows execution results
    • Toolbar — Run, stop, save, and template controls

Editor Features

FeatureDescription
Syntax highlightingPython keywords, strings, comments colored
Code completionCtrl+Space for suggestions
Line numbersNavigation reference
Find/ReplaceCtrl+F and Ctrl+H
Run scriptCtrl+R
Stop scriptCtrl+Shift+R

Using Templates

Access starter code from the Templates menu:

  • Getting Started — Basic application setup
  • Volume Operations — Working with volumes
  • Mask Operations — Segmentation and mask tools
  • Surface Operations — Surface mesh processing
  • AI Segmentation — Automated segmentation
  • Project Management — File operations

Core API Concepts

The Application Object

All scripting starts with the Application object:

import ScriptingApi as api

# Create application instance
app = api.Application()

The app object provides access to:

  • Project management
  • Object access
  • Operations modules
  • User interaction

Operations Modules

Specialized operations are accessed through dedicated modules:

# Get operations modules
volume_operations = app.get_volume_operations()
mask_operations = app.get_mask_operations()
surface_operations = app.get_surface_operations()
volume_mesh_operations = app.get_volume_mesh_operations()
measurement_operations = app.get_measurement_operations()
analysis_operations = app.get_analysis_operations()

Important Conventions

Positional Arguments Only

The Volvicon API requires positional arguments. Keyword arguments are not supported.

# Correct
mask_operations.threshold("MyVolume", params)

# Incorrect - will fail
mask_operations.threshold(volume_name="MyVolume", params=params)

Your First Script

Hello World

import ScriptingApi as api

app = api.Application()

# Display a message
app.show_message_box("Hello, Volvicon!")

# Get confirmation from user
confirmed = app.show_question_message_box("Do you want to continue?")
if confirmed:
app.show_message_box("User confirmed!")
else:
app.show_message_box("User cancelled.")

Running the Script

  1. Enter the code in the editor.
  2. Click Run (or press Ctrl+R).
  3. Observe the message dialog.
  4. Check the console for output.

Working with Projects

Project Information

import ScriptingApi as api

app = api.Application()

# Get project information
project_path = app.get_project_file_path()
print(f"Project path: {project_path}")

# List all objects in the project
volumes = app.get_all_volume_names()
masks = app.get_all_mask_names()
surfaces = app.get_all_surface_names()

print(f"Volumes: {volumes}")
print(f"Masks: {masks}")
print(f"Surfaces: {surfaces}")

Opening and Saving Projects

import ScriptingApi as api

app = api.Application()

# Open a project
app.open_project("C:/Data/MyProject.vvcx")

# Save the current project
app.save_project()

# Save as a new file
app.save_project("C:/Data/MyProject_copy.vvcx")

# Close the project
app.close_project()

Volume Operations

Importing Volumes

import ScriptingApi as api

app = api.Application()
volume_operations = app.get_volume_operations()

# Import a volume file
volume_name = volume_operations.import_3d_image_from_disk("C:/Data/scan.nii")
print(f"Imported: {volume_name}")

Volume Properties

import ScriptingApi as api

app = api.Application()
volume_operations = app.get_volume_operations()

# Get volume information
dims = volume_operations.get_dimensions("CT_Head")
spacing = volume_operations.get_spacing("CT_Head")
origin = volume_operations.get_origin("CT_Head")

print(f"Dimensions: {dims}")
print(f"Spacing: {spacing}")
print(f"Origin: {origin}")

Exporting Volumes

import ScriptingApi as api

app = api.Application()
volume_operations = app.get_volume_operations()

# Export volume to file
volume_operations.export_volume_image_to_disk("CT_Head", "C:/Output/head.nii")

Mask Operations

Creating Masks with Threshold

import ScriptingApi as api

app = api.Application()
mask_operations = app.get_mask_operations()

# Configure threshold parameters
threshold_params = api.ThresholdParams()
threshold_params.lower_threshold = 200
threshold_params.upper_threshold = 3000
threshold_params.filter_regions = True
threshold_params.min_region_size = 100
threshold_params.keep_largest = False

# Apply threshold
result = mask_operations.threshold("CT_Volume", threshold_params)
print(f"Created mask: {result}")

Mask Refinement

import ScriptingApi as api

app = api.Application()
mask_operations = app.get_mask_operations()

# Smooth the mask
mask_operations.smooth_median_filter(["BoneMask"], 2, 2, 2)

# Fill cavities
mask_operations.cavity_fill(["BoneMask"])

Boolean Operations

import ScriptingApi as api

app = api.Application()
mask_operations = app.get_mask_operations()

# Union of two masks
mask_operations.boolean("Mask1", ["Mask2"], "", api.BooleanOperation.Union, True)

# Intersection
mask_operations.boolean("Mask1", ["Mask2"], "", api.BooleanOperation.Intersection, True)

# Difference
mask_operations.boolean("Mask1", ["Mask2"], "", api.BooleanOperation.Difference, True)

Exporting Masks

import ScriptingApi as api

app = api.Application()
mask_operations = app.get_mask_operations()

# Export mask to file
mask_operations.export_mask_image_to_disk("BoneMask", "C:/Output/bone_mask.nii")

Surface Operations

Creating Surfaces from Masks

import ScriptingApi as api

app = api.Application()
mask_operations = app.get_mask_operations()

# Generate surface from mask
mask_to_surface_params = api.MaskToSurfaceParams()
mask_to_surface_params.smooth_iterations = 20
mask_to_surface_params.smooth_factor = 0.06
mask_to_surface_params.triangle_reduction_percent = 50

surface_name = mask_operations.convert_to_surface_objects(["BoneMask"], mask_to_surface_params)
print(f"Created surface: {surface_name}")

Surface Processing

import ScriptingApi as api

app = api.Application()
surface_operations = app.get_surface_operations()

# Smooth the surface
surface_operations.smooth_smart(["BoneSurface"], 20, 0.06) # iterations, factor

# Reduce triangle count
surface_operations.reduce_smart(["BoneSurface"], 50) # target percentage

# Subdivide for more detail
surface_operations.subdivide(["BoneSurface"], api.SurfaceSubdivisionMethod.Adaptive, 1) # iterations

Creating Primitives

import ScriptingApi as api

app = api.Application()
surface_operations = app.get_surface_operations()

# Create a sphere
surface_operations.create_sphere("Sphere", 10, [0, 0, 0]) # radius, center

# Create a cylinder
surface_operations.create_cylinder("Cylinder", 5, 20, [0, 0, 0]) # radius, height, center

Exporting Surfaces

import ScriptingApi as api

app = api.Application()
surface_operations = app.get_surface_operations()

# Export to STL
surface_operations.export_surface_to_disk("BoneSurface", "C:/Output/bone.stl")

# Export to OBJ
surface_operations.export_surface_to_disk("BoneSurface", "C:/Output/bone.obj")

AI Segmentation

Running TotalSegmentator

import ScriptingApi as api

app = api.Application()
app.open_project("C:/Data/ct_scan.vvcx")

# Access AI segmentation module
ai_segmentation = app.get_ai_segmentation()
ai_segmentation.set_model_type(api.AiSegmentationModelType.TotalSegmentator)

# Configure parameters
params = api.TotalSegmentatorParams()
params.task = "total"
params.device = "gpu"

# Run segmentation
volumes = app.get_all_volume_names()
masks = ai_segmentation.run_total_segmentator(volumes, params)
print(f"Created {len(masks)} masks")

Measurements and Analysis

Creating Measurements

import ScriptingApi as api

app = api.Application()
measurement_operations = app.get_measurement_operations()

# Create a point measurement
point = measurement_operations.create_point([10.0, 20.0, 30.0], "Landmark1")

# Create a distance measurement
distance = measurement_operations.create_distance(
[0, 0, 0], # Point 1
[10, 10, 10], # Point 2
"Distance1"
)
print(f"Distance: {distance} mm")

Calculating Statistics

import ScriptingApi as api

app = api.Application()
measure_operations = app.get_measure_operations()

requested_stats = [
api.LabelStatisticType.VoxelCount,
api.LabelStatisticType.Volume,
api.LabelStatisticType.MinIntensity,
api.LabelStatisticType.MaxIntensity,
api.LabelStatisticType.MeanIntensity,
api.LabelStatisticType.StandardDeviation
]

# Get mask statistics
mask_statistics_result = measure_operations.compute_whole_mask_statistics("BoneMask", "CT_Volume", requested_stats)
print(f"Whole mask stats: {mask_statistics_result.mask_name}")
print(f" Total voxel count: {mask_statistics_result.total_voxel_count}")
print(f" Total volume: {mask_statistics_result.total_volume}")
print(f"Label count: {len(mask_statistics_result.label_statistics)}")

mask_label_statistics = api.MaskLabelStatistics()
mask_label_statistics = mask_statistics_result.label_statistics[0]
print(f" Min intensity: {mask_label_statistics.min_intensity}")
print(f" Max intensity: {mask_label_statistics.max_intensity}")
print(f" Mean intensity: {mask_label_statistics.mean_intensity}")
print(f" StdDev: {mask_label_statistics.standard_deviation}")

Error Handling

Try-Except Blocks

import ScriptingApi as api

app = api.Application()
volume_operations = app.get_volume_operations()

try:
# Attempt to import
volume_operations.import_3d_image_from_disk("C:/Data/nonexistent.nii")
except Exception as e:
print(f"Error: {e}")
app.show_message_box(f"Import failed: {e}")

Validating Inputs

import ScriptingApi as api

app = api.Application()

# Check if objects exist before processing
volumes = app.get_all_volume_names()
if "CT_Head" in volumes:
# Process the volume
pass
else:
app.show_message_box("CT_Head volume not found!")

Complete Example: Automated Bone Analysis

"""
Automated Bone Analysis Pipeline
This script demonstrates a complete workflow from volume import through surface export.
"""

import ScriptingApi as api

def main():

global api

# Initialize
app = api.Application()
volume_operations = app.get_volume_operations()
mask_operations = app.get_mask_operations()
surface_operations = app.get_surface_operations()
measure_operations = app.get_measure_operations()

# Configuration
input_path = "C:/tmp/arfaeen.nii.gz"
output_dir = "C:/Output/"

# Step 1: Import volume
print("Importing volume...")
volume_name = volume_operations.import_3d_image_from_disk(input_path)
print(f"Imported: {volume_name}")

# Step 2: Threshold segmentation for bone
print("Segmenting bone...")
threshold_params = api.ThresholdParams()
threshold_params.lower_threshold = 200
threshold_params.upper_threshold = 3000
threshold_params.filter_regions = True
threshold_params.min_region_size = 100
threshold_params.keep_largest = False

mask_name = mask_operations.threshold(volume_name, threshold_params)
print(f"Created mask: {mask_name}")

# Step 3: Refine the mask
print("Refining mask...")
mask_operations.smooth_median_filter([mask_name], 1, 1, 1)

mask_operations.cavity_fill([mask_name])

# Step 4: Calculate statistics
print("Calculating statistics...")
mask_statistics_result = measure_operations.compute_whole_mask_statistics(mask_name, volume_name, [api.LabelStatisticType.VoxelCount, api.LabelStatisticType.Volume])
print(f" Total voxel count: {mask_statistics_result.total_voxel_count}")
print(f" Total volume: {mask_statistics_result.total_volume:.2f} mm³")

# Step 5: Generate surface
print("Generating surface...")
mask_to_surface_params = api.MaskToSurfaceParams()
mask_to_surface_params.smooth_iterations = 20
mask_to_surface_params.smooth_factor = 0.06
mask_to_surface_params.triangle_reduction_percent = 50

surface_name = mask_operations.convert_to_surface_objects([mask_name], mask_to_surface_params)

# Step 6: Export results
print("Exporting results...")
mask_operations.export_mask_image_to_disk(mask_name, f"{output_dir}bone_mask.nii")
surface_operations.export_surface_to_disk(surface_name[0], f"{output_dir}bone_surface.stl")

# Complete
print("Pipeline complete!")
app.show_message_box("Bone analysis complete!")

# Run the script
main()

Best Practices

Code Organization

  • Use functions to organize logical steps
  • Add comments explaining each section
  • Use meaningful variable names
  • Handle errors gracefully

Performance

  • Batch operations when possible
  • Avoid unnecessary object creation
  • Close projects when done
  • Monitor memory usage

Debugging

  • Use print statements for progress tracking
  • Check console output for errors
  • Test with small datasets first
  • Validate intermediate results

Next Steps

Continue with advanced automation:


See Also