Set Demo#

Demonstration of Set services in Dips Python API.

This script demonstrates ISetServices methods including: - AddSetWindow: Create a new set window (Circular, Curved, or Freehand) - GetSetList: List all sets - DeleteSet: Remove a set

Available Set Window Types: - Circular: Defined by center (trend/plunge) and cone angle - Curved: Defined by two corner points (trend/plunge) - WrappedFreehand: Defined by polygon boundaries - Cluster: Created by automatic cluster analysis (not manually created)

Code Snippet: SetDemo.py#
"""
Demonstration of Set services in Dips Python API.

This script demonstrates ISetServices methods including:
- AddSetWindow: Create a new set window (Circular, Curved, or Freehand)
- GetSetList: List all sets
- DeleteSet: Remove a set

Available Set Window Types:
- Circular: Defined by center (trend/plunge) and cone angle
- Curved: Defined by two corner points (trend/plunge)
- WrappedFreehand: Defined by polygon boundaries
- Cluster: Created by automatic cluster analysis (not manually created)
"""

import math
from dips import DipsApp

from dips.SetWindowEntityInfoVal import SetWindowEntityInfoVal
from dips.CircularWindowVal import CircularWindowVal
from dips.CurvedWindowVal import CurvedWindowVal
from dips.WrappedFreehandWindowVal import WrappedFreehandWindowVal
from dips.FreehandWindowVal import FreehandWindowVal
from dips.TrendPlungeVal import TrendPlungeVal
from dips.ColorSurrogateVal import ColorSurrogateVal


# =============================================================================
# CIRCULAR SET WINDOW DEMONSTRATIONS
# =============================================================================

def demonstrate_add_circular_set_window(model):
    """Demonstrate adding a circular set window."""
    print("\n" + "=" * 60)
    print("ADD CIRCULAR SET WINDOW")
    print("=" * 60)
    
    set_window = SetWindowEntityInfoVal()
    set_window.set_window_type = DipsApp.enums.eSetWindowType.Circular
    set_window.color = ColorSurrogateVal.FromRGBA(0, 100, 255)  # Blue
    
    # Get default statistics settings
    set_window.statistics_settings = model.GetDefaultSetStatisticsSettings()
    
    # Configure circular window
    circular = CircularWindowVal()
    circular.id = "CircularSet1"
    circular.center = TrendPlungeVal.FromTrendPlunge(180, 45)
    circular.cone_angle.angle_radians = math.radians(30)
    set_window.circular_set_window = circular
    
    result = model.AddSetWindow(set_window)
    print(f"  ✓ AddSetWindow (Circular): '{circular.id}'")
    print(f"    Center: Trend=180°, Plunge=45°")
    print(f"    Cone Angle: 30°")
    return result


# =============================================================================
# CURVED SET WINDOW DEMONSTRATIONS
# =============================================================================

def demonstrate_add_curved_set_window(model):
    """Demonstrate adding a curved set window."""
    print("\n" + "=" * 60)
    print("ADD CURVED SET WINDOW")
    print("=" * 60)
    
    set_window = SetWindowEntityInfoVal()
    set_window.set_window_type = DipsApp.enums.eSetWindowType.Curved
    set_window.color = ColorSurrogateVal.FromRGBA(255, 100, 0)  # Orange
    
    # Get default statistics settings
    set_window.statistics_settings = model.GetDefaultSetStatisticsSettings()
    
    # Configure curved window with two corner points
    curved = CurvedWindowVal()
    curved.id = "CurvedSet1"
    curved.first_corner = TrendPlungeVal.FromTrendPlunge(60, 30)
    curved.second_corner = TrendPlungeVal.FromTrendPlunge(120, 60)
    set_window.curved_set_window = curved
    
    result = model.AddSetWindow(set_window)
    print(f"  ✓ AddSetWindow (Curved): '{curved.id}'")
    print(f"    First Corner: Trend=60°, Plunge=30°")
    print(f"    Second Corner: Trend=120°, Plunge=60°")
    return result


# =============================================================================
# FREEHAND SET WINDOW DEMONSTRATIONS
# =============================================================================

def demonstrate_add_freehand_set_window(model):
    """Demonstrate adding a freehand (wrapped freehand) set window."""
    print("\n" + "=" * 60)
    print("ADD FREEHAND SET WINDOW")
    print("=" * 60)
    
    set_window = SetWindowEntityInfoVal()
    set_window.set_window_type = DipsApp.enums.eSetWindowType.WrappedFreehand
    set_window.color = ColorSurrogateVal.FromRGBA(0, 200, 100)  # Green
    
    # Get default statistics settings
    set_window.statistics_settings = model.GetDefaultSetStatisticsSettings()
    
    # Configure freehand window with polygon points
    freehand = WrappedFreehandWindowVal()
    freehand.id = "FreehandSet1"
    
    # Primary window - define a polygon of points
    primary = FreehandWindowVal()
    primary.is_wrapped = False
    # Create a roughly pentagonal region
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(200, 40))
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(220, 50))
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(240, 45))
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(230, 35))
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(210, 30))
    freehand.primary_window = primary
    
    # Secondary window (can be empty or used for wrapped sets)
    secondary = FreehandWindowVal()
    secondary.is_wrapped = False
    freehand.secondary_window = secondary
    
    set_window.wrapped_freehand_set_window = freehand
    
    result = model.AddSetWindow(set_window)
    print(f"  ✓ AddSetWindow (Freehand): '{freehand.id}'")
    print(f"    Polygon points: {len(primary.polygon)}")
    print(f"    Points: (200°/40°), (220°/50°), (240°/45°), (230°/35°), (210°/30°)")
    return result


# =============================================================================
# GET AND DELETE DEMONSTRATIONS
# =============================================================================

def demonstrate_get_set_list(model):
    """Demonstrate listing all sets."""
    print("\n" + "=" * 60)
    print("GET SET LIST")
    print("=" * 60)
    
    sets = model.GetSetList()
    print(f"  ✓ GetSetList: {len(sets)} set(s) found")
    
    for i, set_ref in enumerate(sets):
        set_value = set_ref.GetValue()
        # SetEntityInfo has: id, color, set_window_entity_info
        # set_window_type is inside set_window_entity_info
        window_info = set_value.set_window_entity_info
        window_type = window_info.set_window_type
        set_id = set_value.id
        
        print(f"    [{i+1}] ID: '{set_id}' ({window_type})")
    
    return sets


def demonstrate_delete_set(model, set_ref, description=""):
    """Demonstrate deleting a set."""
    if set_ref is None:
        print(f"  - DeleteSet{description}: No set to delete")
        return
    
    set_value = set_ref.GetValue()
    # SetEntityInfo has: id, color, set_window_entity_info
    window_info = set_value.set_window_entity_info
    window_type = window_info.set_window_type
    set_id = set_value.id
    
    model.DeleteSet(set_ref)
    print(f"  ✓ DeleteSet: '{set_id}' ({window_type})")


# =============================================================================
# MULTIPLE SETS DEMONSTRATION
# =============================================================================

def demonstrate_multiple_sets(model):
    """Demonstrate creating multiple sets of different types."""
    print("\n" + "=" * 60)
    print("MULTIPLE SET EXAMPLES")
    print("=" * 60)
    
    created_sets = []
    
    # Create circular sets at different orientations
    print("\n  Creating Circular Sets:")
    circular_examples = [
        ("Set_N", 0, 45, 25, (255, 0, 0)),     # North
        ("Set_E", 90, 60, 20, (0, 255, 0)),    # East
        ("Set_S", 180, 30, 30, (0, 0, 255)),   # South
    ]
    
    for set_id, trend, plunge, cone_angle, color_rgb in circular_examples:
        set_window = SetWindowEntityInfoVal()
        set_window.set_window_type = DipsApp.enums.eSetWindowType.Circular
        set_window.color = ColorSurrogateVal.FromRGBA(*color_rgb)
        set_window.statistics_settings = model.GetDefaultSetStatisticsSettings()
        
        circular = CircularWindowVal()
        circular.id = set_id
        circular.center = TrendPlungeVal.FromTrendPlunge(trend, plunge)
        circular.cone_angle.angle_radians = math.radians(cone_angle)
        set_window.circular_set_window = circular
        
        result = model.AddSetWindow(set_window)
        created_sets.append(result)
        print(f"    ✓ '{set_id}' (Circular: {trend}°/{plunge}°, Cone: {cone_angle}°)")
    
    # Create curved sets
    print("\n  Creating Curved Sets:")
    curved_examples = [
        ("Curved_NE", 30, 20, 60, 50, (255, 128, 0)),
        ("Curved_SW", 210, 40, 250, 70, (128, 0, 255)),
    ]
    
    for set_id, t1, p1, t2, p2, color_rgb in curved_examples:
        set_window = SetWindowEntityInfoVal()
        set_window.set_window_type = DipsApp.enums.eSetWindowType.Curved
        set_window.color = ColorSurrogateVal.FromRGBA(*color_rgb)
        set_window.statistics_settings = model.GetDefaultSetStatisticsSettings()
        
        curved = CurvedWindowVal()
        curved.id = set_id
        curved.first_corner = TrendPlungeVal.FromTrendPlunge(t1, p1)
        curved.second_corner = TrendPlungeVal.FromTrendPlunge(t2, p2)
        set_window.curved_set_window = curved
        
        result = model.AddSetWindow(set_window)
        created_sets.append(result)
        print(f"    ✓ '{set_id}' (Curved: {t1}°/{p1}° to {t2}°/{p2}°)")
    
    # Create freehand set
    print("\n  Creating Freehand Sets:")
    set_window = SetWindowEntityInfoVal()
    set_window.set_window_type = DipsApp.enums.eSetWindowType.WrappedFreehand
    set_window.color = ColorSurrogateVal.FromRGBA(0, 200, 200)
    set_window.statistics_settings = model.GetDefaultSetStatisticsSettings()
    
    freehand = WrappedFreehandWindowVal()
    freehand.id = "Freehand_Custom"
    
    primary = FreehandWindowVal()
    primary.is_wrapped = False
    # Create a custom region
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(300, 20))
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(320, 35))
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(340, 30))
    primary.polygon.append(TrendPlungeVal.FromTrendPlunge(330, 15))
    freehand.primary_window = primary
    
    secondary = FreehandWindowVal()
    secondary.is_wrapped = False
    freehand.secondary_window = secondary
    
    set_window.wrapped_freehand_set_window = freehand
    
    result = model.AddSetWindow(set_window)
    created_sets.append(result)
    print(f"    ✓ 'Freehand_Custom' (Freehand: 4 polygon points)")
    
    return created_sets


def demonstrate_cleanup(model, sets_to_delete):
    """Clean up created sets."""
    print("\n" + "=" * 60)
    print("CLEANUP")
    print("=" * 60)
    
    for set_ref in sets_to_delete:
        demonstrate_delete_set(model, set_ref)


# =============================================================================
# MAIN
# =============================================================================

def main():
    """Main demonstration function."""
    print("=" * 60)
    print("Dips API - Set Services Demo")
    print("=" * 60)
    
    # Connect to Dips
    print("\nConnecting to Dips application...")
    app = DipsApp.LaunchApp(62535)
    print("✓ Connected to Dips")
    model = app.GetModel()
    
    # Show initial state
    print("\n" + "-" * 60)
    print("INITIAL STATE")
    print("-" * 60)
    demonstrate_get_set_list(model)
    
    # Add each type of set window
    circular_set = demonstrate_add_circular_set_window(model)
    curved_set = demonstrate_add_curved_set_window(model)
    freehand_set = demonstrate_add_freehand_set_window(model)
    
    # List sets after adding
    demonstrate_get_set_list(model)
    
    # Delete the sets
    print("\n" + "=" * 60)
    print("DELETE INDIVIDUAL SETS")
    print("=" * 60)
    demonstrate_delete_set(model, circular_set, " (Circular)")
    demonstrate_delete_set(model, curved_set, " (Curved)")
    demonstrate_delete_set(model, freehand_set, " (Freehand)")
    
    # Create multiple sets of all types
    created_sets = demonstrate_multiple_sets(model)
    
    # List all sets
    demonstrate_get_set_list(model)
    
    # Cleanup (commented out to keep sets visible)
    # demonstrate_cleanup(model, created_sets)
    
    # Show final state
    print("\n" + "-" * 60)
    print("FINAL STATE")
    print("-" * 60)
    demonstrate_get_set_list(model)
    
    # Show the application
    app.Show()
    
    # Summary
    print("\n" + "=" * 60)
    print("DEMONSTRATION COMPLETE")
    print("=" * 60)
    print("""
Set services demonstrated (3 methods):

  - AddSetWindow: Create a new set window
  - GetSetList: List all sets in the project
  - DeleteSet: Remove a set from the project

Set Window Types (eSetWindowType):

  1. CIRCULAR
     - Defined by: center (trend/plunge) + cone angle
     - Properties: id, center, cone_angle
     - Use case: Symmetric concentration around a pole

  2. CURVED
     - Defined by: two corner points (trend/plunge)
     - Properties: id, first_corner, second_corner
     - Use case: Elongated or asymmetric pole concentrations

  3. WRAPPED FREEHAND
     - Defined by: polygon of points (trend/plunge)
     - Properties: id, primary_window (polygon), secondary_window
     - Use case: Irregular or complex-shaped pole concentrations

  4. CLUSTER (read-only)
     - Created by automatic cluster analysis
     - Not manually created via AddSetWindow

Common Properties:
  - color: Display color for the set
  - statistics_settings: Statistical analysis settings
""")


if __name__ == "__main__":
    main()