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
- Navigate to Advanced → Scripting.
- 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
| Feature | Description |
|---|---|
| Syntax highlighting | Python keywords, strings, comments colored |
| Code completion | Ctrl+Space for suggestions |
| Line numbers | Navigation reference |
| Find/Replace | Ctrl+F and Ctrl+H |
| Run script | Ctrl+R |
| Stop script | Ctrl+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
- Enter the code in the editor.
- Click Run (or press Ctrl+R).
- Observe the message dialog.
- 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:
- Batch Processing and Automation — Process multiple datasets
- Scripting API Reference — Complete API documentation
- Scripting Code Examples — Ready-to-use code samples