""" STAT7 Visualization Integration Integrates STAT7 experiments with the WebSocket visualization system. Provides easy-to-use functions for connecting experiments to real-time visualization. Usage: from stat7_visualization import visualize_experiment # Visualize EXP-01 await visualize_experiment("EXP-01", sample_size=1000, iterations=5) # Visualize custom bit-chain generation await visualize_continuous_generation(duration_seconds=30) """ import asyncio import threading import time from typing import Optional, Dict, Any from pathlib import Path from warbler_cda.stat7_experiments import ( EXP01_AddressUniqueness, ) # Import the visualization components try: from stat7wsserve import STAT7EventStreamer, ExperimentVisualizer except ImportError: print("Warning: stat7wsserve not found. Visualization features disabled.") STAT7EventStreamer = None ExperimentVisualizer = None class STAT7VisualizationManager: """ High-level manager for STAT7 visualization. Handles WebSocket server startup, experiment integration, and cleanup. """ def __init__(self, host: str = "localhost", port: int = 8765, auto_start: bool = True): self.host = host self.port = port self.event_streamer: Optional[STAT7EventStreamer] = None self.visualizer: Optional[ExperimentVisualizer] = None self.server_thread: Optional[threading.Thread] = None self.is_running = False if STAT7EventStreamer is None: raise ImportError("stat7wsserve module not available. Install required dependencies.") if auto_start: self.start_server() def start_server(self): """Start the WebSocket visualization server in a background thread.""" if self.is_running: return self.event_streamer = STAT7EventStreamer(host=self.host, port=self.port) self.visualizer = ExperimentVisualizer(self.event_streamer) # Start server in background thread self.server_thread = threading.Thread(target=self._run_server, daemon=True) self.server_thread.start() # Wait for server to start time.sleep(2) self.is_running = True print(f"๐Ÿš€ STAT7 Visualization Server started on ws://{self.host}:{self.port}") print("๐ŸŒ Open stat7threejs.html in your browser to view visualization") def _run_server(self): """Run the WebSocket server in asyncio event loop.""" loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: loop.run_until_complete(self.event_streamer.start_server()) except Exception as e: print(f"Server error: {e}") finally: loop.close() def stop_server(self): """Stop the WebSocket server.""" if self.event_streamer: self.event_streamer.stop_server() self.is_running = False print("๐Ÿ‘‹ STAT7 Visualization Server stopped") async def visualize_exp01(self, sample_size: int = 1000, iterations: int = 10): """Visualize EXP-01 address uniqueness test.""" if not self.visualizer: raise RuntimeError("Visualization server not started") await self.visualizer.visualize_exp01_uniqueness(sample_size, iterations) async def visualize_continuous_generation( self, duration_seconds: int = 60, rate_per_second: int = 10 ): """Visualize continuous bit-chain generation.""" if not self.visualizer: raise RuntimeError("Visualization server not started") await self.visualizer.visualize_continuous_generation(duration_seconds, rate_per_second) async def visualize_bitchain_batch(self, bitchains: list, experiment_id: str = "custom"): """Visualize a batch of existing bit-chains.""" if not self.event_streamer: raise RuntimeError("Visualization server not started") for bitchain in bitchains: event = self.event_streamer.create_bitchain_event(bitchain, experiment_id) await self.event_streamer.broadcast_event(event) await asyncio.sleep(0.01) # Small delay for visualization effect # Global visualization manager instance _viz_manager: Optional[STAT7VisualizationManager] = None def get_visualization_manager() -> STAT7VisualizationManager: """Get or create the global visualization manager.""" global _viz_manager if _viz_manager is None: _viz_manager = STAT7VisualizationManager() return _viz_manager async def visualize_experiment(experiment_name: str, **kwargs) -> Dict[str, Any]: """ High-level function to visualize STAT7 experiments. Args: experiment_name: Name of experiment ("EXP-01", "EXP-02", "EXP-03", "continuous") **kwargs: Experiment-specific parameters Returns: Dictionary with experiment results and visualization info """ manager = get_visualization_manager() print(f"๐Ÿงช Starting visualization for {experiment_name}") if experiment_name == "EXP-01": sample_size = kwargs.get("sample_size", 1000) iterations = kwargs.get("iterations", 10) await manager.visualize_exp01(sample_size, iterations) # Run actual experiment for results exp01 = EXP01_AddressUniqueness(sample_size=sample_size, iterations=iterations) results, success = exp01.run() return { "experiment": experiment_name, "success": success, "results": results, "visualization": "completed", } elif experiment_name == "continuous": duration = kwargs.get("duration_seconds", 60) rate = kwargs.get("rate_per_second", 10) await manager.visualize_continuous_generation(duration, rate) return { "experiment": experiment_name, "duration_seconds": duration, "rate_per_second": rate, "visualization": "completed", } else: raise ValueError(f"Unknown experiment: {experiment_name}") def create_jupyter_widget(width: str = "100%", height: str = "600px") -> str: """ Create HTML widget for embedding STAT7 visualization in Jupyter notebooks. Args: width: Widget width (CSS value) height: Widget height (CSS value) Returns: HTML string for Jupyter notebook display """ # Read the visualization HTML html_path = Path(__file__).parent.parent.parent / "stat7threejs.html" if not html_path.exists(): # Fallback to inline HTML return create_inline_jupyter_widget(width, height) with open(html_path, "r", encoding="utf-8") as f: f.read() # Wrap in iframe for Jupyter widget_html = f"""
""" return widget_html def create_inline_jupyter_widget(width: str = "100%", height: str = "600px") -> str: """ Create inline HTML widget for Jupyter (fallback when external file not available). Args: width: Widget width (CSS value) height: Widget height (CSS value) Returns: HTML string for Jupyter notebook display """ return f"""

๐Ÿ”Œ STAT7 Visualization

WebSocket Status: Connecting...

Points Rendered: 0

FPS: 0

""" # Jupyter notebook display helper def display_in_jupyter(width: str = "100%", height: str = "600px"): """ Display STAT7 visualization in Jupyter notebook. Usage in Jupyter: from stat7_visualization import display_in_jupyter, visualize_experiment # Display visualization widget display_in_jupyter() # Run visualization await visualize_experiment("EXP-01", sample_size=500, iterations=3) """ try: from IPython.display import HTML, display widget_html = create_jupyter_widget(width, height) display(HTML(widget_html)) except ImportError: print("IPython not available. Cannot display in Jupyter notebook.") print("Open stat7threejs.html in your browser instead.") # Convenience functions for quick start def quick_start_visualization(): """Quick start visualization with default settings.""" manager = get_visualization_manager() print("๐Ÿš€ STAT7 Visualization started!") print("๐Ÿ“Š Open stat7threejs.html in your browser") print("๐Ÿงช Use visualize_experiment() to run experiments") return manager if __name__ == "__main__": # Example usage async def main(): manager = quick_start_visualization() print("\nRunning example visualizations...") # Visualize EXP-01 await manager.visualize_exp01(sample_size=100, iterations=2) # Continuous generation await manager.visualize_continuous_generation(duration_seconds=10, rate_per_second=5) print("\nโœ… Example visualizations complete!") print("Keep the server running and refresh your browser to see the results.") # Keep server running try: while True: await asyncio.sleep(1) except KeyboardInterrupt: manager.stop_server() asyncio.run(main())