mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-10-30 17:47:50 +00:00
Generic write_csv in utils to save simulation results
tranmsission_main simulation results are saved to simulation_result.csv Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
This commit is contained in:
@@ -19,7 +19,10 @@
|
|||||||
"params": {
|
"params": {
|
||||||
"length": 80,
|
"length": 80,
|
||||||
"loss_coef": 0.2,
|
"loss_coef": 0.2,
|
||||||
"length_units": "km"
|
"length_units": "km",
|
||||||
|
"att_in": 0,
|
||||||
|
"con_in": 0.5,
|
||||||
|
"con_out": 0.5
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"location": {
|
"location": {
|
||||||
@@ -34,8 +37,9 @@
|
|||||||
"type": "Edfa",
|
"type": "Edfa",
|
||||||
"type_variety": "std_low_gain",
|
"type_variety": "std_low_gain",
|
||||||
"operational": {
|
"operational": {
|
||||||
"gain_target": 16,
|
"gain_target": 17,
|
||||||
"tilt_target": 0
|
"tilt_target": 0,
|
||||||
|
"out_voa": 0
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"location": {
|
"location": {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{ "Edfa":[{
|
{ "Edfa":[{
|
||||||
"type_variety": "CienaDB_medium_gain",
|
"type_variety": "high_detail_model_example",
|
||||||
"gain_flatmax": 25,
|
"gain_flatmax": 25,
|
||||||
"gain_min": 15,
|
"gain_min": 15,
|
||||||
"p_max": 21,
|
"p_max": 21,
|
||||||
@@ -8,11 +8,22 @@
|
|||||||
"allowed_for_design": false
|
"allowed_for_design": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"type_variety": "operator_model_example",
|
||||||
|
"type_def": "variable_gain",
|
||||||
|
"gain_flatmax": 26,
|
||||||
|
"gain_min": 15,
|
||||||
|
"p_max": 23,
|
||||||
|
"nf_min": 6,
|
||||||
|
"nf_max": 10,
|
||||||
|
"out_voa_auto": false,
|
||||||
|
"allowed_for_design": false
|
||||||
|
},
|
||||||
|
{
|
||||||
"type_variety": "std_medium_gain",
|
"type_variety": "std_medium_gain",
|
||||||
"type_def": "variable_gain",
|
"type_def": "variable_gain",
|
||||||
"gain_flatmax": 26,
|
"gain_flatmax": 26,
|
||||||
"gain_min": 15,
|
"gain_min": 15,
|
||||||
"p_max": 22,
|
"p_max": 23,
|
||||||
"nf_min": 6,
|
"nf_min": 6,
|
||||||
"nf_max": 10,
|
"nf_max": 10,
|
||||||
"out_voa_auto": false,
|
"out_voa_auto": false,
|
||||||
@@ -21,9 +32,9 @@
|
|||||||
{
|
{
|
||||||
"type_variety": "std_low_gain",
|
"type_variety": "std_low_gain",
|
||||||
"type_def": "variable_gain",
|
"type_def": "variable_gain",
|
||||||
"gain_flatmax": 17,
|
"gain_flatmax": 16,
|
||||||
"gain_min": 8,
|
"gain_min": 8,
|
||||||
"p_max": 22,
|
"p_max": 23,
|
||||||
"nf_min": 6.5,
|
"nf_min": 6.5,
|
||||||
"nf_max": 11,
|
"nf_max": 11,
|
||||||
"out_voa_auto": false,
|
"out_voa_auto": false,
|
||||||
@@ -32,22 +43,12 @@
|
|||||||
{
|
{
|
||||||
"type_variety": "std_fixed_gain",
|
"type_variety": "std_fixed_gain",
|
||||||
"type_def": "fixed_gain",
|
"type_def": "fixed_gain",
|
||||||
"gain_flatmax": 20,
|
"gain_flatmax": 21,
|
||||||
"gain_min": 20,
|
"gain_min": 20,
|
||||||
"p_max": 21,
|
"p_max": 21,
|
||||||
"nf0": 5.5,
|
"nf0": 5.0,
|
||||||
"allowed_for_design": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type_variety": "test",
|
|
||||||
"type_def": "variable_gain",
|
|
||||||
"gain_flatmax": 25,
|
|
||||||
"gain_min": 15,
|
|
||||||
"p_max": 21,
|
|
||||||
"nf_min": 7,
|
|
||||||
"nf_max": 11,
|
|
||||||
"allowed_for_design": false
|
"allowed_for_design": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Fiber":[{
|
"Fiber":[{
|
||||||
"type_variety": "SSMF",
|
"type_variety": "SSMF",
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
],
|
],
|
||||||
"Spans":[{
|
"Spans":[{
|
||||||
"power_mode":true,
|
"power_mode":true,
|
||||||
"delta_power_range_db": [-3,3,1],
|
"delta_power_range_db": [0,0,0.5],
|
||||||
"max_length": 150,
|
"max_length": 150,
|
||||||
"length_units": "km",
|
"length_units": "km",
|
||||||
"max_loss": 28,
|
"max_loss": 28,
|
||||||
@@ -73,11 +74,11 @@
|
|||||||
}],
|
}],
|
||||||
"SI":[{
|
"SI":[{
|
||||||
"f_min": 191.3e12,
|
"f_min": 191.3e12,
|
||||||
"f_max":195.1e12,
|
|
||||||
"baud_rate": 32e9,
|
"baud_rate": 32e9,
|
||||||
|
"f_max":195.1e12,
|
||||||
"spacing": 50e9,
|
"spacing": 50e9,
|
||||||
"power_dbm": 0,
|
"power_dbm": 0,
|
||||||
"power_range_db": [0,0,1],
|
"power_range_db": [0,0,0.5],
|
||||||
"roll_off": 0.15,
|
"roll_off": 0.15,
|
||||||
"OSNR": 11,
|
"OSNR": 11,
|
||||||
"bit_rate":100e9
|
"bit_rate":100e9
|
||||||
@@ -107,7 +108,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type_variety": "Voyager_16QAM",
|
"type_variety": "Voyager",
|
||||||
"frequency":{
|
"frequency":{
|
||||||
"min": 191.35e12,
|
"min": 191.35e12,
|
||||||
"max": 196.1e12
|
"max": 196.1e12
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ propagates a 96 channels comb
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
from gnpy.core.equipment import load_equipment, trx_mode_params
|
from gnpy.core.equipment import load_equipment, trx_mode_params
|
||||||
from gnpy.core.utils import db2lin, lin2db
|
from gnpy.core.utils import db2lin, lin2db, write_csv
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from sys import exit
|
from sys import exit
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from json import loads
|
from json import loads
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from logging import getLogger, basicConfig, INFO, ERROR, DEBUG
|
from logging import getLogger, basicConfig, INFO, ERROR, DEBUG
|
||||||
from numpy import arange
|
from numpy import arange, mean
|
||||||
from matplotlib.pyplot import show, axis, figure, title
|
from matplotlib.pyplot import show, axis, figure, title
|
||||||
from networkx import (draw_networkx_nodes, draw_networkx_edges,
|
from networkx import (draw_networkx_nodes, draw_networkx_edges,
|
||||||
draw_networkx_labels, dijkstra_path)
|
draw_networkx_labels, dijkstra_path)
|
||||||
@@ -49,6 +49,23 @@ def plot_results(network, path, source, destination):
|
|||||||
|
|
||||||
|
|
||||||
def main(network, equipment, source, destination, req = None):
|
def main(network, equipment, source, destination, req = None):
|
||||||
|
result_dicts = {}
|
||||||
|
network_data = [{
|
||||||
|
'network_name' : str(args.filename),
|
||||||
|
'source' : source.uid,
|
||||||
|
'destination' : destination.uid
|
||||||
|
}]
|
||||||
|
result_dicts.update({'network': network_data})
|
||||||
|
design_data = [{
|
||||||
|
'power_mode' : equipment['Spans']['default'].power_mode,
|
||||||
|
'span_power_range' : equipment['Spans']['default'].delta_power_range_db,
|
||||||
|
'design_pch' : equipment['SI']['default'].power_dbm,
|
||||||
|
'baud_rate' : equipment['SI']['default'].baud_rate
|
||||||
|
}]
|
||||||
|
result_dicts.update({'design': design_data})
|
||||||
|
simulation_data = []
|
||||||
|
result_dicts.update({'simulation results': simulation_data})
|
||||||
|
|
||||||
power_mode = equipment['Spans']['default'].power_mode
|
power_mode = equipment['Spans']['default'].power_mode
|
||||||
print('\n'.join([f'Power mode is set to {power_mode}',
|
print('\n'.join([f'Power mode is set to {power_mode}',
|
||||||
f'=> it can be modified in eqpt_config.json - Spans']))
|
f'=> it can be modified in eqpt_config.json - Spans']))
|
||||||
@@ -69,7 +86,6 @@ def main(network, equipment, source, destination, req = None):
|
|||||||
power_range = [0] #better than an error message
|
power_range = [0] #better than an error message
|
||||||
else:
|
else:
|
||||||
power_range.append(last)
|
power_range.append(last)
|
||||||
print(power_range)
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]')
|
print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]')
|
||||||
power_range = [0]
|
power_range = [0]
|
||||||
@@ -80,6 +96,14 @@ def main(network, equipment, source, destination, req = None):
|
|||||||
propagate(path, req, equipment, show=len(power_range)==1)
|
propagate(path, req, equipment, show=len(power_range)==1)
|
||||||
print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :')
|
print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :')
|
||||||
print(destination)
|
print(destination)
|
||||||
|
simulation_data.append({
|
||||||
|
'Pch_dBm' : pref_ch_db + dp_db,
|
||||||
|
'OSNR_ASE_0.1nm' : round(mean(destination.osnr_ase_01nm),2),
|
||||||
|
'OSNR_ASE_signal_bw' : round(mean(destination.osnr_ase),2),
|
||||||
|
'SNR_nli_signal_bw' : round(mean(destination.osnr_nli),2),
|
||||||
|
'SNR_total_signal_bw' : round(mean(destination.snr),2)
|
||||||
|
})
|
||||||
|
write_csv(result_dicts, 'simulation_result.csv')
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -462,8 +462,9 @@ class Edfa(Node):
|
|||||||
return '\n'.join([f'{type(self).__name__} {self.uid}',
|
return '\n'.join([f'{type(self).__name__} {self.uid}',
|
||||||
f' type_variety: {self.params.type_variety}',
|
f' type_variety: {self.params.type_variety}',
|
||||||
f' effective gain(dB): {self.effective_gain:.2f}',
|
f' effective gain(dB): {self.effective_gain:.2f}',
|
||||||
|
f' (before att_in and before output VOA)',
|
||||||
f' noise figure (dB): {nf:.2f}',
|
f' noise figure (dB): {nf:.2f}',
|
||||||
f' including att_in',
|
f' (including att_in)',
|
||||||
f' pad att_in (dB): {self.att_in:.2f}',
|
f' pad att_in (dB): {self.att_in:.2f}',
|
||||||
f' Power In (dBm): {self.pin_db:.2f}',
|
f' Power In (dBm): {self.pin_db:.2f}',
|
||||||
f' Power Out (dBm): {self.pout_db:.2f}',
|
f' Power Out (dBm): {self.pout_db:.2f}',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ def trx_mode_params(equipment, trx_type_variety='', trx_mode='', error_message=F
|
|||||||
trx_params['nb_channel'] = automatic_nch(trx_params['frequency']['min'],
|
trx_params['nb_channel'] = automatic_nch(trx_params['frequency']['min'],
|
||||||
trx_params['frequency']['max'],
|
trx_params['frequency']['max'],
|
||||||
trx_params['spacing'])
|
trx_params['spacing'])
|
||||||
|
print('N channels = ', trx_params['nb_channel'])
|
||||||
return trx_params
|
return trx_params
|
||||||
|
|
||||||
def automatic_spacing(baud_rate):
|
def automatic_spacing(baud_rate):
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ This module contains utility functions that are used with gnpy.
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from csv import writer
|
||||||
from numpy import pi, cos, sqrt, log10
|
from numpy import pi, cos, sqrt, log10
|
||||||
from scipy import constants
|
from scipy import constants
|
||||||
|
|
||||||
@@ -26,6 +27,44 @@ def save_json(obj, filename):
|
|||||||
with open(filename, 'w') as f:
|
with open(filename, 'w') as f:
|
||||||
json.dump(obj, f, indent=2)
|
json.dump(obj, f, indent=2)
|
||||||
|
|
||||||
|
def write_csv(obj, filename):
|
||||||
|
"""
|
||||||
|
convert dictionary items to a csv file
|
||||||
|
the dictionary format :
|
||||||
|
|
||||||
|
{'result category 1':
|
||||||
|
[
|
||||||
|
# 1st line of results
|
||||||
|
{'header 1' : value_xxx,
|
||||||
|
'header 2' : value_yyy},
|
||||||
|
# 2nd line of results: same headers, different results
|
||||||
|
{'header 1' : value_www,
|
||||||
|
'header 2' : value_zzz}
|
||||||
|
],
|
||||||
|
'result_category 2':
|
||||||
|
[
|
||||||
|
{},{}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
the generated csv file will be:
|
||||||
|
result_category 1
|
||||||
|
header 1 header 2
|
||||||
|
value_xxx value_yyy
|
||||||
|
value_www value_zzz
|
||||||
|
result_category 2
|
||||||
|
...
|
||||||
|
"""
|
||||||
|
with open(filename, 'w') as f:
|
||||||
|
w = writer(f)
|
||||||
|
for data_key, data_list in obj.items():
|
||||||
|
#main header
|
||||||
|
w.writerow([data_key])
|
||||||
|
#sub headers:
|
||||||
|
headers = [_ for _ in data_list[0].keys()]
|
||||||
|
w.writerow(headers)
|
||||||
|
for data_dict in data_list:
|
||||||
|
w.writerow([_ for _ in data_dict.values()])
|
||||||
|
|
||||||
def c():
|
def c():
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user