def test_raman_fiber(): """ Test the accuracy of propagating the RamanFiber. """ # spectral information generation power = 1e-3 eqpt_params = load_json(TEST_DIR / 'data' / 'eqpt_config.json') spectral_info_params = eqpt_params['SI'][0] spectral_info_params.pop('power_dbm') spectral_info_params.pop('power_range_db') spectral_info_params.pop('tx_osnr') spectral_info_params.pop('sys_margins') spectral_info_input = create_input_spectral_information(power=power, **spectral_info_params) sim_params = SimParams(**load_json(TEST_DIR / 'data' / 'sim_params.json')) Simulation.set_params(sim_params) fiber = RamanFiber(**load_json(TEST_DIR / 'data' / 'raman_fiber_config.json')) # propagation spectral_info_out = fiber(spectral_info_input) p_signal = [carrier.power.signal for carrier in spectral_info_out.carriers] p_ase = [carrier.power.ase for carrier in spectral_info_out.carriers] p_nli = [carrier.power.nli for carrier in spectral_info_out.carriers] expected_results = read_csv(TEST_DIR / 'data' / 'expected_results_science_utils.csv') assert_allclose(p_signal, expected_results['signal'], rtol=1e-3) assert_allclose(p_ase, expected_results['ase'], rtol=1e-3) assert_allclose(p_nli, expected_results['nli'], rtol=1e-3)
def setup_per_degree(case): """ common setup for degree: returns the dict network for different cases """ json_network = load_json(DATA_DIR / 'testTopology_expected.json') json_network_auto = load_json(DATA_DIR / 'testTopology_auto_design_expected.json') if case == 'no': return json_network elif case == 'all': return json_network_auto elif case == 'Lannion_CAS and all': elem = next(e for e in json_network['elements'] if e['uid'] == 'roadm Lannion_CAS') elem['params'] = { 'per_degree_pch_out_db': { "east edfa in Lannion_CAS to Corlay": -17, "east edfa in Lannion_CAS to Stbrieuc": -18, "east edfa in Lannion_CAS to Morlaix": -21 } } return json_network elif case == 'Lannion_CAS and one': elem = next(e for e in json_network['elements'] if e['uid'] == 'roadm Lannion_CAS') elem['params'] = { 'per_degree_pch_out_db': { "east edfa in Lannion_CAS to Corlay": -17, "east edfa in Lannion_CAS to Stbrieuc": -18 } } return json_network
def test_auto_design_generation_fromxlsgainmode(tmpdir, xls_input, expected_json_output): """ tests generation of topology json test that the build network gives correct results in gain mode """ equipment = load_equipment(eqpt_filename) network = load_network(xls_input, equipment) # in order to test the Eqpt sheet and load gain target, # change the power-mode to False (to be in gain mode) equipment['Span']['default'].power_mode = False # Build the network once using the default power defined in SI in eqpt config p_db = equipment['SI']['default'].power_dbm p_total_db = p_db + lin2db( automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) build_network(network, equipment, p_db, p_total_db) actual_json_output = tmpdir / xls_input.with_name( xls_input.stem + '_auto_design').with_suffix('.json').name save_network(network, actual_json_output) actual = load_json(actual_json_output) unlink(actual_json_output) expected = load_json(expected_json_output) results = compare_networks(expected, actual) assert not results.elements.missing assert not results.elements.extra assert not results.elements.different assert not results.connections.missing assert not results.connections.extra assert not results.connections.different
def test_excel_json_generation(tmpdir, xls_input, expected_json_output): """ tests generation of topology json """ xls_copy = Path(tmpdir) / xls_input.name shutil.copyfile(xls_input, xls_copy) convert_file(xls_copy) actual_json_output = xls_copy.with_suffix('.json') actual = load_json(actual_json_output) unlink(actual_json_output) assert actual == load_json(expected_json_output)
def load_common_data(equipment_filename, topology_filename, simulation_filename, save_raw_network_filename): '''Load common configuration from JSON files''' try: equipment = load_equipment(equipment_filename) network = load_network(topology_filename, equipment) if save_raw_network_filename is not None: save_network(network, save_raw_network_filename) print(f'{ansi_escapes.blue}Raw network (no optimizations) saved to {save_raw_network_filename}{ansi_escapes.reset}') sim_params = SimParams(**load_json(simulation_filename)) if simulation_filename is not None else None if not sim_params: if next((node for node in network if isinstance(node, RamanFiber)), None) is not None: print(f'{ansi_escapes.red}Invocation error:{ansi_escapes.reset} ' f'RamanFiber requires passing simulation params via --sim-params') sys.exit(1) else: Simulation.set_params(sim_params) except exceptions.EquipmentConfigError as e: print(f'{ansi_escapes.red}Configuration error in the equipment library:{ansi_escapes.reset} {e}') sys.exit(1) except exceptions.NetworkTopologyError as e: print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {e}') sys.exit(1) except exceptions.ConfigurationError as e: print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {e}') sys.exit(1) except exceptions.ParametersError as e: print(f'{ansi_escapes.red}Simulation parameters error:{ansi_escapes.reset} {e}') sys.exit(1) except exceptions.ServiceError as e: print(f'{ansi_escapes.red}Service error:{ansi_escapes.reset} {e}') sys.exit(1) return (equipment, network)
def test_excel_service_json_generation(xls_input, expected_json_output): """ test services creation """ equipment = load_equipment(eqpt_filename) network = load_network(DATA_DIR / 'testTopology.xls', equipment) # Build the network once using the default power defined in SI in eqpt config p_db = equipment['SI']['default'].power_dbm p_total_db = p_db + lin2db( automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) build_network(network, equipment, p_db, p_total_db) from_xls = read_service_sheet(xls_input, equipment, network, network_filename=DATA_DIR / 'testTopology.xls') expected = load_json(expected_json_output) results = compare_services(expected, from_xls) assert not results.requests.missing assert not results.requests.extra assert not results.requests.different assert not results.synchronizations.missing assert not results.synchronizations.extra assert not results.synchronizations.different
def test_excel_json_generation(tmpdir, xls_input, expected_json_output): """ tests generation of topology json """ xls_copy = Path(tmpdir) / xls_input.name shutil.copyfile(xls_input, xls_copy) convert_file(xls_copy) actual_json_output = xls_copy.with_suffix('.json') actual = load_json(actual_json_output) unlink(actual_json_output) expected = load_json(expected_json_output) results = compare_networks(expected, actual) assert not results.elements.missing assert not results.elements.extra assert not results.elements.different assert not results.connections.missing assert not results.connections.extra assert not results.connections.different
def test_eqpt_creation(tmpdir): """ tests that convert correctly creates equipment according to equipment sheet including all cominations in testTopologyconvert.xls: if a line exists the amplifier should be created even if no values are provided. """ xls_input = DATA_DIR / 'testTopologyconvert.xls' xls_copy = Path(tmpdir) / xls_input.name shutil.copyfile(xls_input, xls_copy) convert_file(xls_copy) actual_json_output = xls_copy.with_suffix('.json') actual = load_json(actual_json_output) unlink(actual_json_output) connections = { elem['from_node']: elem['to_node'] for elem in actual['connections'] } jsonconverted = {} for elem in actual['elements']: if 'type' in elem.keys() and elem['type'] == 'Edfa': print(elem['uid']) if 'type_variety' in elem.keys(): jsonconverted[elem['uid']] = Amp(elem['uid'], connections[elem['uid']], elem['type_variety']) else: jsonconverted[elem['uid']] = Amp(elem['uid'], connections[elem['uid']]) with open_workbook(xls_input) as wobo: # reading Eqpt sheet assuming header is node A, Node Z, amp variety # fused should not be recorded as an amp eqpt_sheet = wobo.sheet_by_name('Eqpt') raw_eqpts = {} for row in all_rows(eqpt_sheet, start=5): if row[0].value not in raw_eqpts.keys(): raw_eqpts[row[0].value] = Amp(row[0].value, [row[1].value], [row[2].value], [row[7].value]) else: raw_eqpts[row[0].value].to_node.append(row[1].value) raw_eqpts[row[0].value].eqpt.append(row[2].value) raw_eqpts[row[0].value].west.append(row[7].value) # create the possible names similarly to what convert should do possiblename = [f'east edfa in {xlsname} to {node}' for xlsname, value in raw_eqpts.items() for i, node in enumerate(value.to_node) if value.eqpt[i] != 'fused'] +\ [f'west edfa in {xlsname} to {node}' for xlsname, value in raw_eqpts.items() for i, node in enumerate(value.to_node) if value.west[i] != 'fused'] # check that all lines in eqpt sheet correctly converts to an amp element for name in possiblename: assert name in jsonconverted.keys() # check that all amp in the converted files corresponds to an eqpt line for ampuid in jsonconverted.keys(): assert ampuid in possiblename
def test_sim_parameters(): j = load_json(DATA_DIR / 'sim_params.json') sim_params = SimParams(**j) Simulation.set_params(sim_params) s1 = Simulation.get_simulation() assert s1.sim_params.raman_params.flag_raman s2 = Simulation.get_simulation() assert s2.sim_params.raman_params.flag_raman j['raman_parameters']['flag_raman'] = False sim_params = SimParams(**j) Simulation.set_params(sim_params) assert not s2.sim_params.raman_params.flag_raman assert not s1.sim_params.raman_params.flag_raman
def test_auto_design_generation_fromjson(tmpdir, json_input, power_mode): """test that autodesign creates same file as an input file already autodesigned """ equipment = load_equipment(eqpt_filename) network = load_network(json_input, equipment) # in order to test the Eqpt sheet and load gain target, # change the power-mode to False (to be in gain mode) equipment['Span']['default'].power_mode = power_mode # Build the network once using the default power defined in SI in eqpt config p_db = equipment['SI']['default'].power_dbm p_total_db = p_db + lin2db( automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) build_network(network, equipment, p_db, p_total_db) actual_json_output = tmpdir / json_input.with_name( json_input.stem + '_auto_design').with_suffix('.json').name save_network(network, actual_json_output) actual = load_json(actual_json_output) unlink(actual_json_output) assert actual == load_json(json_input)
def test_no_amp_feature(node_uid): ''' Check that booster is not placed on a roadm if fused is specified test_parser covers partly this behaviour. This test should guaranty that the feature is preserved even if convert is changed ''' equipment = load_equipment(EQPT_LIBRARY_NAME) json_network = load_json(NETWORK_FILE_NAME) for elem in json_network['elements']: if elem['uid'] == node_uid: # replace edfa node by a fused node in the topology elem['type'] = 'Fused' elem.pop('type_variety') elem.pop('operational') elem['params'] = {'loss': 0} next_node_uid = next(conn['to_node'] for conn in json_network['connections'] if conn['from_node'] == node_uid) previous_node_uid = next(conn['from_node'] for conn in json_network['connections'] if conn['to_node'] == node_uid) network = network_from_json(json_network, equipment) # Build the network once using the default power defined in SI in eqpt config # power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by # spacing, f_min and f_max p_db = equipment['SI']['default'].power_dbm p_total_db = p_db + lin2db( automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) build_network(network, equipment, p_db, p_total_db) node = next(nd for nd in network.nodes() if nd.uid == node_uid) next_node = next(network.successors(node)) previous_node = next(network.predecessors(node)) if not isinstance(node, Fused): raise AssertionError() if not node.params.loss == 0.0: raise AssertionError() if not next_node_uid == next_node.uid: raise AssertionError() if not previous_node_uid == previous_node.uid: raise AssertionError()
def test_json_response_generation(xls_input, expected_response_file): """ tests if json response is correctly generated for all combinations of requests """ equipment = load_equipment(eqpt_filename) network = load_network(xls_input, equipment) p_db = equipment['SI']['default'].power_dbm p_total_db = p_db + lin2db( automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) build_network(network, equipment, p_db, p_total_db) data = read_service_sheet(xls_input, equipment, network) # change one of the request with bidir option to cover bidir case as well data['path-request'][2]['bidirectional'] = True oms_list = build_oms_list(network, equipment) rqs = requests_from_json(data, equipment) dsjn = disjunctions_from_json(data) dsjn = deduplicate_disjunctions(dsjn) rqs, dsjn = requests_aggregation(rqs, dsjn) pths = compute_path_dsjctn(network, equipment, rqs, dsjn) propagatedpths, reversed_pths, reversed_propagatedpths = \ compute_path_with_disjunction(network, equipment, rqs, pths) pth_assign_spectrum(pths, rqs, oms_list, reversed_pths) result = [] for i, pth in enumerate(propagatedpths): # test ServiceError handling : when M is zero at this point, the # json result should not be created if there is no blocking reason if i == 1: my_rq = deepcopy(rqs[i]) my_rq.M = 0 with pytest.raises(ServiceError): ResultElement(my_rq, pth, reversed_propagatedpths[i]).json my_rq.blocking_reason = 'NO_SPECTRUM' ResultElement(my_rq, pth, reversed_propagatedpths[i]).json result.append(ResultElement(rqs[i], pth, reversed_propagatedpths[i])) temp = {'response': [n.json for n in result]} expected = load_json(expected_response_file) for i, response in enumerate(temp['response']): if i == 2: # compare response must be False because z-a metric is missing # (request with bidir option to cover bidir case) assert not compare_response(expected['response'][i], response) print(f'response {response["response-id"]} should not match') expected['response'][2]['path-properties']['z-a-path-metric'] = [{ 'metric-type': 'SNR-bandwidth', 'accumulative-value': 22.809999999999999 }, { 'metric-type': 'SNR-0.1nm', 'accumulative-value': 26.890000000000001 }, { 'metric-type': 'OSNR-bandwidth', 'accumulative-value': 26.239999999999998 }, { 'metric-type': 'OSNR-0.1nm', 'accumulative-value': 30.32 }, { 'metric-type': 'reference_power', 'accumulative-value': 0.0012589254117941673 }, { 'metric-type': 'path_bandwidth', 'accumulative-value': 60000000000.0 }] # test should be OK now else: assert compare_response(expected['response'][i], response) print(f'response {response["response-id"]} is not correct')
def test_csv_response_generation(tmpdir, json_input): """ tests if generated csv is consistant with expected generation same columns (order not important) """ json_data = load_json(json_input) equipment = load_equipment(eqpt_filename) csv_filename = Path(tmpdir / json_input.name).with_suffix('.csv') with open(csv_filename, 'w', encoding='utf-8') as fcsv: jsontocsv(json_data, equipment, fcsv) expected_csv_filename = json_input.parent / (json_input.stem + '_expected.csv') # expected header # csv_header = \ # [ # 'response-id', # 'source', # 'destination', # 'path_bandwidth', # 'Pass?', # 'nb of tsp pairs', # 'total cost', # 'transponder-type', # 'transponder-mode', # 'OSNR-0.1nm', # 'SNR-0.1nm', # 'SNR-bandwidth', # 'baud rate (Gbaud)', # 'input power (dBm)', # 'path', # 'spectrum (N,M)', # 'reversed path OSNR-0.1nm', # 'reversed path SNR-0.1nm', # 'reversed path SNR-bandwidth' # ] resp = read_csv(csv_filename) print(resp) unlink(csv_filename) expected_resp = read_csv(expected_csv_filename) print(expected_resp) resp_header = list(resp.head(0)) expected_resp_header = list(expected_resp.head(0)) # check that headers are the same resp_header.sort() expected_resp_header.sort() print('headers are differents') print(resp_header) print(expected_resp_header) assert resp_header == expected_resp_header # for each header checks that the output are as expected resp.sort_values(by=['response-id']) expected_resp.sort_values(by=['response-id']) for column in expected_resp: assert list(resp[column].fillna('')) == list( expected_resp[column].fillna('')) print('results are different') print(list(resp[column])) print(list(expected_resp[column])) print(type(list(resp[column])[-1]))
} parser = ArgumentParser() parser.add_argument('expected_output', type=Path, metavar='FILE') parser.add_argument('actual_output', type=Path, metavar='FILE') parser.add_argument('-o', '--output', default=None) parser.add_argument('-c', '--comparison', choices=COMPARISONS, default='networks') def encode_sets(obj): if isinstance(obj, set): return list(obj) raise TypeError(f'{obj!r} is not JSON serializable!') if __name__ == '__main__': args = parser.parse_args() expected = load_json(args.expected_output) actual = load_json(args.actual_output) result = COMPARISONS[args.comparison](expected, actual) if args.output: with open(args.output, 'w', encoding='utf-8') as f: dump(result, f, default=encode_sets, indent=2, ensure_ascii=False) else: print(str(result))
def test_roadm_target_power(prev_node_type, effective_pch_out_db): ''' Check that egress power of roadm is equal to target power if input power is greater than target power else, that it is equal to input power. Use a simple two hops A-B-C topology for the test where the prev_node in ROADM B is either an amplifier or a fused, so that the target power can not be met in this last case. ''' equipment = load_equipment(EQPT_LIBRARY_NAME) json_network = load_json(TEST_DIR / 'data/twohops_roadm_power_test.json') prev_node = next(n for n in json_network['elements'] if n['uid'] == 'west edfa in node B to ila2') json_network['elements'].remove(prev_node) if prev_node_type == 'edfa': prev_node = {'uid': 'west edfa in node B to ila2', 'type': 'Edfa'} elif prev_node_type == 'fused': prev_node = {'uid': 'west edfa in node B to ila2', 'type': 'Fused'} prev_node['params'] = {'loss': 0} json_network['elements'].append(prev_node) network = network_from_json(json_network, equipment) # Build the network once using the default power defined in SI in eqpt config p_db = equipment['SI']['default'].power_dbm p_total_db = p_db + lin2db( automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) build_network(network, equipment, p_db, p_total_db) params = {} params['request_id'] = 0 params['trx_type'] = '' params['trx_mode'] = '' params['source'] = 'trx node A' params['destination'] = 'trx node C' params['bidir'] = False params['nodes_list'] = ['trx node C'] params['loose_list'] = ['strict'] params['format'] = '' params['path_bandwidth'] = 100e9 trx_params = trx_mode_params(equipment) params.update(trx_params) req = PathRequest(**params) path = compute_constrained_path(network, req) si = create_input_spectral_information(req.f_min, req.f_max, req.roll_off, req.baud_rate, req.power, req.spacing) for i, el in enumerate(path): if isinstance(el, Roadm): carriers_power_in_roadm = min([ c.power.signal + c.power.nli + c.power.ase for c in si.carriers ]) si = el(si, degree=path[i + 1].uid) if el.uid == 'roadm node B': print('input', carriers_power_in_roadm) assert el.effective_pch_out_db == effective_pch_out_db for carrier in si.carriers: print(carrier.power.signal + carrier.power.nli + carrier.power.ase) power = carrier.power.signal + carrier.power.nli + carrier.power.ase if prev_node_type == 'edfa': # edfa prev_node sets input power to roadm to a high enough value: # Check that egress power of roadm is equal to target power assert power == pytest.approx( db2lin(effective_pch_out_db - 30), rel=1e-3) elif prev_node_type == 'fused': # fused prev_node does reamplfy power after fiber propagation, so input power # to roadm is low. # Check that egress power of roadm is equalized to the min carrier input power. assert power == pytest.approx(carriers_power_in_roadm, rel=1e-3) else: si = el(si)
def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm): ''' Check that egress power of roadm is equal to target power if input power is greater than target power else, that it is equal to input power. Use a simple two hops A-B-C topology for the test where the prev_node in ROADM B is either an amplifier or a fused, so that the target power can not be met in this last case. ''' equipment = load_equipment(EQPT_LIBRARY_NAME) json_network = load_json(TEST_DIR / 'data/twohops_roadm_power_test.json') prev_node = next(n for n in json_network['elements'] if n['uid'] == 'west edfa in node B to ila2') json_network['elements'].remove(prev_node) if prev_node_type == 'edfa': prev_node = {'uid': 'west edfa in node B to ila2', 'type': 'Edfa'} elif prev_node_type == 'fused': prev_node = {'uid': 'west edfa in node B to ila2', 'type': 'Fused'} prev_node['params'] = {'loss': 0} json_network['elements'].append(prev_node) network = network_from_json(json_network, equipment) p_total_db = power_dbm + lin2db( automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) build_network(network, equipment, power_dbm, p_total_db) params = { 'request_id': 0, 'trx_type': '', 'trx_mode': '', 'source': 'trx node A', 'destination': 'trx node C', 'bidir': False, 'nodes_list': ['trx node C'], 'loose_list': ['strict'], 'format': '', 'path_bandwidth': 100e9, 'effective_freq_slot': None, } trx_params = trx_mode_params(equipment) params.update(trx_params) req = PathRequest(**params) req.power = db2lin(power_dbm - 30) path = compute_constrained_path(network, req) si = create_input_spectral_information(req.f_min, req.f_max, req.roll_off, req.baud_rate, req.power, req.spacing) for i, el in enumerate(path): if isinstance(el, Roadm): carriers_power_in_roadm = min([ c.power.signal + c.power.nli + c.power.ase for c in si.carriers ]) si = el(si, degree=path[i + 1].uid) if el.uid == 'roadm node B': print('input', carriers_power_in_roadm) # if previous was an EDFA, power level at ROADM input is enough for the ROADM to apply its # target power (as specified in equipment ie -20 dBm) # if it is a Fused, the input power to the ROADM is smaller than the target power, and the # ROADM cannot apply this target. In this case, it is assumed that the ROADM has 0 dB loss # so the output power will be the same as the input power, which for this particular case # corresponds to -22dBm + power_dbm # next step (for ROADM modelling) will be to apply a minimum loss for ROADMs ! if prev_node_type == 'edfa': assert el.effective_pch_out_db == effective_pch_out_db if prev_node_type == 'fused': # then output power == input_power == effective_pch_out_db + power_dbm assert effective_pch_out_db + power_dbm == \ pytest.approx(lin2db(carriers_power_in_roadm * 1e3), rel=1e-3) assert el.effective_pch_out_db == effective_pch_out_db + power_dbm for carrier in si.carriers: print(carrier.power.signal + carrier.power.nli + carrier.power.ase) power = carrier.power.signal + carrier.power.nli + carrier.power.ase if prev_node_type == 'edfa': # edfa prev_node sets input power to roadm to a high enough value: # Check that egress power of roadm is equal to target power assert power == pytest.approx( db2lin(effective_pch_out_db - 30), rel=1e-3) elif prev_node_type == 'fused': # fused prev_node does reamplfy power after fiber propagation, so input power # to roadm is low. # Check that egress power of roadm is equalized to the min carrier input power. assert power == pytest.approx(carriers_power_in_roadm, rel=1e-3) else: si = el(si)
def test_restrictions(restrictions, equipment): ''' test that restriction is correctly applied if provided in eqpt_config and if no Edfa type were provided in the network json ''' # add restrictions equipment['Roadm']['default'].restrictions = restrictions # build network json_network = load_json(NETWORK_FILE_NAME) network = network_from_json(json_network, equipment) amp_nodes_nobuild_uid = [ nd.uid for nd in network.nodes() if isinstance(nd, Edfa) and isinstance(next(network.predecessors(nd)), Roadm) ] preamp_nodes_nobuild_uid = [ nd.uid for nd in network.nodes() if isinstance(nd, Edfa) and isinstance(next(network.successors(nd)), Roadm) ] amp_nodes_nobuild = { nd.uid: nd for nd in network.nodes() if isinstance(nd, Edfa) and isinstance(next(network.predecessors(nd)), Roadm) } preamp_nodes_nobuild = { nd.uid: nd for nd in network.nodes() if isinstance(nd, Edfa) and isinstance(next(network.successors(nd)), Roadm) } # roadm dict with restrictions before build roadms = {nd.uid: nd for nd in network.nodes() if isinstance(nd, Roadm)} # Build the network once using the default power defined in SI in eqpt config # power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by # spacing, f_min and f_max p_db = equipment['SI']['default'].power_dbm p_total_db = p_db + lin2db( automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) build_network(network, equipment, p_db, p_total_db) amp_nodes = [ nd for nd in network.nodes() if isinstance(nd, Edfa) and isinstance(next(network.predecessors(nd)), Roadm) and next(network.predecessors(nd)).restrictions['booster_variety_list'] ] preamp_nodes = [ nd for nd in network.nodes() if isinstance(nd, Edfa) and isinstance(next(network.successors(nd)), Roadm) and next(network.successors(nd)).restrictions['preamp_variety_list'] ] # check that previously existing amp are not changed for amp in amp_nodes: if amp.uid in amp_nodes_nobuild_uid: print(amp.uid, amp.params.type_variety) if not amp.params.type_variety == amp_nodes_nobuild[ amp.uid].params.type_variety: raise AssertionError() for amp in preamp_nodes: if amp.uid in preamp_nodes_nobuild_uid: if not amp.params.type_variety == preamp_nodes_nobuild[ amp.uid].params.type_variety: raise AssertionError() # check that restrictions are correctly applied for amp in amp_nodes: if amp.uid not in amp_nodes_nobuild_uid: # and if roadm had no restrictions before build: if restrictions['booster_variety_list'] and \ not roadms[next(network.predecessors(amp)).uid]\ .restrictions['booster_variety_list']: if amp.params.type_variety not in restrictions[ 'booster_variety_list']: raise AssertionError() for amp in preamp_nodes: if amp.uid not in preamp_nodes_nobuild_uid: if restrictions['preamp_variety_list'] and\ not roadms[next(network.successors(amp)).uid].restrictions['preamp_variety_list']: if amp.params.type_variety not in restrictions[ 'preamp_variety_list']: raise AssertionError()