Analysis Module
Overview
At a Glance
- Purpose:
Analyze network topology, link utilization, and spectrum usage patterns
- Location:
fusion/analysis/- Key Files:
network_analysis.py- Depends On:
numpy,fusion.utils.logging_config- Used By:
Simulation reporting, performance analysis scripts
The analysis module provides utilities for examining network state during and after simulations. It answers questions like “How congested is the network?”, “Which links are bottlenecks?”, and “What’s the overall spectrum utilization?”
Developers work here when they need to add new analysis metrics, modify how utilization is calculated, or integrate analysis into new reporting features.
Key Concepts
- Link Utilization
The ratio of occupied spectrum slots to total available slots on a link. A value of 1.0 means fully utilized, 0.0 means empty.
- Bottleneck Link
A link whose utilization exceeds a threshold (default 80%). These links limit network capacity and cause blocking.
- Bidirectional Links
Network links exist in both directions (A-B and B-A). Analysis methods handle this by either processing each direction separately or normalizing to count physical links once.
- Cores Matrix
The spectrum state for a link, stored as a 2D array with shape
(num_cores, num_slots). Values indicate slot status:0: Free slotpositive int: Occupied by lightpath with that IDnegative int: Guard band for lightpath withabs(value)ID
Note
This module currently uses the legacy dict format for network_spectrum
(v5.5.0 compatibility). It will be migrated to use NetworkState and
LinkSpectrum objects directly in v6.1.0.
Architecture
fusion/analysis/
├── __init__.py # Exports NetworkAnalyzer
├── network_analysis.py # NetworkAnalyzer class
├── README.md # Module documentation
└── tests/
├── __init__.py
├── README.md
└── test_network_analysis.py
Data Flow
Input:
network_spectrumdict from simulation engine (orNetworkState.network_spectrum_dict)Processing: Iterate over links, analyze cores matrices, aggregate statistics
Output: Dictionary of metrics (utilization stats, bottleneck lists, congestion data)
Components
network_analysis.py
- Purpose:
Provides the
NetworkAnalyzerclass with static analysis methods- Key Classes:
NetworkAnalyzer
The NetworkAnalyzer class contains four static methods for analyzing network state:
get_link_usage_summary()
Returns per-link usage statistics including usage count, throughput, and link number. Processes each directional link separately.
from fusion.analysis import NetworkAnalyzer
# Get usage summary for all links
usage = NetworkAnalyzer.get_link_usage_summary(network_spectrum)
# Returns: {
# "A-B": {
# "usage_count": 10, # Number of allocations on this link
# "throughput": 100.5, # Total bandwidth served (Gbps)
# "link_num": 1 # Link index in topology
# },
# ...
# }
analyze_network_congestion()
Calculates network-wide congestion metrics including total occupied slots, guard slots, and active request counts.
# Analyze full network
congestion = NetworkAnalyzer.analyze_network_congestion(network_spectrum)
# Analyze specific paths only
congestion = NetworkAnalyzer.analyze_network_congestion(
network_spectrum,
specific_paths=[("A", "B"), ("C", "D")]
)
# Returns: {
# "total_occupied_slots": 1500, # Slots with data or guard bands
# "total_guard_slots": 200, # Slots used for guard bands only
# "active_requests": 45, # Unique lightpath IDs found
# "links_analyzed": 10, # Number of links processed
# "avg_occupied_per_link": 150.0, # Mean occupied slots per link
# "avg_guard_per_link": 20.0 # Mean guard slots per link
# }
get_network_utilization_stats()
Calculates aggregate utilization statistics across the network.
stats = NetworkAnalyzer.get_network_utilization_stats(network_spectrum)
# Returns: {
# "overall_utilization": 0.45, # Ratio of occupied to total slots
# "average_link_utilization": 0.42, # Mean utilization across all links
# "max_link_utilization": 0.85, # Highest link utilization
# "min_link_utilization": 0.10, # Lowest link utilization
# "total_slots": 10240, # Total spectrum slots in network
# "occupied_slots": 4608, # Slots currently in use
# "links_processed": 32 # Number of physical links analyzed
# }
identify_bottleneck_links()
Finds links exceeding a utilization threshold, sorted by utilization descending.
# Find links above 80% utilization (default)
bottlenecks = NetworkAnalyzer.identify_bottleneck_links(network_spectrum)
# Custom threshold
bottlenecks = NetworkAnalyzer.identify_bottleneck_links(
network_spectrum,
threshold=0.9
)
# Returns: [
# {
# "link_key": "A-B", # Normalized link identifier
# "utilization": 0.95, # Max core utilization on this link
# "usage_count": 50, # Number of allocations
# "throughput": 500.0 # Total bandwidth served (Gbps)
# },
# ... # Sorted by utilization descending
# ]
Dependencies
This Module Depends On
fusion.utils.logging_config- Logging utilitiesExternal:
numpy- Array operations for spectrum matrix analysis
Modules That Depend On This
fusion.reporting- Uses analysis for simulation reportsfusion.core.metrics- May use for real-time monitoring
Development Guide
Getting Started
Read the Key Concepts section above
Examine
network_analysis.pyto understand theNetworkAnalyzerclassRun the tests to see example inputs and expected outputs
Common Tasks
Adding a new analysis metric
Add a new static method to
NetworkAnalyzerinnetwork_analysis.pyFollow the existing pattern: accept
network_spectrumdict, return a dictHandle bidirectional links appropriately (count once or separately)
Add comprehensive tests in
tests/test_network_analysis.pyUpdate the module README
Modifying utilization calculation
Locate the relevant method (likely
get_network_utilization_stats)Update the calculation logic
Update tests to reflect new expected values
Document any behavioral changes
Code Patterns
Static Analysis Method Pattern
All analysis methods follow this pattern:
@staticmethod
def analyze_something(network_spectrum: dict) -> dict[str, Any]:
"""
Analyze network for something.
:param network_spectrum: Network spectrum database
:return: Dictionary of analysis results
"""
# Track processed links to avoid double-counting bidirectional
processed_links = set()
for (src, dst), link_data in network_spectrum.items():
# Normalize key for bidirectional handling
link_key = f"{min(src, dst)}-{max(src, dst)}"
if link_key in processed_links:
continue
processed_links.add(link_key)
# Process link_data["cores_matrix"]
...
return {"metric": value, ...}
Testing
- Test Location:
fusion/analysis/tests/- Run Tests:
pytest fusion/analysis/tests/ -v
Unit Tests
All NetworkAnalyzer methods have comprehensive unit tests covering:
Empty network edge cases
Single link scenarios
Multiple links with bidirectional handling
Missing fields and graceful degradation
Parametrized tests for link key formatting
Adding New Tests
Follow the AAA pattern with test classes organized by method:
class TestNewAnalysisMethod:
"""Tests for the new_analysis_method method."""
def test_empty_network_returns_defaults(self) -> None:
"""Test that empty network returns sensible defaults."""
# Arrange
network_spectrum: dict = {}
# Act
result = NetworkAnalyzer.new_analysis_method(network_spectrum)
# Assert
assert result["metric"] == 0