post_process Module#

Module Overview#

This module provides utilities for analyzing and managing results from hierarchical optical network simulations and planning processes.

Its primary responsibilities include:

  • Loading link-level and transceiver-level (BVT) metrics from saved simulation results.

  • Managing results for multiple hierarchy levels (HL2, HL3, HL4, etc.).

  • Providing structured access to network simulation data for further processing or visualization.

  • Acting as a post-processing interface for the SixGman planning framework.

Typical applications include:

  • Post-processing optical network planning simulations

  • Extracting link utilization, spectral efficiency, and BVT deployment data

  • Analyzing results for different hierarchy levels in metro/urban networks

Key Class#

analyse_result#

class sixgman.core.post_process.analyse_result(network_instance, period_time, processing_level_list, results_directory, save_directory)#

Bases: object

” A class for analyzing and managing results from hierarchical optical network simulations.

This class supports loading network planning results for different hierarchy levels, including link-level and transceiver-level (BVT) metrics.

network#

An instance of the Network class defining topology and metadata.

Type:

Network

period_time#

Duration (in years or time units) for planning or simulation.

Type:

int

processing_level_list#

List of hierarchy levels to be analyzed (e.g., [2, 3, 4]).

Type:

List[int]

results_directory#

Directory containing result .npz files for each hierarchy level.

Type:

Path

save_directory#

Directory where output plots will save in.

Type:

Path

Dictionary containing link-level data for each HL.

Type:

Dict[str, np.lib.npyio.NpzFile]

bvt_data#

Dictionary containing transceiver (BVT) data for each HL.

Type:

Dict[str, np.lib.npyio.NpzFile]

__init__(network_instance, period_time, processing_level_list, results_directory, save_directory)#

Initialize the AnalyseResult object.

Args:#

network_instance (Network):

The optical network structure.

period_time (int):

Simulation or planning time period (e.g., 10 years).

processing_level_list (List[int]):

Hierarchy levels to process (e.g., [2, 3, 4]).

results_directory(Path):

Path to the directory where .npz result files are stored.

save_directory (Path):

Path to the directory where output plots will save in.

Example:#

>>> from sixgman.core.optical_result_analyzer import analyse_result
>>> analyser = analyse_result(
...     net, # Network instance
...     10, # Planning period time in years
...     processing_level_list, # List of hierarchy levels to analyze
...     results_dir # Directory where results are saved
... )

Plot or return the evolution of link states (Fiber Pairs numbers) across all hierarchy levels over time.

This function creates a heatmap-style visualization of link states (FP numbers) over a multi-year period, where each row corresponds to a specific link and each column to a simulation year. Vertical dashed lines separate different hierarchical levels using the provided splitter.

Args:#

splitter (List):

A list indicating how many links are in each hierarchy level (used for dashed separators).

save_flag (int):

If 1, the plot will be saved to disk.

save_suffix (str, optional):

Custom suffix for the saved file name. Default is “”.

flag_plot (int, optional):

If 1, show the plot; otherwise, return the data. Default is 1.

Output:#

np.ndarray:

If flag_plot == 0, returns the link state matrix of shape (years, total_links). Each element corresponds to the FP number assigned to a specific link in a given year.

Notes:#

  • When save_flag = 1, the figure is saved in the output directory with the filename pattern {topology_name}_Link_State{save_suffix}.png

  • The visualization allows monitoring the temporal evolution of FP allocation and link utilization across all hierarchical levels.

Example:#

>>> analyser.plot_link_state(
...     splitter, # List of integers indicating the number of links per hierarchy level
...     save_flag = 0, # If 1, save the plot; if 0, do not save
...     ave_suffix = "_NoBypass" # Optional suffix for the saved file name
... )
plot_FP_usage(save_flag, save_suffix='', flag_plot=1)#

Plot and optionally save the Fiber Pair (FP) usage over time across all hierarchy levels.

This function visualizes:
  • The cumulative FP usage in kilometers (left y-axis, log scale)

  • The total number of FPs (right y-axis, linear scale)

Args:#

save_flag (int):

If 1, saves the plot to the result directory.

save_suffix (str):

Optional suffix to append to the saved filename.

flag_plot (int):

If 1, display the plot; if 0, skip plotting.

Output:#

None

Notes:#

  • The cumulative FP usage represents the total deployed fiber length across all active links and years.
    • When save_flag = 1, the figure is stored as {topology_name}_FP_Usage{save_suffix}.png in the result directory.

Example:#

>>> analyser.plot_FP_usage(
...     save_flag = 0, # If 1, save the plot; if 0, do not save
...     save_suffix = "_NoBypass" # Optional suffix for the saved file name
... )
plot_FP_degree(save_flag, save_suffix='', flag_plot=1)#

Plot and optionally save the cumulative Fiber Pair (FP) usage and Band degree types.

This function visualizes:
  • Total FP usage in kilometers (left Y-axis, log scale)

  • Nodal degrees for C-band, SuperC-band, and L-band (right Y-axis, linear scale)

Args:#

save_flag (int):

If 1, saves the plot as an image to the save_directory.

save_suffix (str):

Optional suffix to append to the saved filename.

flag_plot (int):

If 1, plot will be displayed. If 0, no plot is shown.

Output:#

None

Notes:#

  • FP usage represents the total deployed fiber length in kilometers, summed across all links and years.
    • Nodal degree metrics indicate the number of active fiber-pair connections per node in each spectral band.

    • When save_flag = 1, the plot is stored in the results directory with filename pattern {topology_name}_FP_Degree{save_suffix}.png}.

Example:#

>>> analyser.plot_FP_degree(
...     save_flag = 0, # If 1, save the plot; if 0, do not save
...     save_suffix = "_NoBypass" # Optional suffix for the saved file name
... )
plot_bvt_license(save_flag, save_suffix='', flag_plot=1)#

Plot and optionally save the cumulative BVT usage and 100G license allocation over time.

This function visualizes:
  • The cumulative count of BVTs (Bandwidth Variable Transponders) for each band:

    C-Band, SuperC-Band, and L-Band (left Y-axis, log scale).

  • The corresponding allocation of 100G licenses proportionally distributed across

    the bands (right Y-axis, linear scale).

Args:#

save_flag (int):

If 1, saves the plot as an image to the save_directory.

save_suffix (str):

Optional suffix for the saved image filename.

flag_plot (int):

If 1, displays the plot; if 0, skips plotting.

Output:#

None

Notes:#

  • The plotted data reflects cumulative deployment across simulation years, combining all hierarchy levels.
    • 100G license counts are derived proportionally from BVT allocations, assuming four 100G channels per BVT.

    • When save_flag = 1, the plot is saved in the results directory under the filename pattern {topology_name}_BVT_License{save_suffix}.png.

Example:#

>>> analyser.plot_bvt_license(
...     save_flag = 0, # If 1, save the plot; if 0, do not save
...     save_suffix = "_NoBypass" # Optional suffix for the saved file name
... )
calc_cost(save_flag, save_suffix='', C_100GL_First=1, C_100G_Added=0.333, C_MCS=0.7, C_RoB=1.9, C_IRU=0.5)#

Compute OPEX and CAPEX values for network deployment over time.

This function evaluates capital and operational expenditures based on nodal degree evolution and bandwidth resource demands (e.g., BVTs, licenses).

Args:#

save_flag (int):

Whether to save the output CSV file (1) or not (0).

save_suffix (str):

Optional suffix for the saved file name.

C_100GL_First (float):

Unit cost of the first activated 100G license [default = 1].

C_100G_Added (float):

Unit cost of the following activated 100G licenses after the first one [default = 0.333].

C_MCS (float):

Unit cost of a multi-cast switch [default = 0.7].

C_RoB (float):

Unit cost of ROADM on the Blade [default = 1.9].

C_IRU (float):

Cost per km of IRU fiber pair usage [default = 0.5].

Output:#

dict: A dataframe containing columns for OPEX and CAPEX components for different years.

Notes:#

  • The resulting cost dataframe is used for techno-economic analyses of hierarchical optical networks.
    • When save_flag = 1, results are stored as a CSV file named {topology_name}_cost_analyse{save_suffix}.csv in the result directory.

Example:#

>>> analyser.calc_cost(
...     save_flag = 0, # If 1, save the results; if 0, do not save
...     save_suffix = "_NoBypass" # Optional suffix for the saved file name
... ) # Returns a dictionary with OPEX and CAPEX components
compute_E2E_path_latency(node, latency_core_array, destination_core_array, processing_level_list)#

Recursively compute all possible end-to-end (E2E) latency paths from a given core node to its higher-level (top-hierarchy) destination nodes.

This method traces both primary and secondary (dual-home) connectivity paths defined in the input arrays, accumulating the total propagation latency along each possible route. The computation proceeds recursively through hierarchy levels (e.g., HL4 → HL3 → HL2 → HL1), until reaching the top-level standalone HL nodes.

Latency is assumed to be precomputed for each direct connection (typically derived from the physical link distance multiplied by a latency constant, e.g., 5 µs/km).

Args:#

node (int):

Index of the starting node (e.g., a lower-level core or access node).

latency_core_array (np.ndarray):

2D or ragged array where each element [i] stores the per-path latency values (in microseconds) from node i to its directly connected higher-level nodes.

destination_core_array (np.ndarray):

2D or ragged array where each element [i] contains the destination node indices corresponding to the latency entries in latency_core_array[i].

processing_level_list (List[int]):

Ordered list of hierarchy levels (e.g., [1, 2, 3, 4]) used to determine when recursion should terminate (the top-level HL layer).

Output:#

List[Tuple[List[int], float]]:
A list of tuples, where each tuple represents:
  • path_list (List[int]): Node sequence along the E2E path.

  • total_latency (float): Total accumulated latency in microseconds.

Notes:#

  • The recursion terminates when the current node belongs to the top hierarchy

  • Latencies are cumulative: the function sums hop latencies at each recursion step.

  • The function supports dual-homing scenarios by computing both primary and secondary paths defined in destination_core_array.

  • The latency constant (e.g., 5 µs/km) should be applied during the construction of latency_core_array prior to calling this method.

Example

>>> # Suppose each km adds 5 µs latency, and HL4 nodes connect upward
>>> results = planner.compute_E2E_path_latency(
...     node=10,
...     latency_core_array=latency_core_array,
...     destination_core_array=destination_core_array,
...     processing_level_list=[1, 2, 3, 4]
... )
>>> for path, latency in results:
...     print(f"Path: {path}, Total Latency: {latency:.2f} µs")
Path: [10, 8, 5, 1], Total Latency: 1040.0 µs
Path: [10, 7, 3, 1], Total Latency: 960.0 µs
calc_E2E_latency_Total(latency_core_array, destination_core_array, processing_level_list, save_flag, save_suffix='')#

Compute and optionally save the total end-to-end (E2E) latency from the lowest hierarchy-level nodes (e.g., HL4) up to the top-level core nodes (e.g., HL1).

This function iterates over all nodes at the lowest hierarchy level and calls compute_E2E_path_latency() recursively to determine the cumulative latency of all possible paths to top-level destinations. The latency values are derived from the propagation delay (e.g., 5 µs/km) stored in latency_core_array and additional per-level processing delays (default: 200 µs per hierarchy level).

The resulting latencies can optionally be saved to a compressed NumPy .npz file.

Args:#

latency_core_array (np.ndarray):

Array of per-node propagation latencies (in microseconds), where each element [i] contains a list or array of hop latencies from node i to its higher-level destination nodes.

destination_core_array (np.ndarray):

Array of per-node destination indices, corresponding one-to-one with latency_core_array.

processing_level_list (list[int]):

Ordered list of hierarchy levels (e.g., [4, 3, 2, 1]) defining the traversal path from lowest to highest hierarchical layer. The function assumes the first element (e.g., 4) represents the lowest hierarchy level to start from.

save_flag (int):

If set to 1, saves the computed latency results to disk as a compressed .npz file. If 0, results are only returned.

save_suffix (str, optional):

Optional suffix to append to the output filename. For example, if save_suffix=’_test’, the saved file will be named: {topology_name}_latency_test.npz.

Output:#

np.ndarray:

A 1D NumPy array containing the total end-to-end latency (in microseconds) for each lowest-level node path.

Notes:#

  • Each end-to-end latency value includes: 1. Propagation latency accumulated over the full path. 2. Processing overhead added per hierarchy transition (default: 200 µs per hop).

  • The recursion terminates at the top-level standalone HL nodes, as defined in processing_level_list.

  • Saving the results is optional and controlled by save_flag.

Example:#

>>> E2E_latencies = planner.calc_E2E_latency_Total(
...     latency_core_array=latency_core_array,
...     destination_core_array=destination_core_array,
...     processing_level_list=[4, 3, 2, 1],
...     save_flag=1,
...     save_suffix="_final"
... )
>>> print(f"Average E2E latency: {np.mean(E2E_latencies):.2f} µs")
Average E2E latency: 940.23 µs

Key Methods#

  • ``plot_link_state(splitter, save_flag, save_suffix=’’, flag_plot=1)`` Plot or return the evolution of link states (Frequency Plan numbers) across all hierarchy levels over time.

  • ``plot_FP_usage(save_flag, save_suffix=’’, flag_plot=1)`` Plot and optionally save the Fiber Pair (FP) usage over time across all hierarchy levels.

  • ``plot_FP_degree(save_flag, save_suffix=’’, flag_plot=1)`` Plot and optionally save the cumulative Fiber Pair (FP) usage and Band degree types.

  • ``plot_bvt_license(save_flag, save_suffix=’’, flag_plot=1)`` Plot and optionally save the cumulative BVT usage and 100G license allocation over time.

  • ``calc_cost(save_flag, save_suffix=’’, C_100GL_First=1, C_100G_Added=0.333, C_MCS=0.7, C_RoB=1.9, C_IRU=0.5)`` Compute OPEX and CAPEX values for network deployment over time.

  • ``calc_E2E_latency_Total(latency_core_array, destination_core_array, processing_level_list, save_flag, save_suffix=’’)`` Compute end-to-end latency across hierarchical processing levels.