mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-10-30 17:47:50 +00:00
Compare commits
286 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d236fd31e | ||
|
|
9a84e29433 | ||
|
|
143f63170e | ||
|
|
b2d7f883a1 | ||
|
|
73dbdf3042 | ||
|
|
4a071c53d7 | ||
|
|
dcde64a8db | ||
|
|
38cc0e3cc5 | ||
|
|
fb70413784 | ||
|
|
87e10c240e | ||
|
|
43c1085be6 | ||
|
|
4ace60bea2 | ||
|
|
f950a6aee8 | ||
|
|
fb4195c775 | ||
|
|
29f42666e5 | ||
|
|
9bf7f336e3 | ||
|
|
eed6564f11 | ||
|
|
fbb2f2c587 | ||
|
|
44040c4d06 | ||
|
|
ee9af69558 | ||
|
|
ce21609fec | ||
|
|
a1289e6a9b | ||
|
|
138115e1d7 | ||
|
|
ed41305f55 | ||
|
|
9736f7c032 | ||
|
|
be7ae35db3 | ||
|
|
2b4a4ab72c | ||
|
|
426c88432d | ||
|
|
2a800b781f | ||
|
|
8d1d3677ed | ||
|
|
5b6f8c60cf | ||
|
|
3a733b1fd5 | ||
|
|
2d68b94a46 | ||
|
|
bc71823bd0 | ||
|
|
5481b93728 | ||
|
|
05e301182d | ||
|
|
47c89626e3 | ||
|
|
7a032a63b5 | ||
|
|
f195d5f496 | ||
|
|
56569f866f | ||
|
|
bf1f293043 | ||
|
|
28871c6f2d | ||
|
|
d7c1a6b75e | ||
|
|
c69c2a3af2 | ||
|
|
fb29d72906 | ||
|
|
30a06da6b1 | ||
|
|
139c8cc1e7 | ||
|
|
7034d4c686 | ||
|
|
10164495b9 | ||
|
|
87211b35e9 | ||
|
|
e9f9ddb4d6 | ||
|
|
8ea13bb4d6 | ||
|
|
b45829d2df | ||
|
|
6ac3a517cf | ||
|
|
2f2920a716 | ||
|
|
07fd89351b | ||
|
|
7c60b000b5 | ||
|
|
537eb017b5 | ||
|
|
9c514e8086 | ||
|
|
78efb6c650 | ||
|
|
3510d59250 | ||
|
|
41d9d156a6 | ||
|
|
e9d5e748e4 | ||
|
|
5a5bed56c2 | ||
|
|
22de1b1281 | ||
|
|
73e1485b47 | ||
|
|
22ee05ea6f | ||
|
|
31824f318d | ||
|
|
b0cb604e91 | ||
|
|
79102e283a | ||
|
|
db5e63d51b | ||
|
|
af42699133 | ||
|
|
4ba77d0a0a | ||
|
|
064d3af8e0 | ||
|
|
4ab5bac45f | ||
|
|
bbe5fb7821 | ||
|
|
edf1eec072 | ||
|
|
88ac41f721 | ||
|
|
c20e6fb320 | ||
|
|
05500c7047 | ||
|
|
86a39f4b5e | ||
|
|
2b25609255 | ||
|
|
7e0b95bcfd | ||
|
|
f0a52dcc8a | ||
|
|
3bea4b3c9f | ||
|
|
f2cc9f7225 | ||
|
|
e79f9f51b6 | ||
|
|
7fd7f94efe | ||
|
|
0acdf9d9f6 | ||
|
|
a3edb20142 | ||
|
|
33cc11b85c | ||
|
|
5d079ab261 | ||
|
|
a3b1157e38 | ||
|
|
70731b64d6 | ||
|
|
4ea0180caf | ||
|
|
eb2363a3d4 | ||
|
|
41b94cc888 | ||
|
|
1eeb6a0583 | ||
|
|
215c20e245 | ||
|
|
76e9146043 | ||
|
|
2a07eec966 | ||
|
|
cc994bf118 | ||
|
|
37e70e622c | ||
|
|
7d9a508955 | ||
|
|
185adabd77 | ||
|
|
8f9cf8ccc7 | ||
|
|
0c797a254c | ||
|
|
2cdeeabfa6 | ||
|
|
5e874798cb | ||
|
|
ff8f044064 | ||
|
|
d84ee4e76c | ||
|
|
521d27ffac | ||
|
|
35e759212e | ||
|
|
f6dede2b5f | ||
|
|
0d0019f627 | ||
|
|
06fe1c2f63 | ||
|
|
092316a9d7 | ||
|
|
48e3f96967 | ||
|
|
e9e8956caf | ||
|
|
0ae341c2a5 | ||
|
|
0c2f6372f8 | ||
|
|
97e80b4445 | ||
|
|
5e4c9b7d73 | ||
|
|
e96f821cce | ||
|
|
5f7e61e255 | ||
|
|
682b5c5691 | ||
|
|
11e5117505 | ||
|
|
50603420fc | ||
|
|
125264f265 | ||
|
|
b1067a6266 | ||
|
|
50d4ecd700 | ||
|
|
9f37e0371e | ||
|
|
9bd303db05 | ||
|
|
1bcb3ce25c | ||
|
|
e381138320 | ||
|
|
b450677709 | ||
|
|
54a3725e17 | ||
|
|
8889c2437a | ||
|
|
8bf8b2947b | ||
|
|
cb85b8fe2b | ||
|
|
18610fb7a9 | ||
|
|
bd6b278dd1 | ||
|
|
e143d25339 | ||
|
|
ffc7dbc241 | ||
|
|
b842898baf | ||
|
|
7ea9e3b341 | ||
|
|
fcf168b361 | ||
|
|
a7ec7e2ed6 | ||
|
|
00ee102b3a | ||
|
|
ce11524ad9 | ||
|
|
74be14562a | ||
|
|
16694d0a09 | ||
|
|
33c6038921 | ||
|
|
119c9eda90 | ||
|
|
b63e146bf4 | ||
|
|
09dba8a166 | ||
|
|
7f5043622b | ||
|
|
6ad4593f41 | ||
|
|
706661d801 | ||
|
|
a408d28911 | ||
|
|
b86fe96032 | ||
|
|
43926518ad | ||
|
|
128a6e816b | ||
|
|
44db951261 | ||
|
|
3c3d919b77 | ||
|
|
2079d2bc5b | ||
|
|
062e2076ed | ||
|
|
1dd1bad273 | ||
|
|
5b104af296 | ||
|
|
f170574abf | ||
|
|
a68e8ff8d2 | ||
|
|
d5a52d1b2b | ||
|
|
7ac6e058ec | ||
|
|
74ab3c1bcd | ||
|
|
1a2ff2d215 | ||
|
|
aaf0480e9c | ||
|
|
5e50ffbbf6 | ||
|
|
243b701391 | ||
|
|
bdbfe76aed | ||
|
|
541ec04444 | ||
|
|
bf1522b047 | ||
|
|
3f4188a0fd | ||
|
|
8b387ef722 | ||
|
|
cad9a0f18e | ||
|
|
ab84c77363 | ||
|
|
62fa9ab0b0 | ||
|
|
14591c7a11 | ||
|
|
587932290d | ||
|
|
82b148eb87 | ||
|
|
8393daf67d | ||
|
|
be61dfd094 | ||
|
|
77925b218e | ||
|
|
4621ac12bf | ||
|
|
09920c0af2 | ||
|
|
e6a3d9ce5b | ||
|
|
b9645702c8 | ||
|
|
9c2095b138 | ||
|
|
cb42115230 | ||
|
|
5909da4bbf | ||
|
|
2ba1e86b28 | ||
|
|
3358c5eeb5 | ||
|
|
13e4c29bc1 | ||
|
|
4becc9060c | ||
|
|
32d8b2a4d8 | ||
|
|
399eb9700f | ||
|
|
82f83e1462 | ||
|
|
171450fa54 | ||
|
|
9f9f4c78fc | ||
|
|
c469a8d9ba | ||
|
|
99b2a554dc | ||
|
|
57e98d7173 | ||
|
|
78b45a3958 | ||
|
|
64b6b486a9 | ||
|
|
65cb46f479 | ||
|
|
f94d06f124 | ||
|
|
e1f2c55942 | ||
|
|
d28c67143e | ||
|
|
6bb9ae8336 | ||
|
|
0dc7d853ef | ||
|
|
dec9388416 | ||
|
|
017b35fa33 | ||
|
|
cb0a410418 | ||
|
|
f250990a49 | ||
|
|
280443f17f | ||
|
|
6f62251cb4 | ||
|
|
5ad54879b1 | ||
|
|
825d37c05c | ||
|
|
3ac9f90914 | ||
|
|
dbfbf115ff | ||
|
|
ad2590962b | ||
|
|
a9d530c776 | ||
|
|
f255c31f1f | ||
|
|
80ec05f84c | ||
|
|
22541d65e4 | ||
|
|
26fcf0ff6e | ||
|
|
1c32e437a2 | ||
|
|
718007b3de | ||
|
|
4d6c06340f | ||
|
|
bad893bf86 | ||
|
|
75e7fca8e4 | ||
|
|
4e38ba98ab | ||
|
|
fdcdfca589 | ||
|
|
299ca10a47 | ||
|
|
c0b7bf714e | ||
|
|
7f7c568160 | ||
|
|
9bf6ed953a | ||
|
|
e68dc39ddd | ||
|
|
f8007b41d1 | ||
|
|
228125029e | ||
|
|
d185e0c241 | ||
|
|
357bbec257 | ||
|
|
d25e98c567 | ||
|
|
397411690e | ||
|
|
4ab6f8cb1b | ||
|
|
44aff147db | ||
|
|
a36b139065 | ||
|
|
141fc66d47 | ||
|
|
53f29957fd | ||
|
|
9f3995ee20 | ||
|
|
0cf45bd102 | ||
|
|
55932ee3e9 | ||
|
|
797a0856ec | ||
|
|
3fa53adc4d | ||
|
|
bcb5e6bb60 | ||
|
|
6380f8f37a | ||
|
|
93869d6cb5 | ||
|
|
ce51a4d160 | ||
|
|
601e228bb6 | ||
|
|
3f58cbd559 | ||
|
|
2e3274ac78 | ||
|
|
e33144f8cc | ||
|
|
fd1e3f0f61 | ||
|
|
80c41264cf | ||
|
|
a051a5723b | ||
|
|
bd025f3af4 | ||
|
|
c3e546abe3 | ||
|
|
9427d0b139 | ||
|
|
89f5b12f7e | ||
|
|
9d2c10e267 | ||
|
|
305620e5dd | ||
|
|
c91c5d622f | ||
|
|
24e7f4a5a1 | ||
|
|
08c922a5e5 | ||
|
|
efd7468d42 | ||
|
|
902cfa11a7 | ||
|
|
24c6acc027 |
@@ -1,47 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
IMAGE_NAME=telecominfraproject/oopt-gnpy
|
||||
IMAGE_TAG=$(git describe --tags)
|
||||
|
||||
ALREADY_FOUND=0
|
||||
docker pull ${IMAGE_NAME}:${IMAGE_TAG} && ALREADY_FOUND=1
|
||||
|
||||
if [[ $ALREADY_FOUND == 0 ]]; then
|
||||
docker build . -t ${IMAGE_NAME}
|
||||
docker tag ${IMAGE_NAME} ${IMAGE_NAME}:${IMAGE_TAG}
|
||||
|
||||
# shared directory setup: do not clobber the real data
|
||||
mkdir trash
|
||||
cd trash
|
||||
docker run -it --rm --volume $(pwd):/shared ${IMAGE_NAME} gnpy-transmission-example
|
||||
else
|
||||
echo "Image ${IMAGE_NAME}:${IMAGE_TAG} already available, will just update the other tags"
|
||||
fi
|
||||
|
||||
docker images
|
||||
|
||||
do_docker_login() {
|
||||
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
|
||||
}
|
||||
|
||||
if [[ "${TRAVIS_PULL_REQUEST}" == "false" ]]; then
|
||||
if [[ "${TRAVIS_BRANCH}" == "develop" || "${TRAVIS_BRANCH}" == "docker" ]]; then
|
||||
echo "Publishing latest"
|
||||
docker tag ${IMAGE_NAME}:${IMAGE_TAG} ${IMAGE_NAME}:latest
|
||||
do_docker_login
|
||||
if [[ $ALREADY_FOUND == 0 ]]; then
|
||||
docker push ${IMAGE_NAME}:${IMAGE_TAG}
|
||||
fi
|
||||
docker push ${IMAGE_NAME}:latest
|
||||
elif [[ "${TRAVIS_BRANCH}" == "master" ]]; then
|
||||
echo "Publishing stable"
|
||||
docker tag ${IMAGE_NAME}:${IMAGE_TAG} ${IMAGE_NAME}:stable
|
||||
do_docker_login
|
||||
if [[ $ALREADY_FOUND == 0 ]]; then
|
||||
docker push ${IMAGE_NAME}:${IMAGE_TAG}
|
||||
fi
|
||||
docker push ${IMAGE_NAME}:stable
|
||||
fi
|
||||
fi
|
||||
84
.github/workflows/main.yml
vendored
84
.github/workflows/main.yml
vendored
@@ -11,35 +11,43 @@ jobs:
|
||||
name: Tox test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: fedora-python/tox-github-action@v0.4
|
||||
- uses: fedora-python/tox-github-action@v37.0
|
||||
with:
|
||||
tox_env: ${{ matrix.tox_env }}
|
||||
dnf_install: ${{ matrix.dnf_install }}
|
||||
- uses: codecov/codecov-action@v3.1.1
|
||||
if: ${{ endswith(matrix.tox_env, '-cover') }}
|
||||
with:
|
||||
files: ${{ github.workspace }}/cover/coverage.xml
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tox_env:
|
||||
- py38
|
||||
- py39
|
||||
- py310
|
||||
- py311
|
||||
- py312-cover
|
||||
include:
|
||||
- tox_env: docs
|
||||
dnf_install: graphviz
|
||||
|
||||
pypi:
|
||||
needs: build
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') }}
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.repository_owner == 'Telecominfraproject' }}
|
||||
name: PyPI packaging
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/setup-python@v4
|
||||
name: Install Python
|
||||
with:
|
||||
python-version: '3.9'
|
||||
python-version: '3.12'
|
||||
- uses: casperdcl/deploy-pypi@bb869aafd89f657ceaafe9561d3b5584766c0f95
|
||||
with:
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
@@ -48,7 +56,7 @@ jobs:
|
||||
|
||||
docker:
|
||||
needs: build
|
||||
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v'))
|
||||
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')) && github.repository_owner == 'Telecominfraproject' }}
|
||||
name: Docker image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -57,31 +65,81 @@ jobs:
|
||||
with:
|
||||
username: jktjkt
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Extract tag name
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
id: extract_pretty_git
|
||||
run: echo ::set-output name=GIT_DESC::$(git describe --tags)
|
||||
- name: Build and push a container
|
||||
uses: docker/build-push-action@v2
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
telecominfraproject/oopt-gnpy:dev-${{ steps.extract_pretty_git.outputs.GIT_DESC }}
|
||||
telecominfraproject/oopt-gnpy:${{ steps.extract_pretty_git.outputs.GIT_DESC }}
|
||||
telecominfraproject/oopt-gnpy:master
|
||||
- name: Extract tag name
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||
id: extract_tag_name
|
||||
run: echo ::set-output name=GIT_DESC::${GITHUB_REF/refs\/tags\//}
|
||||
- name: Build and push a container
|
||||
uses: docker/build-push-action@v2
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
telecominfraproject/oopt-gnpy:${{ steps.extract_tag_name.outputs.GIT_DESC }}
|
||||
telecominfraproject/oopt-gnpy:latest
|
||||
|
||||
other-platforms:
|
||||
name: Tests on other platforms
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python_version }}
|
||||
- run: |
|
||||
pip install --editable .[tests]
|
||||
pytest -vv
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: windows-2019
|
||||
python_version: "3.10"
|
||||
- os: windows-2022
|
||||
python_version: "3.11"
|
||||
- os: windows-2022
|
||||
python_version: "3.12"
|
||||
- os: macos-12
|
||||
python_version: "3.11"
|
||||
- os: macos-13
|
||||
python_version: "3.12"
|
||||
|
||||
paywalled-platforms:
|
||||
name: Tests on paywalled platforms
|
||||
if: github.repository_owner == 'Telecominfraproject'
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python_version }}
|
||||
- run: |
|
||||
pip install --editable .[tests]
|
||||
pytest -vv
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-13-xlarge # Apple M1 CPU
|
||||
python_version: "3.12"
|
||||
|
||||
3
.lgtm.yml
Normal file
3
.lgtm.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
queries:
|
||||
- exclude: py/clear-text-logging-sensitive-data
|
||||
- exclude: py/clear-text-storage-sensitive-data
|
||||
@@ -1,5 +1,17 @@
|
||||
version: 2
|
||||
build:
|
||||
image: latest
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.12"
|
||||
apt_packages:
|
||||
- graphviz
|
||||
|
||||
python:
|
||||
version: 3.8
|
||||
requirements_file: docs/requirements.txt
|
||||
install:
|
||||
- method: pip
|
||||
path: .
|
||||
extra_requirements:
|
||||
- docs
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
29
.travis.yml
29
.travis.yml
@@ -1,29 +0,0 @@
|
||||
dist: focal
|
||||
os: linux
|
||||
language: python
|
||||
services: docker
|
||||
python:
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
before_install:
|
||||
- sudo apt-get -y install graphviz
|
||||
install: skip
|
||||
script:
|
||||
- pip install --editable .
|
||||
- pip install pytest-cov rstcheck
|
||||
- pytest --cov-report=xml --cov=gnpy -v
|
||||
- pip install -r docs/requirements.txt
|
||||
- rstcheck --ignore-roles cite *.rst
|
||||
- sphinx-build -W --keep-going docs/ x-throwaway-location
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
jobs:
|
||||
include:
|
||||
- stage: test
|
||||
name: Docker image
|
||||
script:
|
||||
- git fetch --unshallow
|
||||
- ./.docker-travis.sh
|
||||
- docker images
|
||||
33
.zuul.yaml
33
.zuul.yaml
@@ -2,24 +2,33 @@
|
||||
- project:
|
||||
check:
|
||||
jobs:
|
||||
- tox-py38-cover
|
||||
- tox-py38:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- tox-py39:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- tox-py310-cover:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- tox-docs-f36:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- coverage-diff:
|
||||
voting: false
|
||||
dependencies:
|
||||
- tox-py38-cover-previous
|
||||
- tox-py38-cover
|
||||
- tox-py310-cover-previous
|
||||
- tox-py310-cover
|
||||
vars:
|
||||
coverage_job_name_previous: tox-py38-cover-previous
|
||||
coverage_job_name_current: tox-py38-cover
|
||||
coverage_job_name_previous: tox-py310-cover-previous
|
||||
coverage_job_name_current: tox-py310-cover
|
||||
- tox-linters-diff-n-report:
|
||||
voting: false
|
||||
- tox-py36-el8
|
||||
- tox-docs-f32
|
||||
- tox-py38-cover-previous
|
||||
gate:
|
||||
jobs:
|
||||
- tox-py38-f32
|
||||
- tox-docs-f32
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- tox-py310-cover-previous:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
tag:
|
||||
jobs:
|
||||
- oopt-release-python:
|
||||
|
||||
@@ -11,18 +11,21 @@ To learn how to contribute, please see CONTRIBUTING.md
|
||||
- Brian Taylor (Facebook) <briantaylor@fb.com>
|
||||
- David Boertjes (Ciena) <dboertje@ciena.com>
|
||||
- Diego Landa (Facebook) <dlanda@fb.com>
|
||||
- Emmanuelle Delfour (Orange) <WEDE7391@orange.com>
|
||||
- Esther Le Rouzic (Orange) <esther.lerouzic@orange.com>
|
||||
- Gabriele Galimberti (Cisco) <ggalimbe@cisco.com>
|
||||
- Gert Grammel (Juniper Networks) <ggrammel@juniper.net>
|
||||
- Giacomo Borraccini (Politecnico di Torino) <giacomo.borraccini@polito.it>
|
||||
- Gilad Goldfarb (Facebook) <giladg@fb.com>
|
||||
- James Powell (Telecom Infra Project) <james.powell@telecominfraproject.com>
|
||||
- Jan Kundrát (Telecom Infra Project) <jan.kundrat@telecominfraproject.com>
|
||||
- Jan Kundrát (Telecom Infra Project) <jkt@jankundrat.com>
|
||||
- Jeanluc Augé (Orange) <jeanluc.auge@orange.com>
|
||||
- Jonas Mårtensson (RISE) <jonas.martensson@ri.se>
|
||||
- Mattia Cantono (Politecnico di Torino) <mattia.cantono@polito.it>
|
||||
- Miguel Garrich (University Catalunya) <miquel.garrich@upct.es>
|
||||
- Raj Nagarajan (Lumentum) <raj.nagarajan@lumentum.com>
|
||||
- Roberts Miculens (Lattelecom) <roberts.miculens@lattelecom.lv>
|
||||
- Sami Alavi (NUST) <sami.mansooralavi1999@gmail.com>
|
||||
- Shengxiang Zhu (University of Arizona) <szhu@email.arizona.edu>
|
||||
- Stefan Melin (Telia Company) <Stefan.Melin@teliacompany.com>
|
||||
- Vittorio Curri (Politecnico di Torino) <vittorio.curri@polito.it>
|
||||
|
||||
12
README.md
12
README.md
@@ -3,12 +3,12 @@
|
||||
[](https://pypi.org/project/gnpy/)
|
||||
[](https://pypi.org/project/gnpy/)
|
||||
[](http://gnpy.readthedocs.io/en/master/?badge=master)
|
||||
[](https://github.com/Telecominfraproject/oopt-gnpy/actions/workflows/main.yml)
|
||||
[](https://github.com/Telecominfraproject/oopt-gnpy/actions/workflows/main.yml)
|
||||
[](https://review.gerrithub.io/q/project:Telecominfraproject/oopt-gnpy+is:open)
|
||||
[](https://github.com/Telecominfraproject/oopt-gnpy/graphs/contributors)
|
||||
[](https://lgtm.com/projects/g/Telecominfraproject/oopt-gnpy/)
|
||||
[](https://codecov.io/gh/Telecominfraproject/oopt-gnpy)
|
||||
[](https://doi.org/10.5281/zenodo.3458319)
|
||||
[](https://matrix.to/#/%23oopt-gnpy%3Amatrix.org?via=matrix.org)
|
||||
|
||||
GNPy is an open-source, community-developed library for building route planning and optimization tools in real-world mesh optical networks.
|
||||
We are a consortium of operators, vendors, and academic researchers sponsored via the [Telecom Infra Project](http://telecominfraproject.com)'s [OOPT/PSE](https://telecominfraproject.com/open-optical-packet-transport) working group.
|
||||
@@ -18,12 +18,14 @@ Together, we are building this tool for rapid development of production-grade ro
|
||||
|
||||
## Quick Start
|
||||
|
||||
Install either via [Docker](docs/install.rst#install-docker), or as a [Python package](docs/install.rst#install-pip).
|
||||
Install either via [Docker](https://gnpy.readthedocs.io/en/master/install.html#using-prebuilt-docker-images), or as a [Python package](https://gnpy.readthedocs.io/en/master/install.html#using-python-on-your-computer).
|
||||
Read our [documentation](https://gnpy.readthedocs.io/), learn from the demos, and [get in touch with us](https://github.com/Telecominfraproject/oopt-gnpy/discussions).
|
||||
|
||||
This example demonstrates how GNPy can be used to check the expected SNR at the end of the line by varying the channel input power:
|
||||
|
||||
[](https://asciinema.org/a/252295)
|
||||

|
||||
|
||||
GNPy can do much more, including acting as a Path Computation Engine, tracking bandwidth requests, or advising the SDN controller about a best possible path through a large DWDM network.
|
||||
Learn more about this [in the documentation](https://gnpy.readthedocs.io/).
|
||||
Learn more about this [in the documentation](https://gnpy.readthedocs.io/), or give it a [try online at `gnpy.app`](https://gnpy.app/):
|
||||
|
||||
[](https://gnpy.app/)
|
||||
|
||||
@@ -7,11 +7,12 @@ There are weekly calls about our progress.
|
||||
Newcomers, users and telecom operators are especially welcome there.
|
||||
We encourage all interested people outside the TIP to [join the project](https://telecominfraproject.com/apply-for-membership/) and especially to [get in touch with us](https://github.com/Telecominfraproject/oopt-gnpy/discussions).
|
||||
|
||||
(contributing)=
|
||||
## Contributing
|
||||
|
||||
`gnpy` is looking for additional contributors, especially those with experience planning and maintaining large-scale, real-world mesh optical networks.
|
||||
|
||||
To get involved, please contact [Jan Kundrát](mailto:jan.kundrat@telecominfraproject.com) or [Gert Grammel](mailto:ggrammel@juniper.net).
|
||||
To get involved, please contact [Jan Kundrát](mailto:jkt@jankundrat.com) or [Gert Grammel](mailto:ggrammel@juniper.net).
|
||||
|
||||
`gnpy` contributions are currently limited to members of [TIP](http://telecominfraproject.com).
|
||||
Membership is free and open to all.
|
||||
|
||||
@@ -1848,3 +1848,15 @@ month={Sept},}
|
||||
title = {Telecom Infra Project},
|
||||
url = {https://www.telecominfraproject.com},
|
||||
}
|
||||
|
||||
@ARTICLE{DAmicoJLT2022,
|
||||
author={D’Amico, Andrea and Correia, Bruno and London, Elliot and Virgillito,
|
||||
Emanuele and Borraccini, Giacomo and Napoli, Antonio and Curri, Vittorio},
|
||||
journal={Journal of Lightwave Technology},
|
||||
title={Scalable and Disaggregated GGN Approximation Applied to a C+L+S Optical Network},
|
||||
year={2022},
|
||||
volume={40},
|
||||
number={11},
|
||||
pages={3499-3511},
|
||||
doi={10.1109/JLT.2022.3162134}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ This path is directional, and all "GNPy elements" along the path match the unidi
|
||||
|
||||
The network topology contains not just the physical topology of the network, but also references to the :ref:`equipment library<concepts-equipment>` and a set of *operating parameters* for each entity.
|
||||
These parameters include the **fiber length** of each fiber, the connector **attenutation losses**, or an amplifier's specific **gain setting**.
|
||||
The topology is specified via :ref:`XLS files<excel>` or via :ref:`JSON<legacy-json>`.
|
||||
|
||||
.. _complete-vs-incomplete:
|
||||
|
||||
|
||||
21
docs/conf.py
21
docs/conf.py
@@ -65,7 +65,7 @@ author = 'Telecom Infra Project - OOPT PSE Group'
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
language = 'en'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
@@ -84,18 +84,11 @@ todo_include_todos = False
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
on_rtd = os.environ.get('READTHEDOCS') == 'True'
|
||||
if on_rtd:
|
||||
html_theme = 'default'
|
||||
html_theme_options = {
|
||||
'logo_only': True,
|
||||
}
|
||||
else:
|
||||
html_theme = 'alabaster'
|
||||
html_theme_options = {
|
||||
'logo': 'images/GNPy-logo.png',
|
||||
'logo_name': False,
|
||||
}
|
||||
html_theme = 'alabaster'
|
||||
html_theme_options = {
|
||||
'logo': 'images/GNPy-logo.png',
|
||||
'logo_name': False,
|
||||
}
|
||||
|
||||
html_logo = 'images/GNPy-logo.png'
|
||||
|
||||
@@ -190,3 +183,5 @@ autodoc_default_options = {
|
||||
}
|
||||
|
||||
graphviz_output_format = 'svg'
|
||||
|
||||
bibtex_bibfiles = ['biblio.bib']
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _excel:
|
||||
|
||||
Excel (XLS, XLSX) input files
|
||||
=============================
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Extending GNPy with vendor-specific data
|
||||
========================================
|
||||
|
||||
GNPy ships with an :ref:`equipment library<concepts-equipment>` containing machine-readable datasheets of networking equipment.
|
||||
Vendors who are willing to contribute descriptions of their supported products are encouraged to `submit a patch <https://review.gerrithub.io/Documentation/intro-gerrit-walkthrough-github.html>`__.
|
||||
Vendors who are willing to contribute descriptions of their supported products are encouraged to `submit a patch <https://review.gerrithub.io/Documentation/intro-gerrit-walkthrough-github.html>`__ -- or just :ref:`get in touch with us directly<contributing>`.
|
||||
|
||||
This chapter discusses option for modeling performance of :ref:`EDFA amplifiers<extending-edfa>`, :ref:`Raman amplifiers<extending-raman>`, :ref:`transponders<extending-transponder>` and :ref:`ROADMs<extending-roadm>`.
|
||||
|
||||
@@ -29,7 +29,7 @@ The NF is expressed as a third-degree polynomial:
|
||||
|
||||
f(x) &= \text{a}x^3 + \text{b}x^2 + \text{c}x + \text{d}
|
||||
|
||||
\text{NF} &= f(G_\text{max} - G)
|
||||
\text{NF} &= f(G - G_\text{max})
|
||||
|
||||
This model can be also used for fixed-gain fixed-NF amplifiers.
|
||||
In that case, use:
|
||||
@@ -91,7 +91,8 @@ Advanced Specification
|
||||
**********************
|
||||
|
||||
The amplifier performance can be further described in terms of gain ripple, NF ripple, and the dynamic gain tilt.
|
||||
When provided, the amplifier characteristic is fine-tuned as a function of carrier frequency.
|
||||
When provided, the amplifier characteristic is fine-tuned as a function of carrier frequency. Note that in this advanced
|
||||
specification tilt is defined vs frequency while tilt_target specified in EDFA instances is defined vs wavelength.
|
||||
|
||||
.. _extending-raman:
|
||||
|
||||
@@ -100,10 +101,10 @@ Raman Amplifiers
|
||||
|
||||
An accurate simulation of Raman amplification requires knowledge of:
|
||||
|
||||
- the *power* and *wavelength* of all Raman pumping lasers,
|
||||
- the *direction*, whether it is co-propagating or counter-propagating,
|
||||
- the Raman efficiency of the fiber,
|
||||
- the fiber temperature.
|
||||
* the *power* and *wavelength* of all Raman pumping lasers,
|
||||
* the *direction*, whether it is co-propagating or counter-propagating,
|
||||
* the Raman efficiency of the fiber,
|
||||
* the fiber temperature.
|
||||
|
||||
Under certain scenarios it is useful to be able to run a simulation without an accurate Raman description.
|
||||
For these purposes, it is possible to approximate a Raman amplifier via a fixed-gain EDFA with the :ref:`polynomial NF<ext-nf-model-polynomial-NF>` model using :math:`\text{a} = \text{b} = \text{c} = 0`, and a desired effective :math:`\text{d} = NF`.
|
||||
@@ -119,38 +120,32 @@ A *mode* usually refers to a particular performance point that is defined by a c
|
||||
|
||||
The following data are required for each mode:
|
||||
|
||||
``bit-rate``
|
||||
Data bit rate, in :math:`\text{Gbits}\times s^{-1}`.
|
||||
``baud-rate``
|
||||
Symbol modulation rate, in :math:`\text{Gbaud}`.
|
||||
``required-osnr``
|
||||
Minimal allowed OSNR for the receiver.
|
||||
``bit_rate``
|
||||
Data bit rate, in :math:`\text{bits}\times s^{-1}`.
|
||||
``baud_rate``
|
||||
Symbol modulation rate, in :math:`\text{baud}`.
|
||||
``OSNR``
|
||||
Minimal required OSNR for the receiver. In :math:`\text{dB}`
|
||||
``tx-osnr``
|
||||
Initial OSNR at the transmitter's output.
|
||||
``grid-spacing``
|
||||
Initial OSNR at the transmitter's output. In :math:`\text{dB}`
|
||||
``min-spacing``
|
||||
Minimal grid spacing, i.e., an effective channel spectral bandwidth.
|
||||
In :math:`\text{Hz}`.
|
||||
``tx-roll-off``
|
||||
``roll-off``
|
||||
Roll-off parameter (:math:`\beta`) of the TX pulse shaping filter.
|
||||
This assumes a raised-cosine filter.
|
||||
``rx-power-min`` and ``rx-power-max``
|
||||
The allowed range of power at the receiver.
|
||||
(work in progress) The allowed range of power at the receiver.
|
||||
In :math:`\text{dBm}`.
|
||||
``cd-max``
|
||||
Maximal allowed Chromatic Dispersion (CD).
|
||||
In :math:`\text{ps}/\text{nm}`.
|
||||
``pmd-max``
|
||||
Maximal allowed Polarization Mode Dispersion (PMD).
|
||||
In :math:`\text{ps}`.
|
||||
``cd-penalty``
|
||||
*Work-in-progress.*
|
||||
Describes the increase of the requires GSNR as the :abbr:`CD (Chromatic Dispersion)` deteriorates.
|
||||
``dgd-penalty``
|
||||
*Work-in-progress.*
|
||||
Describes the increase of the requires GSNR as the :abbr:`DGD (Differential Group Delay)` deteriorates.
|
||||
``pmd-penalty``
|
||||
*Work-in-progress.*
|
||||
Describes the increase of the requires GSNR as the :abbr:`PMD (Polarization Mode Dispersion)` deteriorates.
|
||||
``penalties``
|
||||
Impairments such as Chromatic Dispersion (CD), Polarization Mode Dispersion (PMD), and Polarization Dispersion Loss (PDL)
|
||||
result in penalties at the receiver. The receiver's ability to handle these impairments can be defined for each mode as
|
||||
a list of {impairment: in defined units, 'penalty_value' in dB} (see `transceiver section here <json.rst#_transceiver>`).
|
||||
Maximum allowed CD, maximum allowed PMD, and maximum allowed PDL should be listed there with corresponding penalties.
|
||||
Impairments experienced during propagation are linearly interpolated between given points to obtain the corresponding penalty.
|
||||
The accumulated penalties are subtracted from the path GSNR before comparing with the minimum required OSNR.
|
||||
Impairments: PMD in :math:`\text{ps}`, CD in :math:`\text{ps/nm}`, PDL in :math:`\text{dB}`, penalty_value in :math:`\text{dB}`
|
||||
|
||||
|
||||
GNPy does not directly track the FEC performance, so the type of chosen FEC is likely indicated in the *name* of the selected transponder mode alone.
|
||||
|
||||
@@ -168,6 +163,7 @@ The set of parameters for each ROADM model therefore includes:
|
||||
Per-channel target TX power towards the egress amplifier.
|
||||
Within GNPy, a ROADM is expected to attenuate any signal that enters the ROADM node to this level.
|
||||
This can be overridden on a per-link in the network topology.
|
||||
Targets can be set using power or power spectral density (see `roadm section here <json.rst#__roadm>`)
|
||||
``pmd``
|
||||
Polarization mode dispersion (PMD) penalty of the express path.
|
||||
In :math:`\text{ps}`.
|
||||
|
||||
BIN
docs/images/2022-04-12-gnpy-app.png
Normal file
BIN
docs/images/2022-04-12-gnpy-app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 288 KiB |
1
docs/images/gnpy-transmission-example.svg
Normal file
1
docs/images/gnpy-transmission-example.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 478 KiB |
@@ -17,6 +17,7 @@ in real-world mesh optical networks. It is based on the Gaussian Noise Model.
|
||||
about-project
|
||||
model
|
||||
gnpy-api
|
||||
release-notes
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
@@ -38,7 +38,7 @@ Using Python on your computer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Note**: `gnpy` supports Python 3 only. Python 2 is not supported.
|
||||
`gnpy` requires Python ≥3.6
|
||||
`gnpy` requires Python ≥3.8
|
||||
|
||||
**Note**: the `gnpy` maintainers strongly recommend the use of Anaconda for
|
||||
managing dependencies.
|
||||
@@ -84,7 +84,7 @@ exact version of Python you are using.
|
||||
$ which python # check which Python executable is used
|
||||
/path/to/anaconda/bin/python
|
||||
$ python -V # check your Python version
|
||||
Python 3.6.5 :: Anaconda, Inc.
|
||||
Python 3.8.0 :: Anaconda, Inc.
|
||||
|
||||
.. _install-pip:
|
||||
|
||||
|
||||
@@ -10,33 +10,33 @@ fully-functional programs.
|
||||
|
||||
**Note**: *If you are a network operator or involved in route planning and
|
||||
optimization for your organization, please contact project maintainer Jan
|
||||
Kundrát <jan.kundrat@telecominfraproject.com>. gnpy is looking for users with
|
||||
Kundrát <jkt@jankundrat.com>. gnpy is looking for users with
|
||||
specific, delineated use cases to drive requirements for future
|
||||
development.*
|
||||
|
||||
This example demonstrates how GNPy can be used to check the expected SNR at the end of the line by varying the channel input power:
|
||||
This example demonstrates how GNPy can be used to check the expected SNR at the end of the line by varying the channel input power,
|
||||
or to run a planning script to check SNR of several services:
|
||||
|
||||
.. image:: https://telecominfraproject.github.io/oopt-gnpy/docs/images/transmission_main_example.svg
|
||||
.. image:: images/gnpy-transmission-example.svg
|
||||
:width: 100%
|
||||
:align: left
|
||||
:alt: Running a simple simulation example
|
||||
:target: https://asciinema.org/a/252295
|
||||
|
||||
By default, this script operates on a single span network defined in
|
||||
`gnpy/example-data/edfa_example_network.json <gnpy/example-data/edfa_example_network.json>`_
|
||||
By default, the gnpy-transmission-example script operates on a single span network defined in
|
||||
`gnpy/example-data/edfa_example_network.json <../gnpy/example-data/edfa_example_network.json>`_
|
||||
|
||||
You can specify a different network at the command line as follows. For
|
||||
example, to use the CORONET Global network defined in
|
||||
`gnpy/example-data/CORONET_Global_Topology.json <gnpy/example-data/CORONET_Global_Topology.json>`_:
|
||||
`gnpy/example-data/CORONET_Global_Topology.json <../gnpy/example-data/CORONET_Global_Topology.json>`_:
|
||||
|
||||
.. code-block:: shell-session
|
||||
|
||||
$ gnpy-transmission-example $(gnpy-example-data)/CORONET_Global_Topology.json
|
||||
|
||||
It is also possible to use an Excel file input (for example
|
||||
`gnpy/example-data/CORONET_Global_Topology.xls <gnpy/example-data/CORONET_Global_Topology.xls>`_).
|
||||
`gnpy/example-data/CORONET_Global_Topology.xls <../gnpy/example-data/CORONET_Global_Topology.xls>`_).
|
||||
The Excel file will be processed into a JSON file with the same prefix.
|
||||
Further details about the Excel data structure are available `in the documentation <docs/excel.rst>`__.
|
||||
Further details about the Excel data structure are available `in the documentation <excel.rst>`__.
|
||||
|
||||
The main transmission example will calculate the average signal OSNR and SNR
|
||||
across network elements (transceiver, ROADMs, fibers, and amplifiers)
|
||||
@@ -57,10 +57,10 @@ interference noise.
|
||||
Further Instructions for Use
|
||||
----------------------------
|
||||
|
||||
Simulations are driven by a set of `JSON <docs/json.rst>`__ or `XLS <docs/excel.rst>`__ files.
|
||||
Simulations are driven by a set of `JSON <json.rst>`__ or `XLS <excel.rst>`__ files.
|
||||
|
||||
The ``gnpy-transmission-example`` script propagates a spectrum of channels at 32 Gbaud, 50 GHz spacing and 0 dBm/channel.
|
||||
Launch power can be overridden by using the ``--power`` argument.
|
||||
Launch power in fiber spans can be overridden by using the ``--power`` argument.
|
||||
Spectrum information is not yet parametrized but can be modified directly in the ``eqpt_config.json`` (via the ``SpectralInformation`` -SI- structure) to accommodate any baud rate or spacing.
|
||||
The number of channel is computed based on ``spacing`` and ``f_min``, ``f_max`` values.
|
||||
|
||||
@@ -72,8 +72,8 @@ An experimental support for Raman amplification is available:
|
||||
$(gnpy-example-data)/raman_edfa_example_network.json \
|
||||
--sim $(gnpy-example-data)/sim_params.json --show-channels
|
||||
|
||||
Configuration of Raman pumps (their frequencies, power and pumping direction) is done via the `RamanFiber element in the network topology <gnpy/example-data/raman_edfa_example_network.json>`_.
|
||||
General numeric parameters for simulation control are provided in the `gnpy/example-data/sim_params.json <gnpy/example-data/sim_params.json>`_.
|
||||
Configuration of Raman pumps (their frequencies, power and pumping direction) is done via the `RamanFiber element in the network topology <../gnpy/example-data/raman_edfa_example_network.json>`_.
|
||||
General numeric parameters for simulation control are provided in the `gnpy/example-data/sim_params.json <../gnpy/example-data/sim_params.json>`_.
|
||||
|
||||
Use ``gnpy-path-request`` to request several paths at once:
|
||||
|
||||
@@ -83,7 +83,7 @@ Use ``gnpy-path-request`` to request several paths at once:
|
||||
$ gnpy-path-request -o output_file.json \
|
||||
meshTopologyExampleV2.xls meshTopologyExampleV2_services.json
|
||||
|
||||
This program operates on a network topology (`JSON <docs/json.rst>`__ or `Excel <docs/excel.rst>`__ format), processing the list of service requests (JSON or XLS again).
|
||||
This program operates on a network topology (`JSON <json.rst>`__ or `Excel <excel.rst>`__ format), processing the list of service requests (JSON or XLS again).
|
||||
The service requests and reply formats are based on the `draft-ietf-teas-yang-path-computation-01 <https://tools.ietf.org/html/draft-ietf-teas-yang-path-computation-01>`__ with custom extensions (e.g., for transponder modes).
|
||||
An example of the JSON input is provided in file `service-template.json`, while results are shown in `path_result_template.json`.
|
||||
|
||||
@@ -92,4 +92,4 @@ As a result transponder type is not part of the network info. it is related to t
|
||||
|
||||
The current version includes a spectrum assigment features that enables to compute a candidate spectrum assignment for each service based on a first fit policy. Spectrum is assigned based on service specified spacing value, path_bandwidth value and selected mode for the transceiver. This spectrum assignment includes a basic capacity planning capability so that the spectrum resource is limited by the frequency min and max values defined for the links. If the requested services reach the link spectrum capacity, additional services feasibility are computed but marked as blocked due to spectrum reason.
|
||||
|
||||
OpenROADM networks can be simulated via ``gnpy/example-data/eqpt_config_openroadm.json`` -- see ``gnpy/example-data/Sweden_OpenROADM_example_network.json`` as an example.
|
||||
OpenROADM networks can be simulated via ``gnpy/example-data/eqpt_config_openroadm_*.json`` -- see ``gnpy/example-data/Sweden_OpenROADM*_example_network.json`` as an example.
|
||||
|
||||
1245
docs/json.rst
1245
docs/json.rst
File diff suppressed because it is too large
Load Diff
@@ -126,9 +126,9 @@ that can be easily evaluated extending the FWM theory from a set of discrete
|
||||
tones - the standard FWM theory introduced back in the 90s by Inoue
|
||||
:cite:`Innoue-FWM`- to a continuity of tones, possibly spectrally shaped.
|
||||
Signals propagating in the fiber are not equivalent to Gaussian noise, but
|
||||
thanks to the absence of in-line compensation for choromatic dispersion, the
|
||||
thanks to the absence of in-line compensation for chromatic dispersion, the
|
||||
become so, over short distances. So, the Gaussian noise model with incoherent
|
||||
accumulation of NLI has estensively proved to be a quick yet accurate and
|
||||
accumulation of NLI has extensively proved to be a quick yet accurate and
|
||||
conservative tool to estimate propagation impairments of fiber propagation.
|
||||
Note that the GN-model has not been derived with the aim of an *exact*
|
||||
performance estimation, but to pursue a conservative performance prediction.
|
||||
@@ -145,4 +145,4 @@ Raman Scattering in order to give a proper estimation for all channels
|
||||
:cite:`cantono2018modeling`. This will be the main upgrade required within the
|
||||
PSE framework.
|
||||
|
||||
.. bibliography:: biblio.bib
|
||||
.. bibliography::
|
||||
|
||||
269
docs/release-notes.rst
Normal file
269
docs/release-notes.rst
Normal file
@@ -0,0 +1,269 @@
|
||||
.. _release-notes:
|
||||
|
||||
Release change log
|
||||
==================
|
||||
|
||||
Each release introduces some changes and new features.
|
||||
|
||||
(prepare text for next release)
|
||||
ROADM impairments can be defined per degree and roadm-path type (add, drop or express).
|
||||
Minimum loss when crossing a ROADM is no more 0 dB. It can be set per ROADM degree with roadm-path-impairments.
|
||||
|
||||
The transceiver output power, which was previously set using the same parameter as the input span power (power_dbm),
|
||||
can now be set using a different parameter. It can be set as:
|
||||
|
||||
- for all channels, with tx_power_dbm using SI similarly to tx_osnr (gnpy-transmission-example script)
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
"SI": [{
|
||||
"f_min": 191.35e12,
|
||||
"baud_rate": 32e9,
|
||||
"f_max": 196.1e12,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 3,
|
||||
"power_range_db": [0, 0, 1],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"tx_power_dbm": -10,
|
||||
"sys_margins": 2
|
||||
}
|
||||
]
|
||||
|
||||
- for certain channels, using -spectrum option and tx_channel_power_dbm option (gnpy-transmission-example script).
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"spectrum": [
|
||||
{
|
||||
"f_min": 191.35e12,
|
||||
"f_max":193.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"slot_width": 50e9,
|
||||
"power_dbm": 0,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
},
|
||||
{
|
||||
"f_min": 193.15e12,
|
||||
"f_max":193.15e12,
|
||||
"baud_rate": 32e9,
|
||||
"slot_width": 50e9,
|
||||
"power_dbm": 0,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"tx_power_dbm": -10
|
||||
},
|
||||
{
|
||||
"f_min": 193.2e12,
|
||||
"f_max":195.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"slot_width": 50e9,
|
||||
"power_dbm": 0,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
- per service using the additional parameter ``tx_power`` which similarly to ``power`` should be defined in Watt (gnpy-path-request script)
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"path-request": [
|
||||
{
|
||||
"request-id": "0",
|
||||
"source": "trx SITE1",
|
||||
"destination": "trx SITE2",
|
||||
"src-tp-id": "trx SITE1",
|
||||
"dst-tp-id": "trx SITE2",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 1",
|
||||
"spacing": 50000000000.0,
|
||||
"path_bandwidth": 100000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "0 with tx_power",
|
||||
"source": "trx SITE1",
|
||||
"destination": "trx SITE2",
|
||||
"src-tp-id": "trx SITE1",
|
||||
"dst-tp-id": "trx SITE2",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 1",
|
||||
"tx_power": 0.0001,
|
||||
"spacing": 50000000000.0,
|
||||
"path_bandwidth": 100000000000.0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
v2.9
|
||||
----
|
||||
|
||||
The revision introduces a major refactor that separates design and propagation. Most of these changes have no impact
|
||||
on the user experience, except the following ones:
|
||||
|
||||
**Network design - amplifiers**: amplifier saturation is checked during design in all cases, even if type_variety is
|
||||
set; amplifier gain is no more computed on the fly but only at design phase.
|
||||
|
||||
Before, the design did not consider amplifier power saturation during design if amplifier type_variety was stated.
|
||||
With this revision, the saturation is always applied:
|
||||
If design is made for a per channel power that leads to saturation, the target are properly reduced and the design
|
||||
is freezed. So that when a new simulation is performed on the same network for lower levels of power per channel
|
||||
the same gain target is applied. Before these were recomputed, changing the gain targets, so the simulation was
|
||||
not considering the exact same working points for amplifiers in case of saturation.
|
||||
|
||||
Note that this case (working with saturation settings) is not recommended.
|
||||
|
||||
The gain of amplifiers was estimated on the fly also in case of RamanFiber preceding elements. The refactor now
|
||||
requires that an estimation of Raman gain of the RamanFiber is done during design to properly compute a gain target.
|
||||
The Raman gain is estimated at design for every RamanFiber span and also during propagation instead of being only
|
||||
estimated at propagation stage for those Raman Fiber spans concerned with the transmission. The auto-design is more
|
||||
accurate for unpropagated spans, but this results in an increase overall computation time.
|
||||
This will be improved in the future.
|
||||
|
||||
**Network design - ROADMs**: ROADM target power settings are verified during design.
|
||||
|
||||
Design checks that expected power coming from every directions ingress from a ROADM are consistent with output power
|
||||
targets. The checks only considers the adjacent previous hop. If the expected power at the input of this ROADM is
|
||||
lower than the target power on the out-degree of the ROADM, a warning is displayed, and user is asked to review the
|
||||
input network to avoid this situation. This does not change the design or propagation behaviour.
|
||||
|
||||
**Propagation**: amplifier gain target is no more recomputed during propagation. It is now possible to freeze
|
||||
the design and propagate without automatic changes.
|
||||
|
||||
In previous release, gain was recomputed during propagation based on an hypothetical reference noiseless channel
|
||||
propagation. It was not possible to «freeze» the autodesign, and propagate without recomputing the gain target
|
||||
of amplifiers.
|
||||
With this new release, the design is freezed, so that it is possible to compare performances on same basis.
|
||||
|
||||
**Display**: "effective pch (dbm)" is removed. Display contains the target pch which is the target power per channel
|
||||
in dBm, computed based on reference channel used for design and the amplifier delta_p in dB (and before out VOA
|
||||
contribution). Note that "actual pch out (dBm)" is the actual propagated total power per channel averaged per spectrum
|
||||
band definition at the output of the amplifier element, including noises and out VOA contribution.
|
||||
|
||||
v2.8
|
||||
----
|
||||
|
||||
**Spectrum assignment**: requests can now support multiple slots.
|
||||
The definition in service file supports multiple assignments (unchanged syntax):
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": 0,
|
||||
"M": 4
|
||||
}, {
|
||||
"N": 50,
|
||||
"M": 4
|
||||
}
|
||||
],
|
||||
|
||||
But in results, label-hop is now a list of slots and center frequency index:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"path-route-object": {
|
||||
"index": 4,
|
||||
"label-hop": [
|
||||
{
|
||||
"N": 0,
|
||||
"M": 4
|
||||
}, {
|
||||
"N": 50,
|
||||
"M": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
instead of
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"path-route-object": {
|
||||
"index": 4,
|
||||
"label-hop": {
|
||||
"N": 0,
|
||||
"M": 4
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
**change in display**: only warnings are displayed ; information are disabled and needs the -v (verbose)
|
||||
option to be displayed on standard output.
|
||||
|
||||
**frequency scaling**: A more accurate description of fiber parameters is implemented, including frequency scaling of
|
||||
chromatic dispersion, effective area, Raman gain coefficient, and nonlinear coefficient.
|
||||
|
||||
In particular:
|
||||
|
||||
1. Chromatic dispersion can be defined with ``'dispersion'`` and ``'dispersion_slope'``, as in previous versions, or
|
||||
with ``'dispersion_per_frequency'``; the latter must be defined as a dictionary with two keys, ``'value'`` and
|
||||
``'frequency'`` and it has higher priority than the entries ``'dispersion'`` and ``'dispersion_slope'``.
|
||||
Essential change: In previous versions, when it was not provided the ``'dispersion_slope'`` was calculated in an
|
||||
involute manner to get a vanishing beta3 , and this was a mere artifact for NLI evaluation purposes (namely to evaluate
|
||||
beta2 and beta3, not for total dispersion accumulation). Now, the evaluation of beta2 and beta3 is performed explicitly
|
||||
in the element.py module.
|
||||
|
||||
2. The effective area is provided as a scalar value evaluated at the Fiber reference frequency and properly scaled
|
||||
considering the Fiber refractive indices n1 and n2, and the core radius. These quantities are assumed to be fixed and
|
||||
are hard coded in the parameters.py module. Essential change: The effective area is always scaled along the frequency.
|
||||
|
||||
3. The Raman gain coefficient is properly scaled considering the overlapping of fiber effective area values scaled at
|
||||
the interacting frequencies. Essential change: In previous version the Raman gain coefficient depends only on
|
||||
the frequency offset.
|
||||
|
||||
4. The nonlinear coefficient ``'gamma'`` is properly scaled considering the refractive index n2 and the scaling
|
||||
effective area. Essential change: As the effective area, the nonlinear coefficient is always scaled along the
|
||||
frequency.
|
||||
|
||||
**power offset**: Power equalization now enables defining a power offset in transceiver library to represent
|
||||
the deviation from the general equalisation strategy defined in ROADMs.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
"mode": [{
|
||||
"format": "100G",
|
||||
"baud_rate": 32.0e9,
|
||||
"tx_osnr": 35.0,
|
||||
"min_spacing": 50.0e9,
|
||||
"cost": 1,
|
||||
"OSNR": 10.0,
|
||||
"bit_rate": 100.0e9,
|
||||
"roll_off": 0.2,
|
||||
"equalization_offset_db": 0.0
|
||||
}, {
|
||||
"format": "200G",
|
||||
"baud_rate": 64.0e9,
|
||||
"tx_osnr": 35.0,
|
||||
"min_spacing": 75.0e9,
|
||||
"cost": 1,
|
||||
"OSNR": 13.0,
|
||||
"bit_rate": 200.0e9,
|
||||
"roll_off": 0.2,
|
||||
"equalization_offset_db": 1.76
|
||||
}
|
||||
]
|
||||
|
||||
v2.7
|
||||
----
|
||||
@@ -1,7 +0,0 @@
|
||||
alabaster>=0.7.12,<1
|
||||
docutils>=0.15.2,<1
|
||||
myst-parser>=0.14.0,<1
|
||||
Pygments>=2.7.4,<3
|
||||
rstcheck
|
||||
Sphinx>=3.5.0,<4
|
||||
sphinxcontrib-bibtex>=0.4.2,<1
|
||||
@@ -1,8 +1,8 @@
|
||||
'''
|
||||
"""
|
||||
GNPy is an open-source, community-developed library for building route planning and optimization tools in real-world mesh optical networks. It is based on the Gaussian Noise Model.
|
||||
|
||||
Signal propagation is implemented in :py:mod:`.core`.
|
||||
Path finding and spectrum assignment is in :py:mod:`.topology`.
|
||||
Various tools and auxiliary code, including the JSON I/O handling, is in
|
||||
:py:mod:`.tools`.
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'''
|
||||
"""
|
||||
Simulation of signal propagation in the DWDM network
|
||||
|
||||
Optical signals, as defined via :class:`.info.SpectralInformation`, enter
|
||||
@@ -6,4 +6,4 @@ Optical signals, as defined via :class:`.info.SpectralInformation`, enter
|
||||
through the :py:mod:`.network`.
|
||||
The simulation is controlled via :py:mod:`.parameters` and implemented mainly
|
||||
via :py:mod:`.science_utils`.
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
"""
|
||||
gnpy.core.ansi_escapes
|
||||
======================
|
||||
|
||||
A random subset of ANSI terminal escape codes for colored messages
|
||||
'''
|
||||
"""
|
||||
|
||||
red = '\x1b[1;31;40m'
|
||||
blue = '\x1b[1;34;40m'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,73 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
"""
|
||||
gnpy.core.equipment
|
||||
===================
|
||||
|
||||
This module contains functionality for specifying equipment.
|
||||
'''
|
||||
"""
|
||||
|
||||
from gnpy.core.utils import automatic_nch, db2lin
|
||||
from gnpy.core.exceptions import EquipmentConfigError
|
||||
|
||||
|
||||
def trx_mode_params(equipment, trx_type_variety='', trx_mode='', error_message=False):
|
||||
"""return the trx and SI parameters from eqpt_config for a given type_variety and mode (ie format)"""
|
||||
"""return the trx and SI parameters from eqpt_config for a given type_variety and mode (ie format)
|
||||
|
||||
if the type or mode do no match an existing transceiver in the library, then the function
|
||||
raises an error if error_message is True else returns a default mode based on equipment['SI']['default']
|
||||
If trx_mode is None (but type is valid), it returns an undetermined mode whatever the error message:
|
||||
this is a special case for automatic mode selection.
|
||||
"""
|
||||
trx_params = {}
|
||||
default_si_data = equipment['SI']['default']
|
||||
# default transponder characteristics
|
||||
# mainly used with transmission_main_example.py
|
||||
default_trx_params = {
|
||||
'f_min': default_si_data.f_min,
|
||||
'f_max': default_si_data.f_max,
|
||||
'baud_rate': default_si_data.baud_rate,
|
||||
'spacing': default_si_data.spacing,
|
||||
'OSNR': None,
|
||||
'penalties': {},
|
||||
'bit_rate': None,
|
||||
'cost': None,
|
||||
'roll_off': default_si_data.roll_off,
|
||||
'tx_osnr': default_si_data.tx_osnr,
|
||||
'min_spacing': None,
|
||||
'equalization_offset_db': 0
|
||||
}
|
||||
# Undetermined transponder characteristics
|
||||
# mainly used with path_request_run.py for the automatic mode computation case
|
||||
undetermined_trx_params = {
|
||||
"format": "undetermined",
|
||||
"baud_rate": None,
|
||||
"OSNR": None,
|
||||
"penalties": None,
|
||||
"bit_rate": None,
|
||||
"roll_off": None,
|
||||
"tx_osnr": None,
|
||||
"min_spacing": None,
|
||||
"cost": None,
|
||||
"equalization_offset_db": 0
|
||||
}
|
||||
|
||||
try:
|
||||
trxs = equipment['Transceiver']
|
||||
# if called from path_requests_run.py, trx_mode is filled with None when not specified by user
|
||||
# if called from transmission_main.py, trx_mode is ''
|
||||
if trx_mode is not None:
|
||||
mode_params = next(mode for trx in trxs
|
||||
if trx == trx_type_variety
|
||||
for mode in trxs[trx].mode
|
||||
if mode['format'] == trx_mode)
|
||||
trx_params = {**mode_params}
|
||||
# sanity check: spacing baudrate must be smaller than min spacing
|
||||
trxs = equipment['Transceiver']
|
||||
if trx_type_variety in trxs:
|
||||
modes = {mode['format']: mode for mode in trxs[trx_type_variety].mode}
|
||||
trx_frequencies = {'f_min': trxs[trx_type_variety].frequency['min'],
|
||||
'f_max': trxs[trx_type_variety].frequency['max']}
|
||||
if trx_mode in modes:
|
||||
# if called from transmission_main.py, trx_mode is ''
|
||||
trx_params = {**modes[trx_mode], **trx_frequencies}
|
||||
if trx_params['baud_rate'] > trx_params['min_spacing']:
|
||||
raise EquipmentConfigError(f'Inconsistency in equipment library:\n Transpoder "{trx_type_variety}" mode "{trx_params["format"]}" ' +
|
||||
f'has baud rate {trx_params["baud_rate"]*1e-9} GHz greater than min_spacing {trx_params["min_spacing"]*1e-9}.')
|
||||
else:
|
||||
mode_params = {"format": "undetermined",
|
||||
"baud_rate": None,
|
||||
"OSNR": None,
|
||||
"bit_rate": None,
|
||||
"roll_off": None,
|
||||
"tx_osnr": None,
|
||||
"min_spacing": None,
|
||||
"cost": None}
|
||||
trx_params = {**mode_params}
|
||||
trx_params['f_min'] = equipment['Transceiver'][trx_type_variety].frequency['min']
|
||||
trx_params['f_max'] = equipment['Transceiver'][trx_type_variety].frequency['max']
|
||||
|
||||
# TODO: novel automatic feature maybe unwanted if spacing is specified
|
||||
# trx_params['spacing'] = _automatic_spacing(trx_params['baud_rate'])
|
||||
# temp = trx_params['spacing']
|
||||
# print(f'spacing {temp}')
|
||||
except StopIteration:
|
||||
if error_message:
|
||||
raise EquipmentConfigError(f'Could not find transponder "{trx_type_variety}" with mode "{trx_mode}" in equipment library')
|
||||
else:
|
||||
# default transponder charcteristics
|
||||
# mainly used with transmission_main_example.py
|
||||
trx_params['f_min'] = default_si_data.f_min
|
||||
trx_params['f_max'] = default_si_data.f_max
|
||||
trx_params['baud_rate'] = default_si_data.baud_rate
|
||||
trx_params['spacing'] = default_si_data.spacing
|
||||
trx_params['OSNR'] = None
|
||||
trx_params['bit_rate'] = None
|
||||
trx_params['cost'] = None
|
||||
trx_params['roll_off'] = default_si_data.roll_off
|
||||
trx_params['tx_osnr'] = default_si_data.tx_osnr
|
||||
trx_params['min_spacing'] = None
|
||||
nch = automatic_nch(trx_params['f_min'], trx_params['f_max'], trx_params['spacing'])
|
||||
trx_params['nb_channel'] = nch
|
||||
print(f'There are {nch} channels propagating')
|
||||
|
||||
trx_params['power'] = db2lin(default_si_data.power_dbm) * 1e-3
|
||||
# sanity check: baudrate must be smaller than min spacing
|
||||
raise EquipmentConfigError(f'Inconsistency in equipment library:\n Transponder "{trx_type_variety}" '
|
||||
+ f'mode "{trx_params["format"]}" has baud rate '
|
||||
+ f'{trx_params["baud_rate"] * 1e-9:.2f} GHz greater than min_spacing '
|
||||
+ f'{trx_params["min_spacing"] * 1e-9:.2f}.')
|
||||
trx_params['equalization_offset_db'] = trx_params.get('equalization_offset_db', 0)
|
||||
return trx_params
|
||||
if trx_mode is None:
|
||||
# if called from path_requests_run.py, trx_mode is filled with None when not specified by user
|
||||
trx_params = {**undetermined_trx_params, **trx_frequencies}
|
||||
return trx_params
|
||||
if trx_type_variety in trxs and error_message:
|
||||
raise EquipmentConfigError(f'Could not find transponder "{trx_type_variety}" with mode "{trx_mode}" '
|
||||
+ 'in equipment library')
|
||||
if error_message:
|
||||
raise EquipmentConfigError(f'Could not find transponder "{trx_type_variety}" in equipment library')
|
||||
|
||||
trx_params = {**default_trx_params}
|
||||
return trx_params
|
||||
|
||||
@@ -8,49 +8,371 @@ gnpy.core.info
|
||||
This module contains classes for modelling :class:`SpectralInformation`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from collections import namedtuple
|
||||
from gnpy.core.utils import automatic_nch, lin2db
|
||||
from collections.abc import Iterable
|
||||
from typing import Union
|
||||
from dataclasses import dataclass
|
||||
from numpy import argsort, mean, array, append, ones, ceil, any, zeros, outer, full, ndarray, asarray
|
||||
|
||||
from gnpy.core.utils import automatic_nch, db2lin, watt2dbm
|
||||
from gnpy.core.exceptions import SpectrumError
|
||||
|
||||
DEFAULT_SLOT_WIDTH_STEP = 12.5e9 # Hz
|
||||
"""Channels with unspecified slot width will have their slot width evaluated as the baud rate rounded up to the minimum
|
||||
multiple of the DEFAULT_SLOT_WIDTH_STEP (the baud rate is extended including the roll off in this evaluation)"""
|
||||
|
||||
|
||||
class Power(namedtuple('Power', 'signal nli ase')):
|
||||
"""carriers power in W"""
|
||||
|
||||
|
||||
class Channel(namedtuple('Channel', 'channel_number frequency baud_rate roll_off power chromatic_dispersion pmd')):
|
||||
""" Class containing the parameters of a WDM signal.
|
||||
class Channel(
|
||||
namedtuple('Channel',
|
||||
'channel_number frequency baud_rate slot_width roll_off power chromatic_dispersion pmd pdl latency')):
|
||||
"""Class containing the parameters of a WDM signal.
|
||||
|
||||
:param channel_number: channel number in the WDM grid
|
||||
:param frequency: central frequency of the signal (Hz)
|
||||
:param baud_rate: the symbol rate of the signal (Baud)
|
||||
:param roll_off: the roll off of the signal. It is a pure number between 0 and 1
|
||||
:param power (gnpy.core.info.Power): power of signal, ASE noise and NLI (W)
|
||||
:param chromatic_dispersion: chromatic dispersion (s/m)
|
||||
:param pmd: polarization mode dispersion (s)
|
||||
:param channel_number: channel number in the WDM grid
|
||||
:param frequency: central frequency of the signal (Hz)
|
||||
:param baud_rate: the symbol rate of the signal (Baud)
|
||||
:param slot_width: the slot width (Hz)
|
||||
:param roll_off: the roll off of the signal. It is a pure number between 0 and 1
|
||||
:param power (gnpy.core.info.Power): power of signal, ASE noise and NLI (W)
|
||||
:param chromatic_dispersion: chromatic dispersion (s/m)
|
||||
:param pmd: polarization mode dispersion (s)
|
||||
:param pdl: polarization dependent loss (dB)
|
||||
:param latency: propagation latency (s)
|
||||
"""
|
||||
|
||||
|
||||
class Pref(namedtuple('Pref', 'p_span0, p_spani, neq_ch ')):
|
||||
"""noiseless reference power in dBm:
|
||||
p_span0: inital target carrier power
|
||||
p_spani: carrier power after element i
|
||||
neq_ch: equivalent channel count in dB"""
|
||||
class SpectralInformation(object):
|
||||
"""Class containing the parameters of the entire WDM comb.
|
||||
|
||||
delta_pdb_per_channel: (per frequency) per channel delta power in dbm for the actual mix of channels"""
|
||||
|
||||
def __init__(self, frequency: array, baud_rate: array, slot_width: array, signal: array, nli: array, ase: array,
|
||||
roll_off: array, chromatic_dispersion: array, pmd: array, pdl: array, latency: array,
|
||||
delta_pdb_per_channel: array, tx_osnr: array, tx_power: array, label: array):
|
||||
indices = argsort(frequency)
|
||||
self._frequency = frequency[indices]
|
||||
self._df = outer(ones(frequency.shape), frequency) - outer(frequency, ones(frequency.shape))
|
||||
self._number_of_channels = len(self._frequency)
|
||||
self._channel_number = [*range(1, self._number_of_channels + 1)]
|
||||
self._slot_width = slot_width[indices]
|
||||
self._baud_rate = baud_rate[indices]
|
||||
overlap = self._frequency[:-1] + self._slot_width[:-1] / 2 > self._frequency[1:] - self._slot_width[1:] / 2
|
||||
if any(overlap):
|
||||
overlap = [pair for pair in zip(overlap * self._channel_number[:-1], overlap * self._channel_number[1:])
|
||||
if pair != (0, 0)]
|
||||
raise SpectrumError(f'Spectrum required slot widths larger than the frequency spectral distances '
|
||||
f'between channels: {overlap}.')
|
||||
exceed = self._baud_rate > self._slot_width
|
||||
if any(exceed):
|
||||
raise SpectrumError(f'Spectrum baud rate, including the roll off, larger than the slot width for channels: '
|
||||
f'{[ch for ch in exceed * self._channel_number if ch]}.')
|
||||
self._signal = signal[indices]
|
||||
self._nli = nli[indices]
|
||||
self._ase = ase[indices]
|
||||
self._roll_off = roll_off[indices]
|
||||
self._chromatic_dispersion = chromatic_dispersion[indices]
|
||||
self._pmd = pmd[indices]
|
||||
self._pdl = pdl[indices]
|
||||
self._latency = latency[indices]
|
||||
self._delta_pdb_per_channel = delta_pdb_per_channel[indices]
|
||||
self._tx_osnr = tx_osnr[indices]
|
||||
self._tx_power = tx_power[indices]
|
||||
self._label = label[indices]
|
||||
|
||||
@property
|
||||
def frequency(self):
|
||||
return self._frequency
|
||||
|
||||
@property
|
||||
def df(self):
|
||||
"""Matrix of relative frequency distances between all channels. Positive elements in the upper right side."""
|
||||
return self._df
|
||||
|
||||
@property
|
||||
def slot_width(self):
|
||||
return self._slot_width
|
||||
|
||||
@property
|
||||
def baud_rate(self):
|
||||
return self._baud_rate
|
||||
|
||||
@property
|
||||
def number_of_channels(self):
|
||||
return self._number_of_channels
|
||||
|
||||
@property
|
||||
def powers(self):
|
||||
powers = zip(self.signal, self.nli, self.ase)
|
||||
return [Power(*p) for p in powers]
|
||||
|
||||
@property
|
||||
def signal(self):
|
||||
return self._signal
|
||||
|
||||
@signal.setter
|
||||
def signal(self, signal):
|
||||
self._signal = signal
|
||||
|
||||
@property
|
||||
def nli(self):
|
||||
return self._nli
|
||||
|
||||
@nli.setter
|
||||
def nli(self, nli):
|
||||
self._nli = nli
|
||||
|
||||
@property
|
||||
def ase(self):
|
||||
return self._ase
|
||||
|
||||
@ase.setter
|
||||
def ase(self, ase):
|
||||
self._ase = ase
|
||||
|
||||
@property
|
||||
def roll_off(self):
|
||||
return self._roll_off
|
||||
|
||||
@property
|
||||
def chromatic_dispersion(self):
|
||||
return self._chromatic_dispersion
|
||||
|
||||
@chromatic_dispersion.setter
|
||||
def chromatic_dispersion(self, chromatic_dispersion):
|
||||
self._chromatic_dispersion = chromatic_dispersion
|
||||
|
||||
@property
|
||||
def pmd(self):
|
||||
return self._pmd
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return self._label
|
||||
|
||||
@pmd.setter
|
||||
def pmd(self, pmd):
|
||||
self._pmd = pmd
|
||||
|
||||
@property
|
||||
def pdl(self):
|
||||
return self._pdl
|
||||
|
||||
@pdl.setter
|
||||
def pdl(self, pdl):
|
||||
self._pdl = pdl
|
||||
|
||||
@property
|
||||
def latency(self):
|
||||
return self._latency
|
||||
|
||||
@latency.setter
|
||||
def latency(self, latency):
|
||||
self._latency = latency
|
||||
|
||||
@property
|
||||
def delta_pdb_per_channel(self):
|
||||
return self._delta_pdb_per_channel
|
||||
|
||||
@delta_pdb_per_channel.setter
|
||||
def delta_pdb_per_channel(self, delta_pdb_per_channel):
|
||||
self._delta_pdb_per_channel = delta_pdb_per_channel
|
||||
|
||||
@property
|
||||
def tx_osnr(self):
|
||||
return self._tx_osnr
|
||||
|
||||
@tx_osnr.setter
|
||||
def tx_osnr(self, tx_osnr):
|
||||
self._tx_osnr = tx_osnr
|
||||
|
||||
@property
|
||||
def tx_power(self):
|
||||
return self._tx_power
|
||||
|
||||
@tx_power.setter
|
||||
def tx_power(self, tx_power):
|
||||
self._tx_power = tx_power
|
||||
|
||||
@property
|
||||
def channel_number(self):
|
||||
return self._channel_number
|
||||
|
||||
@property
|
||||
def carriers(self):
|
||||
entries = zip(self.channel_number, self.frequency, self.baud_rate, self.slot_width,
|
||||
self.roll_off, self.powers, self.chromatic_dispersion, self.pmd, self.pdl, self.latency)
|
||||
return [Channel(*entry) for entry in entries]
|
||||
|
||||
def apply_attenuation_lin(self, attenuation_lin):
|
||||
self.signal *= attenuation_lin
|
||||
self.nli *= attenuation_lin
|
||||
self.ase *= attenuation_lin
|
||||
|
||||
def apply_attenuation_db(self, attenuation_db):
|
||||
attenuation_lin = 1 / db2lin(attenuation_db)
|
||||
self.apply_attenuation_lin(attenuation_lin)
|
||||
|
||||
def apply_gain_lin(self, gain_lin):
|
||||
self.signal *= gain_lin
|
||||
self.nli *= gain_lin
|
||||
self.ase *= gain_lin
|
||||
|
||||
def apply_gain_db(self, gain_db):
|
||||
gain_lin = db2lin(gain_db)
|
||||
self.apply_gain_lin(gain_lin)
|
||||
|
||||
def __add__(self, other: SpectralInformation):
|
||||
try:
|
||||
return SpectralInformation(frequency=append(self.frequency, other.frequency),
|
||||
slot_width=append(self.slot_width, other.slot_width),
|
||||
signal=append(self.signal, other.signal), nli=append(self.nli, other.nli),
|
||||
ase=append(self.ase, other.ase),
|
||||
baud_rate=append(self.baud_rate, other.baud_rate),
|
||||
roll_off=append(self.roll_off, other.roll_off),
|
||||
chromatic_dispersion=append(self.chromatic_dispersion,
|
||||
other.chromatic_dispersion),
|
||||
pmd=append(self.pmd, other.pmd),
|
||||
pdl=append(self.pdl, other.pdl),
|
||||
latency=append(self.latency, other.latency),
|
||||
delta_pdb_per_channel=append(self.delta_pdb_per_channel,
|
||||
other.delta_pdb_per_channel),
|
||||
tx_osnr=append(self.tx_osnr, other.tx_osnr),
|
||||
tx_power=append(self.tx_power, other.tx_power),
|
||||
label=append(self.label, other.label))
|
||||
except SpectrumError:
|
||||
raise SpectrumError('Spectra cannot be summed: channels overlapping.')
|
||||
|
||||
def _replace(self, carriers):
|
||||
self.chromatic_dispersion = array([c.chromatic_dispersion for c in carriers])
|
||||
self.pmd = array([c.pmd for c in carriers])
|
||||
self.pdl = array([c.pdl for c in carriers])
|
||||
self.latency = array([c.latency for c in carriers])
|
||||
self.signal = array([c.power.signal for c in carriers])
|
||||
self.nli = array([c.power.nli for c in carriers])
|
||||
self.ase = array([c.power.ase for c in carriers])
|
||||
return self
|
||||
|
||||
|
||||
class SpectralInformation(namedtuple('SpectralInformation', 'pref carriers')):
|
||||
|
||||
def __new__(cls, pref, carriers):
|
||||
return super().__new__(cls, pref, carriers)
|
||||
def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, float],
|
||||
signal: Union[float, ndarray, Iterable],
|
||||
baud_rate: Union[float, ndarray, Iterable],
|
||||
tx_osnr: Union[float, ndarray, Iterable],
|
||||
tx_power: Union[float, ndarray, Iterable] = None,
|
||||
delta_pdb_per_channel: Union[float, ndarray, Iterable] = 0.,
|
||||
slot_width: Union[float, ndarray, Iterable] = None,
|
||||
roll_off: Union[float, ndarray, Iterable] = 0.,
|
||||
chromatic_dispersion: Union[float, ndarray, Iterable] = 0.,
|
||||
pmd: Union[float, ndarray, Iterable] = 0.,
|
||||
pdl: Union[float, ndarray, Iterable] = 0.,
|
||||
latency: Union[float, ndarray, Iterable] = 0.,
|
||||
label: Union[str, ndarray, Iterable] = None):
|
||||
"""This is just a wrapper around the SpectralInformation.__init__() that simplifies the creation of
|
||||
a non-uniform spectral information with NLI and ASE powers set to zero."""
|
||||
frequency = asarray(frequency)
|
||||
number_of_channels = frequency.size
|
||||
try:
|
||||
signal = full(number_of_channels, signal)
|
||||
baud_rate = full(number_of_channels, baud_rate)
|
||||
roll_off = full(number_of_channels, roll_off)
|
||||
slot_width = full(number_of_channels, slot_width) if slot_width is not None else \
|
||||
ceil((1 + roll_off) * baud_rate / DEFAULT_SLOT_WIDTH_STEP) * DEFAULT_SLOT_WIDTH_STEP
|
||||
chromatic_dispersion = full(number_of_channels, chromatic_dispersion)
|
||||
pmd = full(number_of_channels, pmd)
|
||||
pdl = full(number_of_channels, pdl)
|
||||
latency = full(number_of_channels, latency)
|
||||
nli = zeros(number_of_channels)
|
||||
ase = zeros(number_of_channels)
|
||||
delta_pdb_per_channel = full(number_of_channels, delta_pdb_per_channel)
|
||||
tx_osnr = full(number_of_channels, tx_osnr)
|
||||
tx_power = full(number_of_channels, tx_power)
|
||||
label = full(number_of_channels, label)
|
||||
return SpectralInformation(frequency=frequency, slot_width=slot_width,
|
||||
signal=signal, nli=nli, ase=ase,
|
||||
baud_rate=baud_rate, roll_off=roll_off,
|
||||
chromatic_dispersion=chromatic_dispersion,
|
||||
pmd=pmd, pdl=pdl, latency=latency,
|
||||
delta_pdb_per_channel=delta_pdb_per_channel,
|
||||
tx_osnr=tx_osnr, tx_power=tx_power, label=label)
|
||||
except ValueError as e:
|
||||
if 'could not broadcast' in str(e):
|
||||
raise SpectrumError('Dimension mismatch in input fields.')
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing):
|
||||
# pref in dB : convert power lin into power in dB
|
||||
pref = lin2db(power * 1e3)
|
||||
nb_channel = automatic_nch(f_min, f_max, spacing)
|
||||
si = SpectralInformation(
|
||||
pref=Pref(pref, pref, lin2db(nb_channel)),
|
||||
carriers=[
|
||||
Channel(f, (f_min + spacing * f),
|
||||
baud_rate, roll_off, Power(power, 0, 0), 0, 0) for f in range(1, nb_channel + 1)
|
||||
]
|
||||
)
|
||||
return si
|
||||
def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, spacing, tx_osnr, tx_power,
|
||||
delta_pdb=0):
|
||||
"""Creates a fixed slot width spectral information with flat power.
|
||||
all arguments are scalar values"""
|
||||
number_of_channels = automatic_nch(f_min, f_max, spacing)
|
||||
frequency = [(f_min + spacing * i) for i in range(1, number_of_channels + 1)]
|
||||
delta_pdb_per_channel = delta_pdb * ones(number_of_channels)
|
||||
label = [f'{baud_rate * 1e-9 :.2f}G' for i in range(number_of_channels)]
|
||||
return create_arbitrary_spectral_information(frequency, slot_width=spacing, signal=tx_power, baud_rate=baud_rate,
|
||||
roll_off=roll_off, delta_pdb_per_channel=delta_pdb_per_channel,
|
||||
tx_osnr=tx_osnr, tx_power=tx_power, label=label)
|
||||
|
||||
|
||||
def carriers_to_spectral_information(initial_spectrum: dict[float, Carrier],
|
||||
power: float) -> SpectralInformation:
|
||||
"""Initial spectrum is a dict with key = carrier frequency, and value a Carrier object.
|
||||
:param initial_spectrum: indexed by frequency in Hz, with power offset (delta_pdb), baudrate, slot width,
|
||||
tx_osnr, tx_power and roll off.
|
||||
:param power: power of the request
|
||||
"""
|
||||
frequency = list(initial_spectrum.keys())
|
||||
signal = [c.tx_power for c in initial_spectrum.values()]
|
||||
roll_off = [c.roll_off for c in initial_spectrum.values()]
|
||||
baud_rate = [c.baud_rate for c in initial_spectrum.values()]
|
||||
delta_pdb_per_channel = [c.delta_pdb for c in initial_spectrum.values()]
|
||||
slot_width = [c.slot_width for c in initial_spectrum.values()]
|
||||
tx_osnr = [c.tx_osnr for c in initial_spectrum.values()]
|
||||
tx_power = [c.tx_power for c in initial_spectrum.values()]
|
||||
label = [c.label for c in initial_spectrum.values()]
|
||||
return create_arbitrary_spectral_information(frequency=frequency, signal=signal, baud_rate=baud_rate,
|
||||
slot_width=slot_width, roll_off=roll_off,
|
||||
delta_pdb_per_channel=delta_pdb_per_channel, tx_osnr=tx_osnr,
|
||||
tx_power=tx_power, label=label)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Carrier:
|
||||
"""One channel in the initial mixed-type spectrum definition, each type being defined by
|
||||
its delta_pdb (power offset with respect to reference power), baud rate, slot_width, roll_off
|
||||
tx_power, and tx_osnr. delta_pdb offset is applied to target power out of Roadm.
|
||||
Label is used to group carriers which belong to the same partition when printing results.
|
||||
"""
|
||||
delta_pdb: float
|
||||
baud_rate: float
|
||||
slot_width: float
|
||||
roll_off: float
|
||||
tx_osnr: float
|
||||
tx_power: float
|
||||
label: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReferenceCarrier:
|
||||
"""Reference channel type is used to determine target power out of ROADM for the reference channel when
|
||||
constant power spectral density (PSD) equalization is set. Reference channel is the type that has been defined
|
||||
in SI block and used for the initial design of the network.
|
||||
Computing the power out of ROADM for the reference channel is required to correctly compute the loss
|
||||
experienced by reference channel in Roadm element.
|
||||
|
||||
Baud rate is required to find the target power in constant PSD: power = PSD_target * baud_rate.
|
||||
For example, if target PSD is 3.125e4mW/GHz and reference carrier type a 32 GBaud channel then
|
||||
output power should be -20 dBm and for a 64 GBaud channel power target would need 3 dB more: -17 dBm.
|
||||
|
||||
Slot width is required to find the target power in constant PSW (constant power per slot width equalization):
|
||||
power = PSW_target * slot_width.
|
||||
For example, if target PSW is 2e4mW/GHz and reference carrier type a 32 GBaud channel in a 50GHz slot width then
|
||||
output power should be -20 dBm and for a 64 GBaud channel in a 75 GHz slot width, power target would be -18.24 dBm.
|
||||
|
||||
Other attributes (like roll-off) may be added there for future equalization purpose.
|
||||
"""
|
||||
baud_rate: float
|
||||
slot_width: float
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
"""
|
||||
gnpy.core.network
|
||||
=================
|
||||
|
||||
Working with networks which consist of network elements
|
||||
'''
|
||||
"""
|
||||
|
||||
from copy import deepcopy
|
||||
from operator import attrgetter
|
||||
from gnpy.core import ansi_escapes, elements
|
||||
from gnpy.core.exceptions import ConfigurationError, NetworkTopologyError
|
||||
from gnpy.core.utils import round2float, convert_length
|
||||
from collections import namedtuple
|
||||
from logging import getLogger
|
||||
|
||||
from gnpy.core import elements
|
||||
from gnpy.core.exceptions import ConfigurationError, NetworkTopologyError
|
||||
from gnpy.core.utils import round2float, convert_length, psd2powerdbm, lin2db, watt2dbm, dbm2watt
|
||||
from gnpy.core.info import ReferenceCarrier, create_input_spectral_information
|
||||
from gnpy.core.parameters import SimParams, EdfaParams
|
||||
from gnpy.core.science_utils import RamanSolver
|
||||
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
def edfa_nf(gain_target, variety_type, equipment):
|
||||
@@ -27,10 +36,11 @@ def edfa_nf(gain_target, variety_type, equipment):
|
||||
)
|
||||
amp.pin_db = 0
|
||||
amp.nch = 88
|
||||
amp.slot_width = 50e9
|
||||
return amp._calc_nf(True)
|
||||
|
||||
|
||||
def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restrictions=None):
|
||||
def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restrictions=None, verbose=True):
|
||||
"""amplifer selection algorithm
|
||||
@Orange Jean-Luc Augé
|
||||
"""
|
||||
@@ -53,15 +63,8 @@ def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restri
|
||||
# power attribut include power AND gain limitations
|
||||
edfa_list = [Edfa_list(
|
||||
variety=edfa_variety,
|
||||
power=min(
|
||||
pin
|
||||
+ edfa.gain_flatmax
|
||||
+ TARGET_EXTENDED_GAIN,
|
||||
edfa.p_max
|
||||
)
|
||||
- power_target,
|
||||
gain_min=gain_target + 3
|
||||
- edfa.gain_min,
|
||||
power=min(pin + edfa.gain_flatmax + TARGET_EXTENDED_GAIN, edfa.p_max) - power_target,
|
||||
gain_min=gain_target + 3 - edfa.gain_min,
|
||||
nf=edfa_nf(gain_target, edfa_variety, equipment))
|
||||
for edfa_variety, edfa in edfa_dict.items()
|
||||
if ((edfa.allowed_for_design or restrictions is not None) and not edfa.raman)]
|
||||
@@ -70,15 +73,8 @@ def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restri
|
||||
# do not allow extended gain min for Raman
|
||||
raman_list = [Edfa_list(
|
||||
variety=edfa_variety,
|
||||
power=min(
|
||||
pin
|
||||
+ edfa.gain_flatmax
|
||||
+ TARGET_EXTENDED_GAIN,
|
||||
edfa.p_max
|
||||
)
|
||||
- power_target,
|
||||
gain_min=gain_target
|
||||
- edfa.gain_min,
|
||||
power=min(pin + edfa.gain_flatmax + TARGET_EXTENDED_GAIN, edfa.p_max) - power_target,
|
||||
gain_min=gain_target - edfa.gain_min,
|
||||
nf=edfa_nf(gain_target, edfa_variety, equipment))
|
||||
for edfa_variety, edfa in edfa_dict.items()
|
||||
if (edfa.allowed_for_design and edfa.raman)] \
|
||||
@@ -102,10 +98,10 @@ def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restri
|
||||
please increase span fiber padding')
|
||||
else:
|
||||
# TODO: convert to logging
|
||||
print(
|
||||
f'{ansi_escapes.red}WARNING:{ansi_escapes.reset} target gain in node {uid} is below all available amplifiers min gain: \
|
||||
amplifier input padding will be assumed, consider increase span fiber padding instead'
|
||||
)
|
||||
if verbose:
|
||||
logger.warning(f'\n\tWARNING: target gain in node {uid} is below all available amplifiers min gain: '
|
||||
+ '\n\tamplifier input padding will be assumed, consider increase span fiber padding '
|
||||
+ 'instead.\n')
|
||||
acceptable_gain_min_list = edfa_list
|
||||
|
||||
# filter on gain+power limitation:
|
||||
@@ -125,33 +121,33 @@ def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restri
|
||||
# =>chose the amp with the best NF among the acceptable ones:
|
||||
selected_edfa = min(acceptable_power_list, key=attrgetter('nf')) # filter on NF
|
||||
# check what are the gain and power limitations of this amp
|
||||
power_reduction = round(min(selected_edfa.power, 0), 2)
|
||||
if power_reduction < -0.5:
|
||||
print(
|
||||
f'{ansi_escapes.red}WARNING:{ansi_escapes.reset} target gain and power in node {uid}\n \
|
||||
is beyond all available amplifiers capabilities and/or extended_gain_range:\n\
|
||||
a power reduction of {power_reduction} is applied\n'
|
||||
)
|
||||
|
||||
power_reduction = min(selected_edfa.power, 0)
|
||||
if power_reduction < -0.5 and verbose:
|
||||
logger.warning(f'\n\tWARNING: target gain and power in node {uid}\n'
|
||||
+ '\tis beyond all available amplifiers capabilities and/or extended_gain_range:\n'
|
||||
+ f'\ta power reduction of {round(power_reduction, 2)} is applied\n')
|
||||
return selected_edfa.variety, power_reduction
|
||||
|
||||
|
||||
def target_power(network, node, equipment): # get_fiber_dp
|
||||
"""Computes target power using J. -L. Auge, V. Curri and E. Le Rouzic,
|
||||
Open Design for Multi-Vendor Optical Networks, OFC 2019.
|
||||
equation 4
|
||||
"""
|
||||
if isinstance(node, elements.Roadm):
|
||||
return 0
|
||||
|
||||
SPAN_LOSS_REF = 20
|
||||
POWER_SLOPE = 0.3
|
||||
dp_range = list(equipment['Span']['default'].delta_power_range_db)
|
||||
node_loss = span_loss(network, node)
|
||||
|
||||
node_loss = span_loss(network, node, equipment)
|
||||
try:
|
||||
dp = round2float((node_loss - SPAN_LOSS_REF) * POWER_SLOPE, dp_range[2])
|
||||
dp = max(dp_range[0], dp)
|
||||
dp = min(dp_range[1], dp)
|
||||
except IndexError:
|
||||
raise ConfigurationError(f'invalid delta_power_range_db definition in eqpt_config[Span]'
|
||||
f'delta_power_range_db: [lower_bound, upper_bound, step]')
|
||||
raise ConfigurationError('invalid delta_power_range_db definition in eqpt_config[Span]'
|
||||
'delta_power_range_db: [lower_bound, upper_bound, step]')
|
||||
|
||||
return dp
|
||||
|
||||
@@ -190,12 +186,74 @@ def next_node_generator(network, node):
|
||||
yield from next_node_generator(network, next_node)
|
||||
|
||||
|
||||
def span_loss(network, node):
|
||||
"""Total loss of a span (Fiber and Fused nodes) which contains the given node"""
|
||||
def estimate_raman_gain(node, equipment, power_dbm):
|
||||
"""If node is RamanFiber, then estimate the possible Raman gain if any
|
||||
for this purpose computes stimulated_raman_scattering loss_profile. This may be time consuming.
|
||||
"""
|
||||
if isinstance(node, elements.RamanFiber):
|
||||
if hasattr(node, "estimated_gain"):
|
||||
return node.estimated_gain
|
||||
f_min = equipment['SI']['default'].f_min
|
||||
f_max = equipment['SI']['default'].f_max
|
||||
roll_off = equipment['SI']['default'].roll_off
|
||||
baud_rate = equipment['SI']['default'].baud_rate
|
||||
power = dbm2watt(power_dbm)
|
||||
spacing = equipment['SI']['default'].spacing
|
||||
tx_osnr = equipment['SI']['default'].tx_osnr
|
||||
|
||||
# reduce the nb of channels to speed up
|
||||
spacing = spacing * 3
|
||||
power = power * 3
|
||||
|
||||
sim_params = {
|
||||
"raman_params": {
|
||||
"flag": True,
|
||||
"result_spatial_resolution": 50e3,
|
||||
"solver_spatial_resolution": 100
|
||||
}
|
||||
}
|
||||
|
||||
# in order to take into account gain generated in RamanFiber, propagate in the RamanFiber with
|
||||
if hasattr(node, "estimated_gain"):
|
||||
# do not compute twice to save on time
|
||||
return node.estimated_gain
|
||||
spectral_info = create_input_spectral_information(f_min=f_min, f_max=f_max, roll_off=roll_off,
|
||||
baud_rate=baud_rate, tx_power=power, spacing=spacing,
|
||||
tx_osnr=tx_osnr)
|
||||
pin = watt2dbm(sum(spectral_info.signal))
|
||||
attenuation_in_db = node.params.con_in + node.params.att_in
|
||||
spectral_info.apply_attenuation_db(attenuation_in_db)
|
||||
save_sim_params = {"raman_params": SimParams._shared_dict['raman_params'].to_json(),
|
||||
"nli_params": SimParams._shared_dict['nli_params'].to_json()}
|
||||
SimParams.set_params(sim_params)
|
||||
stimulated_raman_scattering = RamanSolver.calculate_stimulated_raman_scattering(spectral_info, node)
|
||||
attenuation_fiber = stimulated_raman_scattering.loss_profile[:spectral_info.number_of_channels, -1]
|
||||
spectral_info.apply_attenuation_lin(attenuation_fiber)
|
||||
attenuation_out_db = node.params.con_out
|
||||
spectral_info.apply_attenuation_db(attenuation_out_db)
|
||||
pout = watt2dbm(sum(spectral_info.signal))
|
||||
estimated_loss = pin - pout
|
||||
estimated_gain = node.loss - estimated_loss
|
||||
node.estimated_gain = estimated_gain
|
||||
SimParams.set_params(save_sim_params)
|
||||
return round(estimated_gain, 2)
|
||||
else:
|
||||
return 0.0
|
||||
|
||||
|
||||
def span_loss(network, node, equipment, input_power=None):
|
||||
"""Total loss of a span (Fiber and Fused nodes) which contains the given node
|
||||
Do not recompute, if it was already computed: records it in design_span_loss"""
|
||||
if hasattr(node, "design_span_loss"):
|
||||
return node.design_span_loss
|
||||
loss = node.loss if node.passive else 0
|
||||
loss += sum(n.loss for n in prev_node_generator(network, node))
|
||||
loss += sum(n.loss for n in next_node_generator(network, node))
|
||||
return loss
|
||||
# add the possible Raman gain
|
||||
gain = estimate_raman_gain(node, equipment, input_power)
|
||||
gain += sum(estimate_raman_gain(n, equipment, input_power) for n in prev_node_generator(network, node))
|
||||
gain += sum(estimate_raman_gain(n, equipment, input_power) for n in next_node_generator(network, node))
|
||||
return loss - gain
|
||||
|
||||
|
||||
def find_first_node(network, node):
|
||||
@@ -232,46 +290,48 @@ def set_amplifier_voa(amp, power_target, power_mode):
|
||||
amp.out_voa = voa
|
||||
|
||||
|
||||
def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_db):
|
||||
""" this node can be a transceiver or a ROADM (same function called in both cases)
|
||||
def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_db, verbose):
|
||||
"""This node can be a transceiver or a ROADM (same function called in both cases).
|
||||
go through each link staring from this_node until next Roadm or Transceiver and
|
||||
set gain and delta_p according to configurations set by user.
|
||||
power_mode = True, set amplifiers delta_p and effective_gain
|
||||
power_mode = False, set amplifiers effective_gain and ignore delta_p config: set it to None
|
||||
"""
|
||||
power_mode = equipment['Span']['default'].power_mode
|
||||
next_oms = (n for n in network.successors(this_node) if not isinstance(n, elements.Transceiver))
|
||||
this_node_degree = {k: v for k, v in this_node.per_degree_pch_out_db.items()} if hasattr(this_node, 'per_degree_pch_out_db') else {}
|
||||
for oms in next_oms:
|
||||
# go through all the OMS departing from the ROADM
|
||||
prev_node = this_node
|
||||
node = oms
|
||||
# if isinstance(next_node, elements.Fused): #support ROADM wo egress amp for metro applications
|
||||
# node = find_last_node(next_node)
|
||||
# next_node = next(n for n in network.successors(node))
|
||||
# next_node = find_last_node(next_node)
|
||||
if node.uid not in this_node_degree:
|
||||
# if no target power is defined on this degree or no per degree target power is given use the global one
|
||||
# if target_pch_out_db is not an attribute, then the element must be a transceiver
|
||||
this_node_degree[node.uid] = getattr(this_node.params, 'target_pch_out_db', 0)
|
||||
if isinstance(this_node, elements.Transceiver):
|
||||
# todo change pref to a ref channel
|
||||
if equipment['SI']['default'].tx_power_dbm is not None:
|
||||
this_node_out_power = equipment['SI']['default'].tx_power_dbm
|
||||
else:
|
||||
this_node_out_power = pref_ch_db
|
||||
if isinstance(this_node, elements.Roadm):
|
||||
# get target power out from ROADM for the reference carrier based on equalization settings
|
||||
this_node_out_power = this_node.get_per_degree_ref_power(degree=node.uid)
|
||||
# use the target power on this degree
|
||||
prev_dp = this_node_degree[node.uid] - pref_ch_db
|
||||
prev_dp = this_node_out_power - pref_ch_db
|
||||
dp = prev_dp
|
||||
prev_voa = 0
|
||||
voa = 0
|
||||
visited_nodes = []
|
||||
while not (isinstance(node, elements.Roadm) or isinstance(node, elements.Transceiver)):
|
||||
# go through all nodes in the OMS (loop until next Roadm instance)
|
||||
try:
|
||||
next_node = next(network.successors(node))
|
||||
except StopIteration:
|
||||
raise NetworkTopologyError(f'{type(node).__name__} {node.uid} is not properly connected, please check network topology')
|
||||
next_node = get_next_node(node, network)
|
||||
visited_nodes.append(node)
|
||||
if next_node in visited_nodes:
|
||||
raise NetworkTopologyError(f'Loop detected for {type(node).__name__} {node.uid}, please check network topology')
|
||||
raise NetworkTopologyError(f'Loop detected for {type(node).__name__} {node.uid}, '
|
||||
+ 'please check network topology')
|
||||
if isinstance(node, elements.Edfa):
|
||||
node_loss = span_loss(network, prev_node)
|
||||
node_loss = span_loss(network, prev_node, equipment)
|
||||
voa = node.out_voa if node.out_voa else 0
|
||||
if node.delta_p is None:
|
||||
dp = target_power(network, next_node, equipment)
|
||||
if node.operational.delta_p is None:
|
||||
dp = target_power(network, next_node, equipment) + voa
|
||||
else:
|
||||
dp = node.delta_p
|
||||
dp = node.operational.delta_p
|
||||
if node.effective_gain is None or power_mode:
|
||||
gain_target = node_loss + dp - prev_dp + prev_voa
|
||||
else: # gain mode with effective_gain
|
||||
@@ -282,8 +342,8 @@ def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_d
|
||||
|
||||
if isinstance(prev_node, elements.Fiber):
|
||||
max_fiber_lineic_loss_for_raman = \
|
||||
equipment['Span']['default'].max_fiber_lineic_loss_for_raman
|
||||
raman_allowed = prev_node.params.loss_coef < max_fiber_lineic_loss_for_raman
|
||||
equipment['Span']['default'].max_fiber_lineic_loss_for_raman * 1e-3 # dB/m
|
||||
raman_allowed = (prev_node.params.loss_coef < max_fiber_lineic_loss_for_raman).all()
|
||||
else:
|
||||
raman_allowed = False
|
||||
|
||||
@@ -298,48 +358,246 @@ def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_d
|
||||
restrictions = next_node.restrictions['preamp_variety_list']
|
||||
else:
|
||||
restrictions = None
|
||||
edfa_variety, power_reduction = select_edfa(raman_allowed, gain_target, power_target, equipment, node.uid, restrictions)
|
||||
edfa_variety, power_reduction = select_edfa(raman_allowed, gain_target, power_target, equipment,
|
||||
node.uid, restrictions, verbose)
|
||||
extra_params = equipment['Edfa'][edfa_variety]
|
||||
node.params.update_params(extra_params.__dict__)
|
||||
dp += power_reduction
|
||||
gain_target += power_reduction
|
||||
elif node.params.raman and not raman_allowed:
|
||||
print(f'{ansi_escapes.red}WARNING{ansi_escapes.reset}: raman is used in node {node.uid}\n but fiber lineic loss is above threshold\n')
|
||||
else:
|
||||
# Check power saturation also in this case
|
||||
p_max = equipment['Edfa'][node.params.type_variety].p_max
|
||||
if power_mode:
|
||||
power_reduction = min(0, p_max - (pref_total_db + dp))
|
||||
else:
|
||||
pout = pref_total_db + prev_dp - node_loss - prev_voa + gain_target
|
||||
power_reduction = min(0, p_max - pout)
|
||||
dp += power_reduction
|
||||
gain_target += power_reduction
|
||||
if node.params.raman and not raman_allowed:
|
||||
if isinstance(prev_node, elements.Fiber):
|
||||
logger.warning(f'\n\tWARNING: raman is used in node {node.uid}\n '
|
||||
+ '\tbut fiber lineic loss is above threshold\n')
|
||||
else:
|
||||
logger.critical(f'\n\tWARNING: raman is used in node {node.uid}\n '
|
||||
+ '\tbut previous node is not a fiber\n')
|
||||
# if variety is imposed by user, and if the gain_target (computed or imposed) is also above
|
||||
# variety max gain + extended range, then warn that gain > max_gain + extended range
|
||||
if gain_target - equipment['Edfa'][node.params.type_variety].gain_flatmax - \
|
||||
equipment['Span']['default'].target_extended_gain > 1e-2:
|
||||
equipment['Span']['default'].target_extended_gain > 1e-2 and verbose:
|
||||
# 1e-2 to allow a small margin according to round2float min step
|
||||
print(f'{ansi_escapes.red}WARNING{ansi_escapes.reset}: '
|
||||
f'WARNING: effective gain in Node {node.uid} is above user '
|
||||
f'specified amplifier {node.params.type_variety}\n'
|
||||
f'max flat gain: {equipment["Edfa"][node.params.type_variety].gain_flatmax}dB ; '
|
||||
f'required gain: {gain_target}dB. Please check amplifier type.')
|
||||
logger.warning(f'\n\tWARNING: effective gain in Node {node.uid}\n'
|
||||
+ f'\tis above user specified amplifier {node.params.type_variety}\n'
|
||||
+ '\tmax flat gain: '
|
||||
+ f'{equipment["Edfa"][node.params.type_variety].gain_flatmax}dB ; '
|
||||
+ f'required gain: {round(gain_target, 2)}dB. Please check amplifier type.\n')
|
||||
|
||||
node.delta_p = dp if power_mode else None
|
||||
node.effective_gain = gain_target
|
||||
# if voa is not set, then set it and possibly optimize it with gain and update delta_p and
|
||||
# effective_gain values
|
||||
set_amplifier_voa(node, power_target, power_mode)
|
||||
# set_amplifier_voa may change delta_p in power_mode
|
||||
node._delta_p = node.delta_p if power_mode else dp
|
||||
|
||||
# target_pch_out_dbm records target power for design: If user defines one, then this is displayed,
|
||||
# else display the one computed during design
|
||||
if node.delta_p is not None and node.operational.delta_p is not None:
|
||||
# use the user defined target
|
||||
node.target_pch_out_dbm = round(node.operational.delta_p + pref_ch_db, 2)
|
||||
elif node.delta_p is not None:
|
||||
# use the design target if no target were set
|
||||
node.target_pch_out_dbm = round(node.delta_p + pref_ch_db, 2)
|
||||
elif node.delta_p is None:
|
||||
node.target_pch_out_dbm = None
|
||||
elif isinstance(node, elements.RamanFiber):
|
||||
_ = span_loss(network, node, equipment, input_power=pref_ch_db + dp)
|
||||
prev_dp = dp
|
||||
prev_voa = voa
|
||||
prev_node = node
|
||||
node = next_node
|
||||
# print(f'{node.uid}')
|
||||
|
||||
if isinstance(this_node, elements.Roadm):
|
||||
this_node.per_degree_pch_out_db = {k: v for k, v in this_node_degree.items()}
|
||||
|
||||
def set_roadm_ref_carrier(roadm, equipment):
|
||||
"""ref_carrier records carrier information used for design and usefull for equalization
|
||||
"""
|
||||
roadm.ref_carrier = ReferenceCarrier(baud_rate=equipment['SI']['default'].baud_rate,
|
||||
slot_width=equipment['SI']['default'].spacing)
|
||||
|
||||
|
||||
def set_roadm_per_degree_targets(roadm, network):
|
||||
"""Set target powers/PSD on all degrees
|
||||
This is needed to populate per_degree_pch_out_dbm or per_degree_pch_psd or per_degree_pch_psw dicts when
|
||||
they are not initialized by users.
|
||||
"""
|
||||
next_oms = (n for n in network.successors(roadm) if not isinstance(n, elements.Transceiver))
|
||||
|
||||
for node in next_oms:
|
||||
# go through all the OMS departing from the ROADM
|
||||
if node.uid not in roadm.per_degree_pch_out_dbm and node.uid not in roadm.per_degree_pch_psd and \
|
||||
node.uid not in roadm.per_degree_pch_psw:
|
||||
# if no target power is defined on this degree or no per degree target power is given use the global one
|
||||
if roadm.params.target_pch_out_db:
|
||||
roadm.per_degree_pch_out_dbm[node.uid] = roadm.params.target_pch_out_db
|
||||
elif roadm.params.target_psd_out_mWperGHz:
|
||||
roadm.per_degree_pch_psd[node.uid] = roadm.params.target_psd_out_mWperGHz
|
||||
elif roadm.params.target_out_mWperSlotWidth:
|
||||
roadm.per_degree_pch_psw[node.uid] = roadm.params.target_out_mWperSlotWidth
|
||||
else:
|
||||
raise ConfigurationError(roadm.uid, 'needs an equalization target')
|
||||
|
||||
|
||||
def set_roadm_input_powers(network, roadm, equipment, pref_ch_db):
|
||||
"""Set reference powers at ROADM input for a reference channel and based on the adjacent OMS.
|
||||
This supposes that there is no dependency on path. For example, the succession:
|
||||
node power out of element
|
||||
roadm A (target power -10dBm) -10dBm
|
||||
fiber A (16 dB loss) -26dBm
|
||||
roadm B (target power -12dBm) -26dBm
|
||||
fiber B (10 dB loss) -36dBm
|
||||
roadm C (target power -14dBm) -36dBm
|
||||
is not consistent because target powers in roadm B and roadm C can not be met.
|
||||
input power for the reference channel will be set -26 dBm in roadm B and -22dBm in roadm C,
|
||||
because at design time we can not know about path.
|
||||
The function raises a warning if target powers can not be met with the design.
|
||||
User should be aware that design was not successfull and that power reduction was applied.
|
||||
Note that this value is only used for visualisation purpose (to compute ROADM loss in elements).
|
||||
"""
|
||||
previous_elements = [n for n in network.predecessors(roadm)]
|
||||
roadm.ref_pch_in_dbm = {}
|
||||
for element in previous_elements:
|
||||
node = element
|
||||
loss = 0.0
|
||||
while isinstance(node, (elements.Fiber, elements.Fused, elements.RamanFiber)):
|
||||
# go through all predecessors until a power target is found either in an amplifier, a ROADM or a transceiver
|
||||
# then deduce power at ROADM input from this degree based on this target and crossed losses
|
||||
loss += node.loss
|
||||
previous_node = node
|
||||
node = next(network.predecessors(node))
|
||||
if isinstance(node, elements.Edfa):
|
||||
roadm.ref_pch_in_dbm[element.uid] = pref_ch_db + node._delta_p - node.out_voa - loss
|
||||
elif isinstance(node, elements.Roadm):
|
||||
roadm.ref_pch_in_dbm[element.uid] = \
|
||||
node.get_per_degree_ref_power(degree=previous_node.uid) - loss
|
||||
elif isinstance(node, elements.Transceiver):
|
||||
roadm.ref_pch_in_dbm[element.uid] = pref_ch_db - loss
|
||||
# check if target power can be met
|
||||
temp = []
|
||||
if roadm.per_degree_pch_out_dbm:
|
||||
temp.append(max([p for p in roadm.per_degree_pch_out_dbm.values()]))
|
||||
if roadm.per_degree_pch_psd:
|
||||
temp.append(max([psd2powerdbm(p, roadm.ref_carrier.baud_rate) for p in roadm.per_degree_pch_psd.values()]))
|
||||
if roadm.per_degree_pch_psw:
|
||||
temp.append(max([psd2powerdbm(p, roadm.ref_carrier.slot_width) for p in roadm.per_degree_pch_psw.values()]))
|
||||
if roadm.params.target_pch_out_db:
|
||||
temp.append(roadm.params.target_pch_out_db)
|
||||
if roadm.params.target_psd_out_mWperGHz:
|
||||
temp.append(psd2powerdbm(roadm.params.target_psd_out_mWperGHz, roadm.ref_carrier.baud_rate))
|
||||
if roadm.params.target_out_mWperSlotWidth:
|
||||
temp.append(psd2powerdbm(roadm.params.target_out_mWperSlotWidth, roadm.ref_carrier.slot_width))
|
||||
if not temp:
|
||||
raise ConfigurationError(f'Could not find target power/PSD/PSW in ROADM "{roadm.uid}"')
|
||||
target_to_be_supported = max(temp)
|
||||
for from_degree, in_power in roadm.ref_pch_in_dbm.items():
|
||||
if in_power < target_to_be_supported:
|
||||
logger.warning(
|
||||
f'WARNING: maximum target power {target_to_be_supported}dBm '
|
||||
+ f'in ROADM "{roadm.uid}" can not be met for at least one crossing path. Min input power '
|
||||
+ f'from "{from_degree}" direction is {round(in_power, 2)}dBm. Please correct input topology.'
|
||||
)
|
||||
|
||||
|
||||
def set_fiber_input_power(network, fiber, equipment, pref_ch_db):
|
||||
"""Set reference powers at fiber input for a reference channel.
|
||||
Supposes that target power out of ROADMs and amplifiers are consistent.
|
||||
This is only for visualisation purpose
|
||||
"""
|
||||
loss = 0.0
|
||||
node = next(network.predecessors(fiber))
|
||||
while isinstance(node, elements.Fused):
|
||||
loss += node.loss
|
||||
previous_node = node
|
||||
node = next(network.predecessors(node))
|
||||
if isinstance(node, (elements.Fiber, elements.RamanFiber)) and node.ref_pch_in_dbm is not None:
|
||||
fiber.ref_pch_in_dbm = node.ref_pch_in_dbm - loss - node.loss
|
||||
if isinstance(node, (elements.Fiber, elements.RamanFiber)) and node.ref_pch_in_dbm is None:
|
||||
set_fiber_input_power(network, node, equipment, pref_ch_db)
|
||||
fiber.ref_pch_in_dbm = node.ref_pch_in_dbm - loss - node.loss
|
||||
elif isinstance(node, elements.Roadm):
|
||||
fiber.ref_pch_in_dbm = \
|
||||
node.get_per_degree_ref_power(degree=previous_node.uid) - loss
|
||||
elif isinstance(node, elements.Edfa):
|
||||
fiber.ref_pch_in_dbm = pref_ch_db + node._delta_p - node.out_voa - loss
|
||||
elif isinstance(node, elements.Transceiver):
|
||||
fiber.ref_pch_in_dbm = pref_ch_db - loss
|
||||
|
||||
|
||||
def set_roadm_internal_paths(roadm, network):
|
||||
"""Set ROADM path types (express, add, drop)
|
||||
|
||||
Uses implicit guess if no information is set in ROADM
|
||||
"""
|
||||
next_oms = [n.uid for n in network.successors(roadm) if not isinstance(n, elements.Transceiver)]
|
||||
previous_oms = [n.uid for n in network.predecessors(roadm) if not isinstance(n, elements.Transceiver)]
|
||||
drop_port = [n.uid for n in network.successors(roadm) if isinstance(n, elements.Transceiver)]
|
||||
add_port = [n.uid for n in network.predecessors(roadm) if isinstance(n, elements.Transceiver)]
|
||||
|
||||
default_express = 'express'
|
||||
default_add = 'add'
|
||||
default_drop = 'drop'
|
||||
# take user defined element impairment id if it exists
|
||||
correct_from_degrees = []
|
||||
correct_add = []
|
||||
correct_to_degrees = []
|
||||
correct_drop = []
|
||||
for from_degree in previous_oms:
|
||||
correct_from_degrees.append(from_degree)
|
||||
for to_degree in next_oms:
|
||||
correct_to_degrees.append(to_degree)
|
||||
impairment_id = roadm.get_per_degree_impairment_id(from_degree, to_degree)
|
||||
roadm.set_roadm_paths(from_degree=from_degree, to_degree=to_degree, path_type=default_express,
|
||||
impairment_id=impairment_id)
|
||||
for drop in drop_port:
|
||||
correct_drop.append(drop)
|
||||
impairment_id = roadm.get_per_degree_impairment_id(from_degree, drop)
|
||||
path_type = roadm.get_path_type_per_id(impairment_id)
|
||||
# a degree connected to a transceiver MUST be add or drop
|
||||
# but a degree connected to something else could be an express, add or drop
|
||||
# (for example case of external shelves)
|
||||
if path_type and path_type != 'drop':
|
||||
msg = f'Roadm {roadm.uid} path_type is defined as {path_type} but it should be drop'
|
||||
raise NetworkTopologyError(msg)
|
||||
roadm.set_roadm_paths(from_degree=from_degree, to_degree=drop, path_type=default_drop,
|
||||
impairment_id=impairment_id)
|
||||
for to_degree in next_oms:
|
||||
for add in add_port:
|
||||
correct_add.append(add)
|
||||
impairment_id = roadm.get_per_degree_impairment_id(add, to_degree)
|
||||
path_type = roadm.get_path_type_per_id(impairment_id)
|
||||
if path_type and path_type != 'add':
|
||||
msg = f'Roadm {roadm.uid} path_type is defined as {path_type} but it should be add'
|
||||
raise NetworkTopologyError(msg)
|
||||
roadm.set_roadm_paths(from_degree=add, to_degree=to_degree, path_type=default_add,
|
||||
impairment_id=impairment_id)
|
||||
# sanity check: raise an error if per_degree from or to degrees are not in the correct list
|
||||
# raise an error if user defined path_type is not consistent with inferred path_type:
|
||||
for item in roadm.per_degree_impairments.values():
|
||||
if item['from_degree'] not in correct_from_degrees + correct_add or \
|
||||
item['to_degree'] not in correct_to_degrees + correct_drop:
|
||||
msg = f'Roadm {roadm.uid} has wrong from-to degree uid {item["from_degree"]} - {item["to_degree"]}'
|
||||
raise NetworkTopologyError(msg)
|
||||
|
||||
|
||||
def add_roadm_booster(network, roadm):
|
||||
next_nodes = [n for n in network.successors(roadm)
|
||||
if not (isinstance(n, elements.Transceiver) or isinstance(n, elements.Fused) or isinstance(n, elements.Edfa))]
|
||||
if not (isinstance(n, elements.Transceiver) or isinstance(n, elements.Fused)
|
||||
or isinstance(n, elements.Edfa))]
|
||||
# no amplification for fused spans or TRX
|
||||
for next_node in next_nodes:
|
||||
network.remove_edge(roadm, next_node)
|
||||
amp = elements.Edfa(
|
||||
uid=f'Edfa_booster_{roadm.uid}_to_{next_node.uid}',
|
||||
params={},
|
||||
params=EdfaParams.default_values,
|
||||
metadata={
|
||||
'location': {
|
||||
'latitude': roadm.lat,
|
||||
@@ -365,7 +623,7 @@ def add_roadm_preamp(network, roadm):
|
||||
network.remove_edge(prev_node, roadm)
|
||||
amp = elements.Edfa(
|
||||
uid=f'Edfa_preamp_{roadm.uid}_from_{prev_node.uid}',
|
||||
params={},
|
||||
params=EdfaParams.default_values,
|
||||
metadata={
|
||||
'location': {
|
||||
'latitude': roadm.lat,
|
||||
@@ -388,13 +646,13 @@ def add_roadm_preamp(network, roadm):
|
||||
|
||||
|
||||
def add_inline_amplifier(network, fiber):
|
||||
next_node = next(network.successors(fiber))
|
||||
next_node = get_next_node(fiber, network)
|
||||
if isinstance(next_node, elements.Fiber) or isinstance(next_node, elements.RamanFiber):
|
||||
# no amplification for fused spans or TRX
|
||||
network.remove_edge(fiber, next_node)
|
||||
amp = elements.Edfa(
|
||||
uid=f'Edfa_{fiber.uid}',
|
||||
params={},
|
||||
params=EdfaParams.default_values,
|
||||
metadata={
|
||||
'location': {
|
||||
'latitude': (fiber.lat + next_node.lat) / 2,
|
||||
@@ -413,6 +671,9 @@ def add_inline_amplifier(network, fiber):
|
||||
|
||||
|
||||
def calculate_new_length(fiber_length, bounds, target_length):
|
||||
"""If fiber is over boundary, then assume this is a link "intent" and computes the set of
|
||||
identical fiber spans this link should be composed of.
|
||||
"""
|
||||
if fiber_length < bounds.stop:
|
||||
return fiber_length, 1
|
||||
|
||||
@@ -426,13 +687,27 @@ def calculate_new_length(fiber_length, bounds, target_length):
|
||||
return (length1, n_spans1)
|
||||
elif (bounds.start <= length2 <= bounds.stop) and not(bounds.start <= length1 <= bounds.stop):
|
||||
return (length2, n_spans2)
|
||||
elif target_length - length1 < length2 - target_length:
|
||||
return (length1, n_spans1)
|
||||
else:
|
||||
elif length2 - target_length <= target_length - length1 and length2 <= bounds.stop:
|
||||
return (length2, n_spans2)
|
||||
else:
|
||||
return (length1, n_spans1)
|
||||
|
||||
|
||||
def split_fiber(network, fiber, bounds, target_length, equipment):
|
||||
def get_next_node(node, network):
|
||||
"""get_next node else raise tha appropriate error
|
||||
"""
|
||||
try:
|
||||
next_node = next(network.successors(node))
|
||||
return next_node
|
||||
except StopIteration:
|
||||
raise NetworkTopologyError(
|
||||
f'{type(node).__name__} {node.uid} is not properly connected, please check network topology')
|
||||
|
||||
|
||||
def split_fiber(network, fiber, bounds, target_length):
|
||||
"""If fiber length exceeds boundary then assume this is a link "intent", and replace this one-span link
|
||||
with an n_spans link, with identical fiber types.
|
||||
"""
|
||||
new_length, n_spans = calculate_new_length(fiber.params.length, bounds, target_length)
|
||||
if n_spans == 1:
|
||||
return
|
||||
@@ -475,11 +750,10 @@ def split_fiber(network, fiber, bounds, target_length, equipment):
|
||||
|
||||
|
||||
def add_connector_loss(network, fibers, default_con_in, default_con_out, EOL):
|
||||
"""Add default connector loss if no loss are defined. EOL repair margin is added as a connector loss
|
||||
"""
|
||||
for fiber in fibers:
|
||||
try:
|
||||
next_node = next(network.successors(fiber))
|
||||
except StopIteration:
|
||||
raise NetworkTopologyError(f'Fiber {fiber.uid} is not properly connected, please check network topology')
|
||||
next_node = get_next_node(fiber, network)
|
||||
if fiber.params.con_in is None:
|
||||
fiber.params.con_in = default_con_in
|
||||
if fiber.params.con_out is None:
|
||||
@@ -488,19 +762,18 @@ def add_connector_loss(network, fibers, default_con_in, default_con_out, EOL):
|
||||
fiber.params.con_out += EOL
|
||||
|
||||
|
||||
def add_fiber_padding(network, fibers, padding):
|
||||
"""last_fibers = (fiber for n in network.nodes()
|
||||
if not (isinstance(n, elements.Fiber) or isinstance(n, elements.Fused))
|
||||
for fiber in network.predecessors(n)
|
||||
if isinstance(fiber, elements.Fiber))"""
|
||||
def add_fiber_padding(network, fibers, padding, equipment):
|
||||
"""Add a padding att_in at the input of the 1st fiber of a succession of fibers and fused
|
||||
"""
|
||||
for fiber in fibers:
|
||||
try:
|
||||
next_node = next(network.successors(fiber))
|
||||
except StopIteration:
|
||||
raise NetworkTopologyError(f'Fiber {fiber.uid} is not properly connected, please check network topology')
|
||||
next_node = get_next_node(fiber, network)
|
||||
if isinstance(next_node, elements.Fused):
|
||||
continue
|
||||
this_span_loss = span_loss(network, fiber)
|
||||
# do not pad if this is a Raman Fiber
|
||||
if isinstance(fiber, elements.RamanFiber):
|
||||
continue
|
||||
this_span_loss = span_loss(network, fiber, equipment)
|
||||
fiber.design_span_loss = this_span_loss
|
||||
if this_span_loss < padding:
|
||||
# add a padding att_in at the input of the 1st fiber:
|
||||
# address the case when several fibers are spliced together
|
||||
@@ -509,38 +782,69 @@ def add_fiber_padding(network, fibers, padding):
|
||||
# just after a roadm: need to check that first_fiber is really a fiber
|
||||
if isinstance(first_fiber, elements.Fiber):
|
||||
first_fiber.params.att_in = first_fiber.params.att_in + padding - this_span_loss
|
||||
fiber.design_span_loss += first_fiber.params.att_in
|
||||
|
||||
|
||||
def build_network(network, equipment, pref_ch_db, pref_total_db):
|
||||
def add_missing_elements_in_network(network, equipment):
|
||||
"""Autodesign network: add missing elements. split fibers if their length is too big
|
||||
add ROADM preamp or booster and inline amplifiers between fibers
|
||||
"""
|
||||
default_span_data = equipment['Span']['default']
|
||||
max_length = int(convert_length(default_span_data.max_length, default_span_data.length_units))
|
||||
min_length = max(int(default_span_data.padding / 0.2 * 1e3), 50_000)
|
||||
bounds = range(min_length, max_length)
|
||||
target_length = max(min_length, 90_000)
|
||||
|
||||
# set roadm loss for gain_mode before to build network
|
||||
target_length = max(min_length, min(max_length, 90_000))
|
||||
fibers = [f for f in network.nodes() if isinstance(f, elements.Fiber)]
|
||||
add_connector_loss(network, fibers, default_span_data.con_in, default_span_data.con_out, default_span_data.EOL)
|
||||
add_fiber_padding(network, fibers, default_span_data.padding)
|
||||
# don't group split fiber and add amp in the same loop
|
||||
# =>for code clarity (at the expense of speed):
|
||||
for fiber in fibers:
|
||||
split_fiber(network, fiber, bounds, target_length, equipment)
|
||||
|
||||
split_fiber(network, fiber, bounds, target_length)
|
||||
roadms = [r for r in network.nodes() if isinstance(r, elements.Roadm)]
|
||||
for roadm in roadms:
|
||||
add_roadm_preamp(network, roadm)
|
||||
add_roadm_booster(network, roadm)
|
||||
|
||||
fibers = [f for f in network.nodes() if isinstance(f, elements.Fiber)]
|
||||
for fiber in fibers:
|
||||
add_inline_amplifier(network, fiber)
|
||||
|
||||
for roadm in roadms:
|
||||
set_egress_amplifier(network, roadm, equipment, pref_ch_db, pref_total_db)
|
||||
|
||||
trx = [t for t in network.nodes() if isinstance(t, elements.Transceiver)]
|
||||
for t in trx:
|
||||
next_node = next(network.successors(t), None)
|
||||
if next_node and not isinstance(next_node, elements.Roadm):
|
||||
set_egress_amplifier(network, t, equipment, 0, pref_total_db)
|
||||
def add_missing_fiber_attributes(network, equipment):
|
||||
"""Fill in connector loss with default values. Add the padding loss is required.
|
||||
EOL is added as a connector loss
|
||||
"""
|
||||
default_span_data = equipment['Span']['default']
|
||||
fibers = [f for f in network.nodes() if isinstance(f, elements.Fiber)]
|
||||
add_connector_loss(network, fibers, default_span_data.con_in, default_span_data.con_out, default_span_data.EOL)
|
||||
# don't group split fiber and add amp in the same loop
|
||||
# =>for code clarity (at the expense of speed):
|
||||
add_fiber_padding(network, fibers, default_span_data.padding, equipment)
|
||||
|
||||
|
||||
def build_network(network, equipment, pref_ch_db, pref_total_db, set_connector_losses=True, verbose=True):
|
||||
"""Set roadm equalization target and amplifier gain and power
|
||||
"""
|
||||
roadms = [r for r in network.nodes() if isinstance(r, elements.Roadm)]
|
||||
transceivers = [t for t in network.nodes() if isinstance(t, elements.Transceiver)]
|
||||
|
||||
if set_connector_losses:
|
||||
add_missing_fiber_attributes(network, equipment)
|
||||
# set roadm equalization targets first
|
||||
for roadm in roadms:
|
||||
set_roadm_ref_carrier(roadm, equipment)
|
||||
set_roadm_per_degree_targets(roadm, network)
|
||||
# then set amplifiers gain, delta_p and out_voa on each OMS
|
||||
for roadm in roadms + transceivers:
|
||||
set_egress_amplifier(network, roadm, equipment, pref_ch_db, pref_total_db, verbose)
|
||||
for roadm in roadms:
|
||||
set_roadm_input_powers(network, roadm, equipment, pref_ch_db)
|
||||
set_roadm_internal_paths(roadm, network)
|
||||
for fiber in [f for f in network.nodes() if isinstance(f, (elements.Fiber, elements.RamanFiber))]:
|
||||
set_fiber_input_power(network, fiber, equipment, pref_ch_db)
|
||||
|
||||
|
||||
def design_network(reference_channel, network, equipment, set_connector_losses=True, verbose=True):
|
||||
"""Network is designed according to reference channel. Verbose indicate if the function should
|
||||
print all warnings or not
|
||||
"""
|
||||
pref_ch_db = watt2dbm(reference_channel.power) # reference channel power
|
||||
pref_total_db = pref_ch_db + lin2db(reference_channel.nb_channel) # reference total power
|
||||
build_network(network, equipment, pref_ch_db, pref_total_db, set_connector_losses=set_connector_losses,
|
||||
verbose=verbose)
|
||||
|
||||
@@ -7,11 +7,12 @@ gnpy.core.parameters
|
||||
|
||||
This module contains all parameters to configure standard network elements.
|
||||
"""
|
||||
from collections import namedtuple
|
||||
|
||||
from scipy.constants import c, pi
|
||||
from numpy import squeeze, log10, exp
|
||||
from numpy import asarray, array, exp, sqrt, log, outer, ones, squeeze, append, flip, linspace, full
|
||||
|
||||
from gnpy.core.utils import db2lin, convert_length
|
||||
from gnpy.core.utils import convert_length
|
||||
from gnpy.core.exceptions import ParametersError
|
||||
|
||||
|
||||
@@ -28,110 +29,228 @@ class Parameters:
|
||||
|
||||
class PumpParams(Parameters):
|
||||
def __init__(self, power, frequency, propagation_direction):
|
||||
self._power = power
|
||||
self._frequency = frequency
|
||||
self._propagation_direction = propagation_direction
|
||||
|
||||
@property
|
||||
def power(self):
|
||||
return self._power
|
||||
|
||||
@property
|
||||
def frequency(self):
|
||||
return self._frequency
|
||||
|
||||
@property
|
||||
def propagation_direction(self):
|
||||
return self._propagation_direction
|
||||
self.power = power
|
||||
self.frequency = frequency
|
||||
self.propagation_direction = propagation_direction.lower()
|
||||
|
||||
|
||||
class RamanParams(Parameters):
|
||||
def __init__(self, **kwargs):
|
||||
self._flag_raman = kwargs['flag_raman']
|
||||
self._space_resolution = kwargs['space_resolution'] if 'space_resolution' in kwargs else None
|
||||
self._tolerance = kwargs['tolerance'] if 'tolerance' in kwargs else None
|
||||
def __init__(self, flag=False, result_spatial_resolution=10e3, solver_spatial_resolution=50):
|
||||
"""Simulation parameters used within the Raman Solver
|
||||
|
||||
@property
|
||||
def flag_raman(self):
|
||||
return self._flag_raman
|
||||
:params flag: boolean for enabling/disable the evaluation of the Raman power profile in frequency and position
|
||||
:params result_spatial_resolution: spatial resolution of the evaluated Raman power profile
|
||||
:params solver_spatial_resolution: spatial step for the iterative solution of the first order ode
|
||||
"""
|
||||
self.flag = flag
|
||||
self.result_spatial_resolution = result_spatial_resolution # [m]
|
||||
self.solver_spatial_resolution = solver_spatial_resolution # [m]
|
||||
|
||||
@property
|
||||
def space_resolution(self):
|
||||
return self._space_resolution
|
||||
|
||||
@property
|
||||
def tolerance(self):
|
||||
return self._tolerance
|
||||
def to_json(self):
|
||||
return {"flag": self.flag,
|
||||
"result_spatial_resolution": self.result_spatial_resolution,
|
||||
"solver_spatial_resolution": self.solver_spatial_resolution}
|
||||
|
||||
|
||||
class NLIParams(Parameters):
|
||||
def __init__(self, **kwargs):
|
||||
self._nli_method_name = kwargs['nli_method_name']
|
||||
self._wdm_grid_size = kwargs['wdm_grid_size']
|
||||
self._dispersion_tolerance = kwargs['dispersion_tolerance']
|
||||
self._phase_shift_tolerance = kwargs['phase_shift_tolerance']
|
||||
self._f_cut_resolution = None
|
||||
self._f_pump_resolution = None
|
||||
self._computed_channels = kwargs['computed_channels'] if 'computed_channels' in kwargs else None
|
||||
def __init__(self, method='gn_model_analytic', dispersion_tolerance=1, phase_shift_tolerance=0.1,
|
||||
computed_channels=None, computed_number_of_channels=None):
|
||||
"""Simulation parameters used within the Nli Solver
|
||||
|
||||
@property
|
||||
def nli_method_name(self):
|
||||
return self._nli_method_name
|
||||
:params method: formula for NLI calculation
|
||||
:params dispersion_tolerance: tuning parameter for ggn model solution
|
||||
:params phase_shift_tolerance: tuning parameter for ggn model solution
|
||||
:params computed_channels: the NLI is evaluated for these channels and extrapolated for the others
|
||||
:params computed_number_of_channels: the NLI is evaluated for this number of channels equally distributed
|
||||
in the spectrum and extrapolated for the others
|
||||
"""
|
||||
self.method = method.lower()
|
||||
self.dispersion_tolerance = dispersion_tolerance
|
||||
self.phase_shift_tolerance = phase_shift_tolerance
|
||||
self.computed_channels = computed_channels
|
||||
self.computed_number_of_channels = computed_number_of_channels
|
||||
|
||||
@property
|
||||
def wdm_grid_size(self):
|
||||
return self._wdm_grid_size
|
||||
|
||||
@property
|
||||
def dispersion_tolerance(self):
|
||||
return self._dispersion_tolerance
|
||||
|
||||
@property
|
||||
def phase_shift_tolerance(self):
|
||||
return self._phase_shift_tolerance
|
||||
|
||||
@property
|
||||
def f_cut_resolution(self):
|
||||
return self._f_cut_resolution
|
||||
|
||||
@f_cut_resolution.setter
|
||||
def f_cut_resolution(self, f_cut_resolution):
|
||||
self._f_cut_resolution = f_cut_resolution
|
||||
|
||||
@property
|
||||
def f_pump_resolution(self):
|
||||
return self._f_pump_resolution
|
||||
|
||||
@f_pump_resolution.setter
|
||||
def f_pump_resolution(self, f_pump_resolution):
|
||||
self._f_pump_resolution = f_pump_resolution
|
||||
|
||||
@property
|
||||
def computed_channels(self):
|
||||
return self._computed_channels
|
||||
def to_json(self):
|
||||
return {"method": self.method,
|
||||
"dispersion_tolerance": self.dispersion_tolerance,
|
||||
"phase_shift_tolerance": self.phase_shift_tolerance,
|
||||
"computed_channels": self.computed_channels,
|
||||
"computed_number_of_channels": self.computed_number_of_channels}
|
||||
|
||||
|
||||
class SimParams(Parameters):
|
||||
def __init__(self, **kwargs):
|
||||
try:
|
||||
if 'nli_parameters' in kwargs:
|
||||
self._nli_params = NLIParams(**kwargs['nli_parameters'])
|
||||
else:
|
||||
self._nli_params = None
|
||||
if 'raman_parameters' in kwargs:
|
||||
self._raman_params = RamanParams(**kwargs['raman_parameters'])
|
||||
else:
|
||||
self._raman_params = None
|
||||
except KeyError as e:
|
||||
raise ParametersError(f'Simulation parameters must include {e}. Configuration: {kwargs}')
|
||||
_shared_dict = {'nli_params': NLIParams(), 'raman_params': RamanParams()}
|
||||
|
||||
@classmethod
|
||||
def set_params(cls, sim_params):
|
||||
cls._shared_dict['nli_params'] = NLIParams(**sim_params.get('nli_params', {}))
|
||||
cls._shared_dict['raman_params'] = RamanParams(**sim_params.get('raman_params', {}))
|
||||
|
||||
@property
|
||||
def nli_params(self):
|
||||
return self._nli_params
|
||||
return self._shared_dict['nli_params']
|
||||
|
||||
@property
|
||||
def raman_params(self):
|
||||
return self._raman_params
|
||||
return self._shared_dict['raman_params']
|
||||
|
||||
|
||||
class RoadmParams(Parameters):
|
||||
def __init__(self, **kwargs):
|
||||
self.target_pch_out_db = kwargs.get('target_pch_out_db')
|
||||
self.target_psd_out_mWperGHz = kwargs.get('target_psd_out_mWperGHz')
|
||||
self.target_out_mWperSlotWidth = kwargs.get('target_out_mWperSlotWidth')
|
||||
equalisation_type = ['target_pch_out_db', 'target_psd_out_mWperGHz', 'target_out_mWperSlotWidth']
|
||||
temp = [kwargs.get(k) is not None for k in equalisation_type]
|
||||
if sum(temp) > 1:
|
||||
raise ParametersError('ROADM config contains more than one equalisation type.'
|
||||
+ 'Please choose only one', kwargs)
|
||||
self.per_degree_pch_out_db = kwargs.get('per_degree_pch_out_db', {})
|
||||
self.per_degree_pch_psd = kwargs.get('per_degree_psd_out_mWperGHz', {})
|
||||
self.per_degree_pch_psw = kwargs.get('per_degree_psd_out_mWperSlotWidth', {})
|
||||
try:
|
||||
self.add_drop_osnr = kwargs['add_drop_osnr']
|
||||
self.pmd = kwargs['pmd']
|
||||
self.pdl = kwargs['pdl']
|
||||
self.restrictions = kwargs['restrictions']
|
||||
self.roadm_path_impairments = self.get_roadm_path_impairments(kwargs['roadm-path-impairments'])
|
||||
except KeyError as e:
|
||||
raise ParametersError(f'ROADM configurations must include {e}. Configuration: {kwargs}')
|
||||
self.per_degree_impairments = kwargs.get('per_degree_impairments', [])
|
||||
|
||||
def get_roadm_path_impairments(self, path_impairments_list):
|
||||
"""Get the ROADM list of profiles for impairments definition
|
||||
|
||||
transform the ietf model into gnpy internal model: add a path-type in the attributes
|
||||
"""
|
||||
if not path_impairments_list:
|
||||
return {}
|
||||
authorized_path_types = {
|
||||
'roadm-express-path': 'express',
|
||||
'roadm-add-path': 'add',
|
||||
'roadm-drop-path': 'drop',
|
||||
}
|
||||
roadm_path_impairments = {}
|
||||
for path_impairment in path_impairments_list:
|
||||
index = path_impairment['roadm-path-impairments-id']
|
||||
path_type = next(key for key in path_impairment if key in authorized_path_types.keys())
|
||||
impairment_dict = dict({'path-type': authorized_path_types[path_type]}, **path_impairment[path_type][0])
|
||||
roadm_path_impairments[index] = RoadmImpairment(impairment_dict)
|
||||
return roadm_path_impairments
|
||||
|
||||
|
||||
class RoadmPath:
|
||||
def __init__(self, from_degree, to_degree, path_type, impairment_id=None, impairment=None):
|
||||
"""Records roadm internal paths, types and impairment
|
||||
|
||||
path_type must be in "express", "add", "drop"
|
||||
impairment_id must be one of the id detailed in equipement
|
||||
"""
|
||||
self.from_degree = from_degree
|
||||
self.to_degree = to_degree
|
||||
self.path_type = path_type
|
||||
self.impairment_id = impairment_id
|
||||
self.impairment = impairment
|
||||
|
||||
|
||||
class RoadmImpairment:
|
||||
"""Generic definition of impairments for express, add and drop"""
|
||||
def __init__(self, params):
|
||||
"""Records roadm internal paths and types"""
|
||||
self.path_type = params.get('path-type')
|
||||
self.pmd = params.get('roadm-pmd')
|
||||
self.cd = params.get('roadm-cd')
|
||||
self.pdl = params.get('roadm-pdl')
|
||||
self.inband_crosstalk = params.get('roadm-inband-crosstalk')
|
||||
self.maxloss = params.get('roadm-maxloss', 0)
|
||||
if params.get('frequency-range') is not None:
|
||||
self.fmin = params.get('frequency-range')['lower-frequency']
|
||||
self.fmax = params.get('frequency-range')['upper-frequency']
|
||||
else:
|
||||
self.fmin, self.fmax = None, None
|
||||
self.osnr = params.get('roadm-osnr', None)
|
||||
self.pmax = params.get('roadm-pmax', None)
|
||||
self.nf = params.get('roadm-noise-figure', None)
|
||||
self.minloss = params.get('minloss', None)
|
||||
self.typloss = params.get('typloss', None)
|
||||
self.pmin = params.get('pmin', None)
|
||||
self.ptyp = params.get('ptyp', None)
|
||||
|
||||
|
||||
class FusedParams(Parameters):
|
||||
def __init__(self, **kwargs):
|
||||
self.loss = kwargs['loss'] if 'loss' in kwargs else 1
|
||||
|
||||
|
||||
DEFAULT_RAMAN_COEFFICIENT = {
|
||||
# SSMF Raman coefficient profile in terms of mode intensity (g0 * A_ff_overlap)
|
||||
'gamma_raman': array(
|
||||
[0.0, 8.524419934705497e-16, 2.643567866245371e-15, 4.410548410941305e-15, 6.153422961291078e-15,
|
||||
7.484924703044943e-15, 8.452060808349209e-15, 9.101549322698156e-15, 9.57837595158966e-15,
|
||||
1.0008642675474562e-14, 1.0865773569905647e-14, 1.1300776305865833e-14, 1.2143238647099625e-14,
|
||||
1.3231065750676068e-14, 1.4624900971525384e-14, 1.6013330554840492e-14, 1.7458119359310242e-14,
|
||||
1.9320241330434762e-14, 2.1720395392873534e-14, 2.4137337406734775e-14, 2.628163218460466e-14,
|
||||
2.8041019963285974e-14, 2.9723155447089933e-14, 3.129353531005888e-14, 3.251796163324624e-14,
|
||||
3.3198839487612773e-14, 3.329527690685666e-14, 3.313155691238456e-14, 3.289013852154548e-14,
|
||||
3.2458917188506916e-14, 3.060684277937575e-14, 3.2660349473783173e-14, 2.957419109657689e-14,
|
||||
2.518894321396672e-14, 1.734560485857344e-14, 9.902860761605233e-15, 7.219176385099358e-15,
|
||||
6.079565990401311e-15, 5.828373065963427e-15, 7.20580801091692e-15, 7.561924351387493e-15,
|
||||
7.621152352332206e-15, 6.8859886780643254e-15, 5.629181047471162e-15, 3.679727598966185e-15,
|
||||
2.7555869742500355e-15, 2.4810133942597675e-15, 2.2160080532403624e-15, 2.1440626024765557e-15,
|
||||
2.33873070799544e-15, 2.557317929858713e-15, 3.039839048226572e-15, 4.8337165515610065e-15,
|
||||
5.4647431818257436e-15, 5.229187813711269e-15, 4.510768525811313e-15, 3.3213473130607794e-15,
|
||||
2.2602577027996455e-15, 1.969576495866441e-15, 1.5179853954188527e-15, 1.2953988551200156e-15,
|
||||
1.1304672156251838e-15, 9.10004390675213e-16, 8.432919922183503e-16, 7.849224069008326e-16,
|
||||
7.827568196032024e-16, 9.000514440646232e-16, 1.3025926460013665e-15, 1.5444108938497558e-15,
|
||||
1.8795594063060786e-15, 1.7796130169921014e-15, 1.5938159865046653e-15, 1.1585522355108287e-15,
|
||||
8.507044444633358e-16, 7.625404663756823e-16, 8.14510750925789e-16, 9.047944693473188e-16,
|
||||
9.636431901702084e-16, 9.298633899602105e-16, 8.349739503637023e-16, 7.482901278066085e-16,
|
||||
6.240794767134268e-16, 5.00652535687506e-16, 3.553373263685851e-16, 2.0344217706119682e-16,
|
||||
1.4267522642294203e-16, 8.980016576743517e-17, 2.9829068181832594e-17, 1.4861959129014824e-17,
|
||||
7.404482113326137e-18]
|
||||
), # m/W
|
||||
# SSMF Raman coefficient profile
|
||||
'g0': array(
|
||||
[0.00000000e+00, 1.12351610e-05, 3.47838074e-05, 5.79356636e-05, 8.06921680e-05, 9.79845709e-05, 1.10454361e-04,
|
||||
1.18735302e-04, 1.24736889e-04, 1.30110053e-04, 1.41001273e-04, 1.46383247e-04, 1.57011792e-04, 1.70765865e-04,
|
||||
1.88408911e-04, 2.05914127e-04, 2.24074028e-04, 2.47508283e-04, 2.77729174e-04, 3.08044243e-04, 3.34764439e-04,
|
||||
3.56481704e-04, 3.77127256e-04, 3.96269124e-04, 4.10955175e-04, 4.18718761e-04, 4.19511263e-04, 4.17025384e-04,
|
||||
4.13565369e-04, 4.07726048e-04, 3.83671291e-04, 4.08564283e-04, 3.69571936e-04, 3.14442090e-04, 2.16074535e-04,
|
||||
1.23097823e-04, 8.95457457e-05, 7.52470400e-05, 7.19806145e-05, 8.87961158e-05, 9.30812065e-05, 9.37058268e-05,
|
||||
8.45719619e-05, 6.90585286e-05, 4.50407159e-05, 3.36521245e-05, 3.02292475e-05, 2.69376939e-05, 2.60020897e-05,
|
||||
2.82958958e-05, 3.08667558e-05, 3.66024657e-05, 5.80610307e-05, 6.54797937e-05, 6.25022715e-05, 5.37806442e-05,
|
||||
3.94996621e-05, 2.68120644e-05, 2.33038554e-05, 1.79140757e-05, 1.52472424e-05, 1.32707565e-05, 1.06541760e-05,
|
||||
9.84649374e-06, 9.13999627e-06, 9.08971012e-06, 1.04227525e-05, 1.50419271e-05, 1.77838232e-05, 2.15810815e-05,
|
||||
2.03744008e-05, 1.81939341e-05, 1.31862121e-05, 9.65352116e-06, 8.62698322e-06, 9.18688016e-06, 1.01737784e-05,
|
||||
1.08017817e-05, 1.03903588e-05, 9.30040333e-06, 8.30809173e-06, 6.90650401e-06, 5.52238029e-06, 3.90648708e-06,
|
||||
2.22908227e-06, 1.55796177e-06, 9.77218716e-07, 3.23477236e-07, 1.60602454e-07, 7.97306386e-08]
|
||||
), # [1 / (W m)]
|
||||
|
||||
# Note the non-uniform spacing of this range; this is required for properly capturing the Raman peak shape.
|
||||
'frequency_offset': array([
|
||||
0., 0.5, 1., 1.5, 2., 2.5, 3., 3.5, 4., 4.5, 5., 5.5, 6., 6.5, 7., 7.5, 8., 8.5, 9., 9.5, 10., 10.5, 11., 11.5,
|
||||
12., 12.5, 12.75, 13., 13.25, 13.5, 14., 14.5, 14.75, 15., 15.5, 16., 16.5, 17., 17.5, 18., 18.25, 18.5, 18.75,
|
||||
19., 19.5, 20., 20.5, 21., 21.5, 22., 22.5, 23., 23.5, 24., 24.5, 25., 25.5, 26., 26.5, 27., 27.5, 28., 28.5,
|
||||
29., 29.5, 30., 30.5, 31., 31.5, 32., 32.5, 33., 33.5, 34., 34.5, 35., 35.5, 36., 36.5, 37., 37.5, 38., 38.5,
|
||||
39., 39.5, 40., 40.5, 41., 41.5, 42.]) * 1e12, # [Hz]
|
||||
|
||||
# Raman profile reference frequency
|
||||
'reference_frequency': 206.184634112792e12, # [Hz] (1454 nm)
|
||||
|
||||
# Raman profile reference effective area
|
||||
'reference_effective_area': 75.74659443542413e-12 # [m^2] (@1454 nm)
|
||||
}
|
||||
|
||||
|
||||
class RamanGainCoefficient(namedtuple('RamanGainCoefficient', 'normalized_gamma_raman frequency_offset')):
|
||||
""" Raman Gain Coefficient Parameters
|
||||
|
||||
Based on:
|
||||
Andrea D’Amico, Bruno Correia, Elliot London, Emanuele Virgillito, Giacomo Borraccini, Antonio Napoli,
|
||||
and Vittorio Curri, "Scalable and Disaggregated GGN Approximation Applied to a C+L+S Optical Network,"
|
||||
J. Lightwave Technol. 40, 3499-3511 (2022)
|
||||
Section III.D
|
||||
"""
|
||||
|
||||
|
||||
class FiberParams(Parameters):
|
||||
@@ -139,45 +258,94 @@ class FiberParams(Parameters):
|
||||
try:
|
||||
self._length = convert_length(kwargs['length'], kwargs['length_units'])
|
||||
# fixed attenuator for padding
|
||||
self._att_in = kwargs['att_in'] if 'att_in' in kwargs else 0
|
||||
self._att_in = kwargs.get('att_in', 0)
|
||||
# if not defined in the network json connector loss in/out
|
||||
# the None value will be updated in network.py[build_network]
|
||||
# with default values from eqpt_config.json[Spans]
|
||||
self._con_in = kwargs['con_in'] if 'con_in' in kwargs else None
|
||||
self._con_out = kwargs['con_out'] if 'con_out' in kwargs else None
|
||||
self._con_in = kwargs.get('con_in')
|
||||
self._con_out = kwargs.get('con_out')
|
||||
|
||||
# Reference frequency (unique for all parameters: beta2, beta3, gamma, effective_area)
|
||||
if 'ref_wavelength' in kwargs:
|
||||
self._ref_wavelength = kwargs['ref_wavelength']
|
||||
self._ref_frequency = c / self.ref_wavelength
|
||||
self._ref_frequency = c / self._ref_wavelength
|
||||
elif 'ref_frequency' in kwargs:
|
||||
self._ref_frequency = kwargs['ref_frequency']
|
||||
self._ref_wavelength = c / self.ref_frequency
|
||||
self._ref_wavelength = c / self._ref_frequency
|
||||
else:
|
||||
self._ref_wavelength = 1550e-9
|
||||
self._ref_frequency = c / self.ref_wavelength
|
||||
self._dispersion = kwargs['dispersion'] # s/m/m
|
||||
self._dispersion_slope = kwargs['dispersion_slope'] if 'dispersion_slope' in kwargs else \
|
||||
-2 * self._dispersion/self.ref_wavelength # s/m/m/m
|
||||
self._beta2 = -(self.ref_wavelength ** 2) * self.dispersion / (2 * pi * c) # 1/(m * Hz^2)
|
||||
# Eq. (3.23) in Abramczyk, Halina. "Dispersion phenomena in optical fibers." Virtual European University
|
||||
# on Lasers. Available online: http://mitr.p.lodz.pl/evu/lectures/Abramczyk3.pdf
|
||||
# (accessed on 25 March 2018) (2005).
|
||||
self._beta3 = ((self.dispersion_slope - (4*pi*c/self.ref_wavelength**3) * self.beta2) /
|
||||
(2*pi*c/self.ref_wavelength**2)**2)
|
||||
self._gamma = kwargs['gamma'] # 1/W/m
|
||||
self._ref_wavelength = 1550e-9 # conventional central C band wavelength [m]
|
||||
self._ref_frequency = c / self._ref_wavelength
|
||||
|
||||
# Chromatic Dispersion
|
||||
if 'dispersion_per_frequency' in kwargs:
|
||||
# Frequency-dependent dispersion
|
||||
self._dispersion = asarray(kwargs['dispersion_per_frequency']['value']) # s/m/m
|
||||
self._f_dispersion_ref = asarray(kwargs['dispersion_per_frequency']['frequency']) # Hz
|
||||
self._dispersion_slope = None
|
||||
elif 'dispersion' in kwargs:
|
||||
# Single value dispersion
|
||||
self._dispersion = asarray(kwargs['dispersion']) # s/m/m
|
||||
self._dispersion_slope = kwargs.get('dispersion_slope') # s/m/m/m
|
||||
self._f_dispersion_ref = asarray(self._ref_frequency) # Hz
|
||||
else:
|
||||
# Default single value dispersion
|
||||
self._dispersion = asarray(1.67e-05) # s/m/m
|
||||
self._dispersion_slope = None
|
||||
self._f_dispersion_ref = asarray(self.ref_frequency) # Hz
|
||||
|
||||
# Effective Area and Nonlinear Coefficient
|
||||
self._effective_area = kwargs.get('effective_area') # m^2
|
||||
self._n1 = 1.468
|
||||
self._core_radius = 4.2e-6 # m
|
||||
self._n2 = 2.6e-20 # m^2/W
|
||||
if self._effective_area is not None:
|
||||
default_gamma = 2 * pi * self._n2 / (self._ref_wavelength * self._effective_area)
|
||||
self._gamma = kwargs.get('gamma', default_gamma) # 1/W/m
|
||||
elif 'gamma' in kwargs:
|
||||
self._gamma = kwargs['gamma'] # 1/W/m
|
||||
self._effective_area = 2 * pi * self._n2 / (self._ref_wavelength * self._gamma) # m^2
|
||||
else:
|
||||
self._effective_area = 83e-12 # m^2
|
||||
self._gamma = 2 * pi * self._n2 / (self._ref_wavelength * self._effective_area) # 1/W/m
|
||||
self._contrast = 0.5 * (c / (2 * pi * self._ref_frequency * self._core_radius * self._n1) * exp(
|
||||
pi * self._core_radius ** 2 / self._effective_area)) ** 2
|
||||
|
||||
# Raman Gain Coefficient
|
||||
raman_coefficient = kwargs.get('raman_coefficient')
|
||||
if raman_coefficient is None:
|
||||
self._raman_reference_frequency = DEFAULT_RAMAN_COEFFICIENT['reference_frequency']
|
||||
frequency_offset = asarray(DEFAULT_RAMAN_COEFFICIENT['frequency_offset'])
|
||||
gamma_raman = asarray(DEFAULT_RAMAN_COEFFICIENT['gamma_raman'])
|
||||
stokes_wave = self._raman_reference_frequency - frequency_offset
|
||||
normalized_gamma_raman = gamma_raman / self._raman_reference_frequency # 1 / m / W / Hz
|
||||
self._g0 = gamma_raman / self.effective_area_overlap(stokes_wave, self._raman_reference_frequency)
|
||||
else:
|
||||
self._raman_reference_frequency = raman_coefficient['reference_frequency']
|
||||
frequency_offset = asarray(raman_coefficient['frequency_offset'])
|
||||
stokes_wave = self._raman_reference_frequency - frequency_offset
|
||||
self._g0 = asarray(raman_coefficient['g0'])
|
||||
gamma_raman = self._g0 * self.effective_area_overlap(stokes_wave, self._raman_reference_frequency)
|
||||
normalized_gamma_raman = gamma_raman / self._raman_reference_frequency # 1 / m / W / Hz
|
||||
|
||||
# Raman gain coefficient array of the frequency offset constructed such that positive frequency values
|
||||
# represent a positive power transfer from higher frequency and vice versa
|
||||
frequency_offset = append(-flip(frequency_offset[1:]), frequency_offset)
|
||||
normalized_gamma_raman = append(- flip(normalized_gamma_raman[1:]), normalized_gamma_raman)
|
||||
self._raman_coefficient = RamanGainCoefficient(normalized_gamma_raman, frequency_offset)
|
||||
|
||||
# Polarization Mode Dispersion
|
||||
self._pmd_coef = kwargs['pmd_coef'] # s/sqrt(m)
|
||||
if type(kwargs['loss_coef']) == dict:
|
||||
self._loss_coef = squeeze(kwargs['loss_coef']['loss_coef_power']) * 1e-3 # lineic loss dB/m
|
||||
self._f_loss_ref = squeeze(kwargs['loss_coef']['frequency']) # Hz
|
||||
|
||||
# Loss Coefficient
|
||||
if isinstance(kwargs['loss_coef'], dict):
|
||||
self._loss_coef = asarray(kwargs['loss_coef']['value']) * 1e-3 # lineic loss dB/m
|
||||
self._f_loss_ref = asarray(kwargs['loss_coef']['frequency']) # Hz
|
||||
else:
|
||||
self._loss_coef = kwargs['loss_coef'] * 1e-3 # lineic loss dB/m
|
||||
self._f_loss_ref = 193.5e12 # Hz
|
||||
self._lin_attenuation = db2lin(self.length * self.loss_coef)
|
||||
self._lin_loss_exp = self.loss_coef / (10 * log10(exp(1))) # linear power exponent loss Neper/m
|
||||
self._effective_length = (1 - exp(- self.lin_loss_exp * self.length)) / self.lin_loss_exp
|
||||
self._asymptotic_length = 1 / self.lin_loss_exp
|
||||
# raman parameters (not compulsory)
|
||||
self._raman_efficiency = kwargs['raman_efficiency'] if 'raman_efficiency' in kwargs else None
|
||||
self._pumps_loss_coef = kwargs['pumps_loss_coef'] if 'pumps_loss_coef' in kwargs else None
|
||||
self._loss_coef = asarray(kwargs['loss_coef']) * 1e-3 # lineic loss dB/m
|
||||
self._f_loss_ref = asarray(self._ref_frequency) # Hz
|
||||
# Lumped Losses
|
||||
self._lumped_losses = kwargs['lumped_losses'] if 'lumped_losses' in kwargs else array([])
|
||||
self._latency = self._length / (c / self._n1) # s
|
||||
except KeyError as e:
|
||||
raise ParametersError(f'Fiber configurations json must include {e}. Configuration: {kwargs}')
|
||||
|
||||
@@ -210,6 +378,10 @@ class FiberParams(Parameters):
|
||||
def con_out(self):
|
||||
return self._con_out
|
||||
|
||||
@property
|
||||
def lumped_losses(self):
|
||||
return self._lumped_losses
|
||||
|
||||
@con_out.setter
|
||||
def con_out(self, con_out):
|
||||
self._con_out = con_out
|
||||
@@ -218,6 +390,10 @@ class FiberParams(Parameters):
|
||||
def dispersion(self):
|
||||
return self._dispersion
|
||||
|
||||
@property
|
||||
def f_dispersion_ref(self):
|
||||
return self._f_dispersion_ref
|
||||
|
||||
@property
|
||||
def dispersion_slope(self):
|
||||
return self._dispersion_slope
|
||||
@@ -226,6 +402,20 @@ class FiberParams(Parameters):
|
||||
def gamma(self):
|
||||
return self._gamma
|
||||
|
||||
def effective_area_scaling(self, frequency):
|
||||
V = 2 * pi * frequency / c * self._core_radius * self._n1 * sqrt(2 * self._contrast)
|
||||
w = self._core_radius / sqrt(log(V))
|
||||
return asarray(pi * w ** 2)
|
||||
|
||||
def effective_area_overlap(self, frequency_stokes_wave, frequency_pump):
|
||||
effective_area_stokes_wave = self.effective_area_scaling(frequency_stokes_wave)
|
||||
effective_area_pump = self.effective_area_scaling(frequency_pump)
|
||||
return squeeze(outer(effective_area_stokes_wave, ones(effective_area_pump.size)) + outer(
|
||||
ones(effective_area_stokes_wave.size), effective_area_pump)) / 2
|
||||
|
||||
def gamma_scaling(self, frequency):
|
||||
return asarray(2 * pi * self._n2 * frequency / (c * self.effective_area_scaling(frequency)))
|
||||
|
||||
@property
|
||||
def pmd_coef(self):
|
||||
return self._pmd_coef
|
||||
@@ -238,14 +428,6 @@ class FiberParams(Parameters):
|
||||
def ref_frequency(self):
|
||||
return self._ref_frequency
|
||||
|
||||
@property
|
||||
def beta2(self):
|
||||
return self._beta2
|
||||
|
||||
@property
|
||||
def beta3(self):
|
||||
return self._beta3
|
||||
|
||||
@property
|
||||
def loss_coef(self):
|
||||
return self._loss_coef
|
||||
@@ -255,31 +437,180 @@ class FiberParams(Parameters):
|
||||
return self._f_loss_ref
|
||||
|
||||
@property
|
||||
def lin_loss_exp(self):
|
||||
return self._lin_loss_exp
|
||||
def raman_coefficient(self):
|
||||
return self._raman_coefficient
|
||||
|
||||
@property
|
||||
def lin_attenuation(self):
|
||||
return self._lin_attenuation
|
||||
|
||||
@property
|
||||
def effective_length(self):
|
||||
return self._effective_length
|
||||
|
||||
@property
|
||||
def asymptotic_length(self):
|
||||
return self._asymptotic_length
|
||||
|
||||
@property
|
||||
def raman_efficiency(self):
|
||||
return self._raman_efficiency
|
||||
|
||||
@property
|
||||
def pumps_loss_coef(self):
|
||||
return self._pumps_loss_coef
|
||||
def latency(self):
|
||||
return self._latency
|
||||
|
||||
def asdict(self):
|
||||
dictionary = super().asdict()
|
||||
dictionary['loss_coef'] = self.loss_coef * 1e3
|
||||
dictionary['length_units'] = 'm'
|
||||
if len(self.lumped_losses) == 0:
|
||||
dictionary.pop('lumped_losses')
|
||||
if not self.raman_coefficient:
|
||||
dictionary.pop('raman_coefficient')
|
||||
else:
|
||||
raman_frequency_offset = \
|
||||
self.raman_coefficient.frequency_offset[self.raman_coefficient.frequency_offset >= 0]
|
||||
dictionary['raman_coefficient'] = {'g0': self._g0.tolist(),
|
||||
'frequency_offset': raman_frequency_offset.tolist(),
|
||||
'reference_frequency': self._raman_reference_frequency}
|
||||
return dictionary
|
||||
|
||||
|
||||
class EdfaParams:
|
||||
default_values = {
|
||||
'f_min': 191.3e12,
|
||||
'f_max': 196.1e12,
|
||||
'multi_band': None,
|
||||
'bands': [],
|
||||
'type_variety': '',
|
||||
'type_def': '',
|
||||
'gain_flatmax': None,
|
||||
'gain_min': None,
|
||||
'p_max': None,
|
||||
'nf_model': None,
|
||||
'dual_stage_model': None,
|
||||
'preamp_variety': None,
|
||||
'booster_variety': None,
|
||||
'nf_min': None,
|
||||
'nf_max': None,
|
||||
'nf_coef': None,
|
||||
'nf0': None,
|
||||
'nf_fit_coeff': None,
|
||||
'nf_ripple': 0,
|
||||
'dgt': None,
|
||||
'gain_ripple': 0,
|
||||
'tilt_ripple': 0,
|
||||
'f_ripple_ref': None,
|
||||
'out_voa_auto': False,
|
||||
'allowed_for_design': False,
|
||||
'raman': False,
|
||||
'pmd': 0,
|
||||
'pdl': 0,
|
||||
'advance_configurations_from_json': None
|
||||
}
|
||||
|
||||
def __init__(self, **params):
|
||||
try:
|
||||
self.type_variety = params['type_variety']
|
||||
self.type_def = params['type_def']
|
||||
|
||||
# Bandwidth
|
||||
self.f_min = params['f_min']
|
||||
self.f_max = params['f_max']
|
||||
self.bandwidth = self.f_max - self.f_min
|
||||
self.f_cent = (self.f_max + self.f_min) / 2
|
||||
self.f_ripple_ref = params['f_ripple_ref']
|
||||
|
||||
# Gain
|
||||
self.gain_flatmax = params['gain_flatmax']
|
||||
self.gain_min = params['gain_min']
|
||||
|
||||
gain_ripple = params['gain_ripple']
|
||||
if gain_ripple == 0:
|
||||
self.gain_ripple = asarray([0, 0])
|
||||
self.f_ripple_ref = asarray([self.f_min, self.f_max])
|
||||
else:
|
||||
self.gain_ripple = asarray(gain_ripple)
|
||||
if self.f_ripple_ref is not None:
|
||||
if (self.f_ripple_ref[0] != self.f_min) or (self.f_ripple_ref[-1] != self.f_max):
|
||||
raise ParametersError("The reference ripple frequency maximum and minimum have to coincide "
|
||||
"with the EDFA frequency maximum and minimum.")
|
||||
elif self.gain_ripple.size != self.f_ripple_ref.size:
|
||||
raise ParametersError("The reference ripple frequency and the gain ripple must have the same "
|
||||
"size.")
|
||||
else:
|
||||
self.f_ripple_ref = linspace(self.f_min, self.f_max, self.gain_ripple.size)
|
||||
|
||||
tilt_ripple = params['tilt_ripple']
|
||||
|
||||
if tilt_ripple == 0:
|
||||
self.tilt_ripple = full(self.gain_ripple.size, 0)
|
||||
else:
|
||||
self.tilt_ripple = asarray(tilt_ripple)
|
||||
if self.tilt_ripple.size != self.gain_ripple.size:
|
||||
raise ParametersError("The tilt ripple and the gain ripple must have the same size.")
|
||||
|
||||
# Power
|
||||
self.p_max = params['p_max']
|
||||
|
||||
# Noise Figure
|
||||
self.nf_model = params['nf_model']
|
||||
self.nf_min = params['nf_min']
|
||||
self.nf_max = params['nf_max']
|
||||
self.nf_coef = params['nf_coef']
|
||||
self.nf0 = params['nf0']
|
||||
self.nf_fit_coeff = params['nf_fit_coeff']
|
||||
|
||||
nf_ripple = params['nf_ripple']
|
||||
if nf_ripple == 0:
|
||||
self.nf_ripple = full(self.gain_ripple.size, 0)
|
||||
else:
|
||||
self.nf_ripple = asarray(nf_ripple)
|
||||
if self.nf_ripple.size != self.gain_ripple.size:
|
||||
raise ParametersError("The noise figure ripple and the gain ripple must have the same size.")
|
||||
|
||||
# VOA
|
||||
self.out_voa_auto = params['out_voa_auto']
|
||||
|
||||
# Dual Stage
|
||||
self.dual_stage_model = params['dual_stage_model']
|
||||
if self.dual_stage_model is not None:
|
||||
# Preamp
|
||||
self.preamp_variety = params['preamp_variety']
|
||||
self.preamp_type_def = params['preamp_type_def']
|
||||
self.preamp_nf_model = params['preamp_nf_model']
|
||||
self.preamp_nf_fit_coeff = params['preamp_nf_fit_coeff']
|
||||
self.preamp_gain_min = params['preamp_gain_min']
|
||||
self.preamp_gain_flatmax = params['preamp_gain_flatmax']
|
||||
|
||||
# Booster
|
||||
self.booster_variety = params['booster_variety']
|
||||
self.booster_type_def = params['booster_type_def']
|
||||
self.booster_nf_model = params['booster_nf_model']
|
||||
self.booster_nf_fit_coeff = params['booster_nf_fit_coeff']
|
||||
self.booster_gain_min = params['booster_gain_min']
|
||||
self.booster_gain_flatmax = params['booster_gain_flatmax']
|
||||
|
||||
# Others
|
||||
self.pmd = params['pmd']
|
||||
self.pdl = params['pdl']
|
||||
self.raman = params['raman']
|
||||
self.dgt = params['dgt']
|
||||
self.advance_configurations_from_json = params['advance_configurations_from_json']
|
||||
|
||||
# Design
|
||||
self.allowed_for_design = params['allowed_for_design']
|
||||
|
||||
except KeyError as e:
|
||||
raise ParametersError(f'Edfa configurations json must include {e}. Configuration: {params}')
|
||||
|
||||
def update_params(self, kwargs):
|
||||
for k, v in kwargs.items():
|
||||
setattr(self, k, self.update_params(**v) if isinstance(v, dict) else v)
|
||||
|
||||
|
||||
class EdfaOperational:
|
||||
default_values = {
|
||||
'gain_target': None,
|
||||
'delta_p': None,
|
||||
'out_voa': None,
|
||||
'tilt_target': 0
|
||||
}
|
||||
|
||||
def __init__(self, **operational):
|
||||
self.update_attr(operational)
|
||||
|
||||
def update_attr(self, kwargs):
|
||||
clean_kwargs = {k: v for k, v in kwargs.items() if v != ''}
|
||||
for k, v in self.default_values.items():
|
||||
setattr(self, k, clean_kwargs.get(k, v))
|
||||
|
||||
def __repr__(self):
|
||||
return (f'{type(self).__name__}('
|
||||
f'gain_target={self.gain_target!r}, '
|
||||
f'tilt_target={self.tilt_target!r})')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,8 +9,9 @@ This module contains utility functions that are used with gnpy.
|
||||
"""
|
||||
|
||||
from csv import writer
|
||||
from numpy import pi, cos, sqrt, log10, linspace, zeros, shape, where, logical_and
|
||||
from numpy import pi, cos, sqrt, log10, linspace, zeros, shape, where, logical_and, mean, array
|
||||
from scipy import constants
|
||||
from copy import deepcopy
|
||||
|
||||
from gnpy.core.exceptions import ConfigurationError
|
||||
|
||||
@@ -106,7 +107,99 @@ def db2lin(value):
|
||||
return 10**(value / 10)
|
||||
|
||||
|
||||
def watt2dbm(value):
|
||||
"""Convert Watt units to dBm
|
||||
|
||||
>>> round(watt2dbm(0.001), 1)
|
||||
0.0
|
||||
>>> round(watt2dbm(0.02), 1)
|
||||
13.0
|
||||
"""
|
||||
return lin2db(value * 1e3)
|
||||
|
||||
|
||||
def dbm2watt(value):
|
||||
"""Convert dBm units to Watt
|
||||
|
||||
>>> round(dbm2watt(0), 4)
|
||||
0.001
|
||||
>>> round(dbm2watt(-3), 4)
|
||||
0.0005
|
||||
>>> round(dbm2watt(13), 4)
|
||||
0.02
|
||||
"""
|
||||
return db2lin(value) * 1e-3
|
||||
|
||||
|
||||
def psd2powerdbm(psd_mwperghz, baudrate_baud):
|
||||
"""computes power in dBm based on baudrate in bauds and psd in mW/GHz
|
||||
|
||||
>>> round(psd2powerdbm(0.031176, 64e9),3)
|
||||
3.0
|
||||
>>> round(psd2powerdbm(0.062352, 32e9),3)
|
||||
3.0
|
||||
>>> round(psd2powerdbm(0.015625, 64e9),3)
|
||||
0.0
|
||||
"""
|
||||
return lin2db(baudrate_baud * psd_mwperghz * 1e-9)
|
||||
|
||||
|
||||
def power_dbm_to_psd_mw_ghz(power_dbm, baudrate_baud):
|
||||
"""computes power spectral density in mW/GHz based on baudrate in bauds and power in dBm
|
||||
|
||||
>>> power_dbm_to_psd_mw_ghz(0, 64e9)
|
||||
0.015625
|
||||
>>> round(power_dbm_to_psd_mw_ghz(3, 64e9), 6)
|
||||
0.031176
|
||||
>>> round(power_dbm_to_psd_mw_ghz(3, 32e9), 6)
|
||||
0.062352
|
||||
"""
|
||||
return db2lin(power_dbm) / (baudrate_baud * 1e-9)
|
||||
|
||||
|
||||
def psd_mw_per_ghz(power_watt, baudrate_baud):
|
||||
"""computes power spectral density in mW/GHz based on baudrate in bauds and power in W
|
||||
|
||||
>>> psd_mw_per_ghz(2e-3, 32e9)
|
||||
0.0625
|
||||
>>> psd_mw_per_ghz(1e-3, 64e9)
|
||||
0.015625
|
||||
>>> psd_mw_per_ghz(0.5e-3, 32e9)
|
||||
0.015625
|
||||
"""
|
||||
return power_watt * 1e3 / (baudrate_baud * 1e-9)
|
||||
|
||||
|
||||
def round2float(number, step):
|
||||
"""Round a floating point number so that its "resolution" is not bigger than 'step'
|
||||
|
||||
The finest step is fixed at 0.01; smaller values are silently changed to 0.01.
|
||||
|
||||
>>> round2float(123.456, 1000)
|
||||
0.0
|
||||
>>> round2float(123.456, 100)
|
||||
100.0
|
||||
>>> round2float(123.456, 10)
|
||||
120.0
|
||||
>>> round2float(123.456, 1)
|
||||
123.0
|
||||
>>> round2float(123.456, 0.1)
|
||||
123.5
|
||||
>>> round2float(123.456, 0.01)
|
||||
123.46
|
||||
>>> round2float(123.456, 0.001)
|
||||
123.46
|
||||
>>> round2float(123.249, 0.5)
|
||||
123.0
|
||||
>>> round2float(123.250, 0.5)
|
||||
123.0
|
||||
>>> round2float(123.251, 0.5)
|
||||
123.5
|
||||
>>> round2float(123.300, 0.2)
|
||||
123.2
|
||||
>>> round2float(123.301, 0.2)
|
||||
123.4
|
||||
"""
|
||||
step = round(step, 1)
|
||||
if step >= 0.01:
|
||||
number = round(number / step, 0)
|
||||
@@ -120,25 +213,39 @@ wavelength2freq = constants.lambda2nu
|
||||
freq2wavelength = constants.nu2lambda
|
||||
|
||||
|
||||
def freq2wavelength(value):
|
||||
""" Converts frequency units to wavelength units.
|
||||
|
||||
>>> round(freq2wavelength(191.35e12) * 1e9, 3)
|
||||
1566.723
|
||||
>>> round(freq2wavelength(196.1e12) * 1e9, 3)
|
||||
1528.773
|
||||
"""
|
||||
return constants.c / value
|
||||
|
||||
|
||||
def snr_sum(snr, bw, snr_added, bw_added=12.5e9):
|
||||
snr_added = snr_added - lin2db(bw / bw_added)
|
||||
snr = -lin2db(db2lin(-snr) + db2lin(-snr_added))
|
||||
return snr
|
||||
|
||||
|
||||
def per_label_average(values, labels):
|
||||
"""computes the average per defined spectrum band, using labels
|
||||
|
||||
>>> labels = ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'C', 'D', 'D', 'D', 'D']
|
||||
>>> values = [28.51, 28.23, 28.15, 28.17, 28.36, 28.53, 28.64, 28.68, 28.7, 28.71, 28.72, 28.73, 28.74, 28.91, 27.96, 27.85, 27.87, 28.02]
|
||||
>>> per_label_average(values, labels)
|
||||
{'A': 28.28, 'B': 28.68, 'C': 28.91, 'D': 27.92}
|
||||
"""
|
||||
|
||||
label_set = sorted(set(labels))
|
||||
summary = {}
|
||||
for label in label_set:
|
||||
vals = [val for val, lab in zip(values, labels) if lab == label]
|
||||
summary[label] = round(mean(vals), 2)
|
||||
return summary
|
||||
|
||||
|
||||
def pretty_summary_print(summary):
|
||||
"""Build a prettty string that shows the summary dict values per label with 2 digits"""
|
||||
if len(summary) == 1:
|
||||
return f'{list(summary.values())[0]:.2f}'
|
||||
text = ', '.join([f'{label}: {value:.2f}' for label, value in summary.items()])
|
||||
return text
|
||||
|
||||
|
||||
def deltawl2deltaf(delta_wl, wavelength):
|
||||
""" deltawl2deltaf(delta_wl, wavelength):
|
||||
"""deltawl2deltaf(delta_wl, wavelength):
|
||||
delta_wl is BW in wavelength units
|
||||
wavelength is the center wl
|
||||
units for delta_wl and wavelength must be same
|
||||
@@ -156,9 +263,9 @@ def deltawl2deltaf(delta_wl, wavelength):
|
||||
|
||||
|
||||
def deltaf2deltawl(delta_f, frequency):
|
||||
""" deltawl2deltaf(delta_f, frequency):
|
||||
converts delta frequency to delta wavelength
|
||||
units for delta_wl and wavelength must be same
|
||||
"""convert delta frequency to delta wavelength
|
||||
|
||||
Units for delta_wl and wavelength must be same.
|
||||
|
||||
:param delta_f: delta frequency in same units as frequency
|
||||
:param frequency: frequency BW is relevant for
|
||||
@@ -173,8 +280,7 @@ def deltaf2deltawl(delta_f, frequency):
|
||||
|
||||
|
||||
def rrc(ffs, baud_rate, alpha):
|
||||
""" rrc(ffs, baud_rate, alpha): computes the root-raised cosine filter
|
||||
function.
|
||||
"""compute the root-raised cosine filter function
|
||||
|
||||
:param ffs: A numpy array of frequencies
|
||||
:param baud_rate: The Baud Rate of the System
|
||||
@@ -200,7 +306,7 @@ def rrc(ffs, baud_rate, alpha):
|
||||
|
||||
|
||||
def merge_amplifier_restrictions(dict1, dict2):
|
||||
"""Updates contents of dicts recursively
|
||||
"""Update contents of dicts recursively
|
||||
|
||||
>>> d1 = {'params': {'restrictions': {'preamp_variety_list': [], 'booster_variety_list': []}}}
|
||||
>>> d2 = {'params': {'target_pch_out_db': -20}}
|
||||
@@ -295,3 +401,60 @@ def convert_length(value, units):
|
||||
return value * 1e3
|
||||
else:
|
||||
raise ConfigurationError(f'Cannot convert length in "{units}" into meters')
|
||||
|
||||
|
||||
def replace_none(dictionary):
|
||||
""" Replaces None with inf values in a frequency slots dict
|
||||
|
||||
>>> replace_none({'N': 3, 'M': None})
|
||||
{'N': 3, 'M': inf}
|
||||
|
||||
"""
|
||||
for key, val in dictionary.items():
|
||||
if val is None:
|
||||
dictionary[key] = float('inf')
|
||||
if val == float('inf'):
|
||||
dictionary[key] = None
|
||||
return dictionary
|
||||
|
||||
|
||||
def order_slots(slots):
|
||||
""" Order frequency slots from larger slots to smaller ones up to None
|
||||
|
||||
>>> l = [{'N': 3, 'M': None}, {'N': 2, 'M': 1}, {'N': None, 'M': None},{'N': 7, 'M': 2},{'N': None, 'M': 1} , {'N': None, 'M': 0}]
|
||||
>>> order_slots(l)
|
||||
([7, 2, None, None, 3, None], [2, 1, 1, 0, None, None], [3, 1, 4, 5, 0, 2])
|
||||
"""
|
||||
slots_list = deepcopy(slots)
|
||||
slots_list = [replace_none(e) for e in slots_list]
|
||||
for i, e in enumerate(slots_list):
|
||||
e['i'] = i
|
||||
slots_list = sorted(slots_list, key=lambda x: (-x['M'], x['N']) if x['M'] != float('inf') else (x['M'], x['N']))
|
||||
slots_list = [replace_none(e) for e in slots_list]
|
||||
return [e['N'] for e in slots_list], [e['M'] for e in slots_list], [e['i'] for e in slots_list]
|
||||
|
||||
|
||||
def restore_order(elements, order):
|
||||
""" Use order to re-order the element of the list, and ignore None values
|
||||
|
||||
>>> restore_order([7, 2, None, None, 3, None], [3, 1, 4, 5, 0, 2])
|
||||
[3, 2, 7]
|
||||
"""
|
||||
return [elements[i[0]] for i in sorted(enumerate(order), key=lambda x:x[1]) if elements[i[0]] is not None]
|
||||
|
||||
|
||||
def calculate_absolute_min_or_zero(x: array) -> array:
|
||||
"""Calculates the element-wise absolute minimum between the x and zero.
|
||||
|
||||
Parameters:
|
||||
x (array): The first input array.
|
||||
|
||||
Returns:
|
||||
array: The element-wise absolute minimum between x and zero.
|
||||
|
||||
Example:
|
||||
>>> x = array([-1, 2, -3])
|
||||
>>> calculate_absolute_min_or_zero(x)
|
||||
array([1., 0., 3.])
|
||||
"""
|
||||
return (abs(x) - x) / 2
|
||||
|
||||
@@ -1,160 +1,160 @@
|
||||
{
|
||||
"nf_fit_coeff": [
|
||||
0.0008,
|
||||
0.0272,
|
||||
-0.2249,
|
||||
6.4902
|
||||
],
|
||||
"f_min": 191.4e12,
|
||||
"f_max": 196.1e12,
|
||||
"nf_ripple": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"gain_ripple": [
|
||||
-0.15656302345061,
|
||||
-0.22244242043552,
|
||||
-0.25188965661642,
|
||||
-0.23575900335007,
|
||||
-0.20897508375209,
|
||||
-0.19440221943049,
|
||||
-0.18324644053602,
|
||||
-0.18053287269681,
|
||||
-0.17113588777219,
|
||||
-0.15460322445561,
|
||||
-0.13550774706866,
|
||||
-0.10606051088777,
|
||||
-0.0765630234506,
|
||||
-0.04962835008375,
|
||||
-0.01319618927973,
|
||||
0.01027114740367,
|
||||
0.03378873534338,
|
||||
0.04961788107202,
|
||||
0.04494451423784,
|
||||
0.0399193886097,
|
||||
0.01584903685091,
|
||||
-0.00420121440538,
|
||||
-0.01847257118928,
|
||||
-0.02475397822447,
|
||||
-0.01053287269681,
|
||||
0.01509526800668,
|
||||
0.05921587102177,
|
||||
0.1191656197655,
|
||||
0.18147717755444,
|
||||
0.23579878559464,
|
||||
0.26941687604691,
|
||||
0.27836159966498,
|
||||
0.26956762981574,
|
||||
0.23826109715241,
|
||||
0.18936662479061,
|
||||
0.1204721524288,
|
||||
0.0453465242881,
|
||||
-0.00877407872698,
|
||||
-0.02199015912898,
|
||||
0.00107516750419,
|
||||
0.02795958961474,
|
||||
0.02740682579566,
|
||||
-0.01028161641541,
|
||||
-0.05982935510889,
|
||||
-0.06701528475711,
|
||||
0.00223094639866,
|
||||
0.14157768006701,
|
||||
0.15017064489112
|
||||
],
|
||||
"dgt": [
|
||||
1.0,
|
||||
1.03941448941778,
|
||||
1.07773189112355,
|
||||
1.11575888725852,
|
||||
1.15209185089701,
|
||||
1.18632744096844,
|
||||
1.21911100318577,
|
||||
1.24931318255134,
|
||||
1.27657903892303,
|
||||
1.30069883494415,
|
||||
1.32210817897091,
|
||||
1.3405812000038,
|
||||
1.35690844654118,
|
||||
1.3710092503689,
|
||||
1.38430337205545,
|
||||
1.3966294751726,
|
||||
1.40864903907609,
|
||||
1.42089447397912,
|
||||
1.43476940680732,
|
||||
1.44977369463316,
|
||||
1.46637521309853,
|
||||
1.48420288841848,
|
||||
1.50335352244996,
|
||||
1.5242627235492,
|
||||
1.54578500307573,
|
||||
1.56750088631614,
|
||||
1.58973304612691,
|
||||
1.61073904908309,
|
||||
1.63068023161292,
|
||||
1.64799163036252,
|
||||
1.66286684904577,
|
||||
1.6761448370895,
|
||||
1.68845480656382,
|
||||
1.70379790088896,
|
||||
1.72461030013125,
|
||||
1.75428006928365,
|
||||
1.79748596476494,
|
||||
1.85543800978691,
|
||||
1.92915262384742,
|
||||
2.01414465424155,
|
||||
2.10336369905543,
|
||||
2.19013043016015,
|
||||
2.26678136721453,
|
||||
2.33147727493671,
|
||||
2.38192717604575,
|
||||
2.41879254989742,
|
||||
2.44342862248888,
|
||||
2.4553191172498
|
||||
]
|
||||
"nf_fit_coeff": [
|
||||
0.0008,
|
||||
0.0272,
|
||||
-0.2249,
|
||||
6.4902
|
||||
],
|
||||
"f_min": 191.4e12,
|
||||
"f_max": 196.1e12,
|
||||
"nf_ripple": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"gain_ripple": [
|
||||
-0.15656302345061,
|
||||
-0.22244242043552,
|
||||
-0.25188965661642,
|
||||
-0.23575900335007,
|
||||
-0.20897508375209,
|
||||
-0.19440221943049,
|
||||
-0.18324644053602,
|
||||
-0.18053287269681,
|
||||
-0.17113588777219,
|
||||
-0.15460322445561,
|
||||
-0.13550774706866,
|
||||
-0.10606051088777,
|
||||
-0.0765630234506,
|
||||
-0.04962835008375,
|
||||
-0.01319618927973,
|
||||
0.01027114740367,
|
||||
0.03378873534338,
|
||||
0.04961788107202,
|
||||
0.04494451423784,
|
||||
0.0399193886097,
|
||||
0.01584903685091,
|
||||
-0.00420121440538,
|
||||
-0.01847257118928,
|
||||
-0.02475397822447,
|
||||
-0.01053287269681,
|
||||
0.01509526800668,
|
||||
0.05921587102177,
|
||||
0.1191656197655,
|
||||
0.18147717755444,
|
||||
0.23579878559464,
|
||||
0.26941687604691,
|
||||
0.27836159966498,
|
||||
0.26956762981574,
|
||||
0.23826109715241,
|
||||
0.18936662479061,
|
||||
0.1204721524288,
|
||||
0.0453465242881,
|
||||
-0.00877407872698,
|
||||
-0.02199015912898,
|
||||
0.00107516750419,
|
||||
0.02795958961474,
|
||||
0.02740682579566,
|
||||
-0.01028161641541,
|
||||
-0.05982935510889,
|
||||
-0.06701528475711,
|
||||
0.00223094639866,
|
||||
0.14157768006701,
|
||||
0.15017064489112
|
||||
],
|
||||
"dgt": [
|
||||
1.0,
|
||||
1.03941448941778,
|
||||
1.07773189112355,
|
||||
1.11575888725852,
|
||||
1.15209185089701,
|
||||
1.18632744096844,
|
||||
1.21911100318577,
|
||||
1.24931318255134,
|
||||
1.27657903892303,
|
||||
1.30069883494415,
|
||||
1.32210817897091,
|
||||
1.3405812000038,
|
||||
1.35690844654118,
|
||||
1.3710092503689,
|
||||
1.38430337205545,
|
||||
1.3966294751726,
|
||||
1.40864903907609,
|
||||
1.42089447397912,
|
||||
1.43476940680732,
|
||||
1.44977369463316,
|
||||
1.46637521309853,
|
||||
1.48420288841848,
|
||||
1.50335352244996,
|
||||
1.5242627235492,
|
||||
1.54578500307573,
|
||||
1.56750088631614,
|
||||
1.58973304612691,
|
||||
1.61073904908309,
|
||||
1.63068023161292,
|
||||
1.64799163036252,
|
||||
1.66286684904577,
|
||||
1.6761448370895,
|
||||
1.68845480656382,
|
||||
1.70379790088896,
|
||||
1.72461030013125,
|
||||
1.75428006928365,
|
||||
1.79748596476494,
|
||||
1.85543800978691,
|
||||
1.92915262384742,
|
||||
2.01414465424155,
|
||||
2.10336369905543,
|
||||
2.19013043016015,
|
||||
2.26678136721453,
|
||||
2.33147727493671,
|
||||
2.38192717604575,
|
||||
2.41879254989742,
|
||||
2.44342862248888,
|
||||
2.4553191172498
|
||||
]
|
||||
}
|
||||
|
||||
6233
gnpy/example-data/Sweden_OpenROADMv5_example_network.json
Normal file
6233
gnpy/example-data/Sweden_OpenROADMv5_example_network.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,106 +1,108 @@
|
||||
{
|
||||
"nf_ripple": [
|
||||
0.0
|
||||
],
|
||||
"gain_ripple": [
|
||||
0.0
|
||||
],
|
||||
"dgt": [
|
||||
1.0,
|
||||
1.017807767853702,
|
||||
1.0356155337864215,
|
||||
1.0534217504465226,
|
||||
1.0712204022764056,
|
||||
1.0895983485572227,
|
||||
1.108555289615659,
|
||||
1.1280891949729075,
|
||||
1.1476135933863398,
|
||||
1.1672278304018044,
|
||||
1.1869318618366975,
|
||||
1.2067249615595257,
|
||||
1.2264996957264114,
|
||||
1.2428104897182262,
|
||||
1.2556591482982988,
|
||||
1.2650555289898042,
|
||||
1.2744470198196236,
|
||||
1.2838336236692311,
|
||||
1.2932153453410835,
|
||||
1.3040618749785347,
|
||||
1.316383926863083,
|
||||
1.3301807335621048,
|
||||
1.3439818461440451,
|
||||
1.3598972673004606,
|
||||
1.3779439775587023,
|
||||
1.3981208704326855,
|
||||
1.418273806730323,
|
||||
1.4340878115214444,
|
||||
1.445565137158368,
|
||||
1.45273959485914,
|
||||
1.4599103316162523,
|
||||
1.4670307626366115,
|
||||
1.474100442252211,
|
||||
1.48111939735681,
|
||||
1.488134243479226,
|
||||
1.495145456062699,
|
||||
1.502153039909686,
|
||||
1.5097346239790443,
|
||||
1.5178910621476225,
|
||||
1.5266220576235803,
|
||||
1.5353620432989845,
|
||||
1.545374152761467,
|
||||
1.5566577309558969,
|
||||
1.569199764184379,
|
||||
1.5817353179379183,
|
||||
1.5986915141218316,
|
||||
1.6201194134191075,
|
||||
1.6460167077689267,
|
||||
1.6719047669939942,
|
||||
1.6918150918099673,
|
||||
1.7057507692361864,
|
||||
1.7137640932265894,
|
||||
1.7217732861435076,
|
||||
1.7297783508684146,
|
||||
1.737780757913635,
|
||||
1.7459181197626403,
|
||||
1.7541903672600494,
|
||||
1.7625959636196327,
|
||||
1.7709972329654864,
|
||||
1.7793941781790852,
|
||||
1.7877868031023945,
|
||||
1.7961751115773796,
|
||||
1.8045606557581335,
|
||||
1.8139629377087627,
|
||||
1.824381436842932,
|
||||
1.835814081380705,
|
||||
1.847275503201129,
|
||||
1.862235672444246,
|
||||
1.8806927939516411,
|
||||
1.9026104247588487,
|
||||
1.9245345552113182,
|
||||
1.9482128147680253,
|
||||
1.9736443063300082,
|
||||
2.0008103857988204,
|
||||
2.0279625371819305,
|
||||
2.055100772005235,
|
||||
2.082225099873648,
|
||||
2.1183028432496016,
|
||||
2.16337565384239,
|
||||
2.2174389328192197,
|
||||
2.271520771371253,
|
||||
2.322373696229342,
|
||||
2.3699990328716107,
|
||||
2.414398437185221,
|
||||
2.4587748041127506,
|
||||
2.499446286796604,
|
||||
2.5364027376452056,
|
||||
2.5696460593920065,
|
||||
2.602860350286428,
|
||||
2.630396440815385,
|
||||
2.6521732021128046,
|
||||
2.6681935771243177,
|
||||
2.6841217449620203,
|
||||
2.6947834587664494,
|
||||
2.705443819238505,
|
||||
2.714526681131686
|
||||
]
|
||||
"nf_ripple": [
|
||||
0.0
|
||||
],
|
||||
"gain_ripple": [
|
||||
0.0
|
||||
],
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 196.1e12,
|
||||
"dgt": [
|
||||
1.0,
|
||||
1.017807767853702,
|
||||
1.0356155337864215,
|
||||
1.0534217504465226,
|
||||
1.0712204022764056,
|
||||
1.0895983485572227,
|
||||
1.108555289615659,
|
||||
1.1280891949729075,
|
||||
1.1476135933863398,
|
||||
1.1672278304018044,
|
||||
1.1869318618366975,
|
||||
1.2067249615595257,
|
||||
1.2264996957264114,
|
||||
1.2428104897182262,
|
||||
1.2556591482982988,
|
||||
1.2650555289898042,
|
||||
1.2744470198196236,
|
||||
1.2838336236692311,
|
||||
1.2932153453410835,
|
||||
1.3040618749785347,
|
||||
1.316383926863083,
|
||||
1.3301807335621048,
|
||||
1.3439818461440451,
|
||||
1.3598972673004606,
|
||||
1.3779439775587023,
|
||||
1.3981208704326855,
|
||||
1.418273806730323,
|
||||
1.4340878115214444,
|
||||
1.445565137158368,
|
||||
1.45273959485914,
|
||||
1.4599103316162523,
|
||||
1.4670307626366115,
|
||||
1.474100442252211,
|
||||
1.48111939735681,
|
||||
1.488134243479226,
|
||||
1.495145456062699,
|
||||
1.502153039909686,
|
||||
1.5097346239790443,
|
||||
1.5178910621476225,
|
||||
1.5266220576235803,
|
||||
1.5353620432989845,
|
||||
1.545374152761467,
|
||||
1.5566577309558969,
|
||||
1.569199764184379,
|
||||
1.5817353179379183,
|
||||
1.5986915141218316,
|
||||
1.6201194134191075,
|
||||
1.6460167077689267,
|
||||
1.6719047669939942,
|
||||
1.6918150918099673,
|
||||
1.7057507692361864,
|
||||
1.7137640932265894,
|
||||
1.7217732861435076,
|
||||
1.7297783508684146,
|
||||
1.737780757913635,
|
||||
1.7459181197626403,
|
||||
1.7541903672600494,
|
||||
1.7625959636196327,
|
||||
1.7709972329654864,
|
||||
1.7793941781790852,
|
||||
1.7877868031023945,
|
||||
1.7961751115773796,
|
||||
1.8045606557581335,
|
||||
1.8139629377087627,
|
||||
1.824381436842932,
|
||||
1.835814081380705,
|
||||
1.847275503201129,
|
||||
1.862235672444246,
|
||||
1.8806927939516411,
|
||||
1.9026104247588487,
|
||||
1.9245345552113182,
|
||||
1.9482128147680253,
|
||||
1.9736443063300082,
|
||||
2.0008103857988204,
|
||||
2.0279625371819305,
|
||||
2.055100772005235,
|
||||
2.082225099873648,
|
||||
2.1183028432496016,
|
||||
2.16337565384239,
|
||||
2.2174389328192197,
|
||||
2.271520771371253,
|
||||
2.322373696229342,
|
||||
2.3699990328716107,
|
||||
2.414398437185221,
|
||||
2.4587748041127506,
|
||||
2.499446286796604,
|
||||
2.5364027376452056,
|
||||
2.5696460593920065,
|
||||
2.602860350286428,
|
||||
2.630396440815385,
|
||||
2.6521732021128046,
|
||||
2.6681935771243177,
|
||||
2.6841217449620203,
|
||||
2.6947834587664494,
|
||||
2.705443819238505,
|
||||
2.714526681131686
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,80 +1,80 @@
|
||||
{
|
||||
"network_name": "EDFA Example Network - P2P",
|
||||
"elements": [{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.5
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": 17,
|
||||
"tilt_target": 0,
|
||||
"out_voa": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
"network_name": "EDFA Example Network - P2P",
|
||||
"elements": [
|
||||
{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
|
||||
],
|
||||
"connections": [{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.5
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": 17,
|
||||
"tilt_target": 0,
|
||||
"out_voa": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,328 +1,443 @@
|
||||
{ "Edfa":[{
|
||||
"type_variety": "high_detail_model_example",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": false
|
||||
}, {
|
||||
"type_variety": "Juniper_BoosterHG",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 10,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "Juniper-BoosterHG.json",
|
||||
"out_voa_auto": 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": "openroadm_ila_low_noise",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [-8.104e-4,-6.221e-2,-5.889e-1,37.62],
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_ila_standard",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [-5.952e-4,-6.250e-2,-1.071,28.99],
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_preamp",
|
||||
"type_def": "openroadm_preamp",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_booster",
|
||||
"type_def": "openroadm_booster",
|
||||
"gain_flatmax": 32,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "std_high_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 35,
|
||||
"gain_min": 25,
|
||||
"p_max": 21,
|
||||
"nf_min": 5.5,
|
||||
"nf_max": 7,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_medium_gain",
|
||||
"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": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_low_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 23,
|
||||
"nf_min": 6.5,
|
||||
"nf_max": 11,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "high_power",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 25,
|
||||
"nf_min": 9,
|
||||
"nf_max": 15,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "std_fixed_gain",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5.5,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "4pumps_raman",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 12,
|
||||
"gain_min": 12,
|
||||
"p_max": 21,
|
||||
"nf0": -1,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "hybrid_4pumps_lowgain",
|
||||
"type_def": "dual_stage",
|
||||
"raman": true,
|
||||
"gain_min": 25,
|
||||
"preamp_variety": "4pumps_raman",
|
||||
"booster_variety": "std_low_gain",
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "hybrid_4pumps_mediumgain",
|
||||
"type_def": "dual_stage",
|
||||
"raman": true,
|
||||
"gain_min": 25,
|
||||
"preamp_variety": "4pumps_raman",
|
||||
"booster_variety": "std_medium_gain",
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "medium+low_gain",
|
||||
"type_def": "dual_stage",
|
||||
"gain_min": 25,
|
||||
"preamp_variety": "std_medium_gain",
|
||||
"booster_variety": "std_low_gain",
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "medium+high_power",
|
||||
"type_def": "dual_stage",
|
||||
"gain_min": 25,
|
||||
"preamp_variety": "std_medium_gain",
|
||||
"booster_variety": "high_power",
|
||||
"allowed_for_design": false
|
||||
}
|
||||
{
|
||||
"Edfa": [
|
||||
{
|
||||
"type_variety": "high_detail_model_example",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "Juniper_BoosterHG",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 10,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "Juniper-BoosterHG.json",
|
||||
"out_voa_auto": 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": "openroadm_ila_low_noise",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-8.104e-4,
|
||||
-6.221e-2,
|
||||
-5.889e-1,
|
||||
37.62
|
||||
],
|
||||
"Fiber":[{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"gamma": 0.00127,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "NZDF",
|
||||
"dispersion": 0.5e-05,
|
||||
"gamma": 0.00146,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "LOF",
|
||||
"dispersion": 2.2e-05,
|
||||
"gamma": 0.000843,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_ila_standard",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-5.952e-4,
|
||||
-6.250e-2,
|
||||
-1.071,
|
||||
28.99
|
||||
],
|
||||
"RamanFiber":[{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"gamma": 0.00127,
|
||||
"pmd_coef": 1.265e-15,
|
||||
"raman_efficiency": {
|
||||
"cr":[
|
||||
0, 9.4E-06, 2.92E-05, 4.88E-05, 6.82E-05, 8.31E-05, 9.4E-05, 0.0001014, 0.0001069, 0.0001119,
|
||||
0.0001217, 0.0001268, 0.0001365, 0.000149, 0.000165, 0.000181, 0.0001977, 0.0002192, 0.0002469,
|
||||
0.0002749, 0.0002999, 0.0003206, 0.0003405, 0.0003592, 0.000374, 0.0003826, 0.0003841, 0.0003826,
|
||||
0.0003802, 0.0003756, 0.0003549, 0.0003795, 0.000344, 0.0002933, 0.0002024, 0.0001158, 8.46E-05,
|
||||
7.14E-05, 6.86E-05, 8.5E-05, 8.93E-05, 9.01E-05, 8.15E-05, 6.67E-05, 4.37E-05, 3.28E-05, 2.96E-05,
|
||||
2.65E-05, 2.57E-05, 2.81E-05, 3.08E-05, 3.67E-05, 5.85E-05, 6.63E-05, 6.36E-05, 5.5E-05, 4.06E-05,
|
||||
2.77E-05, 2.42E-05, 1.87E-05, 1.6E-05, 1.4E-05, 1.13E-05, 1.05E-05, 9.8E-06, 9.8E-06, 1.13E-05,
|
||||
1.64E-05, 1.95E-05, 2.38E-05, 2.26E-05, 2.03E-05, 1.48E-05, 1.09E-05, 9.8E-06, 1.05E-05, 1.17E-05,
|
||||
1.25E-05, 1.21E-05, 1.09E-05, 9.8E-06, 8.2E-06, 6.6E-06, 4.7E-06, 2.7E-06, 1.9E-06, 1.2E-06, 4E-07,
|
||||
2E-07, 1E-07
|
||||
],
|
||||
"frequency_offset":[
|
||||
0, 0.5e12, 1e12, 1.5e12, 2e12, 2.5e12, 3e12, 3.5e12, 4e12, 4.5e12, 5e12, 5.5e12, 6e12, 6.5e12, 7e12,
|
||||
7.5e12, 8e12, 8.5e12, 9e12, 9.5e12, 10e12, 10.5e12, 11e12, 11.5e12, 12e12, 12.5e12, 12.75e12,
|
||||
13e12, 13.25e12, 13.5e12, 14e12, 14.5e12, 14.75e12, 15e12, 15.5e12, 16e12, 16.5e12, 17e12,
|
||||
17.5e12, 18e12, 18.25e12, 18.5e12, 18.75e12, 19e12, 19.5e12, 20e12, 20.5e12, 21e12, 21.5e12,
|
||||
22e12, 22.5e12, 23e12, 23.5e12, 24e12, 24.5e12, 25e12, 25.5e12, 26e12, 26.5e12, 27e12, 27.5e12, 28e12,
|
||||
28.5e12, 29e12, 29.5e12, 30e12, 30.5e12, 31e12, 31.5e12, 32e12, 32.5e12, 33e12, 33.5e12, 34e12, 34.5e12,
|
||||
35e12, 35.5e12, 36e12, 36.5e12, 37e12, 37.5e12, 38e12, 38.5e12, 39e12, 39.5e12, 40e12, 40.5e12, 41e12,
|
||||
41.5e12, 42e12
|
||||
]
|
||||
}
|
||||
}
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_preamp",
|
||||
"type_def": "openroadm_preamp",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_preamp_typical_ver5",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-5.952e-4,
|
||||
-6.250e-2,
|
||||
-1.071,
|
||||
28.99
|
||||
],
|
||||
"Span":[{
|
||||
"power_mode":true,
|
||||
"delta_power_range_db": [-2,3,0.5],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_preamp_worstcase_ver5",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-5.952e-4,
|
||||
-6.250e-2,
|
||||
-1.071,
|
||||
27.99
|
||||
],
|
||||
"Roadm":[{
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list":[],
|
||||
"booster_variety_list":[]
|
||||
}
|
||||
}],
|
||||
"SI":[{
|
||||
"f_min": 191.3e12,
|
||||
"baud_rate": 32e9,
|
||||
"f_max":195.1e12,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"power_range_db": [0,0,1],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"sys_margins": 2
|
||||
}],
|
||||
"Transceiver":[
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_booster",
|
||||
"type_def": "openroadm_booster",
|
||||
"gain_flatmax": 32,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "std_high_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 35,
|
||||
"gain_min": 25,
|
||||
"p_max": 21,
|
||||
"nf_min": 5.5,
|
||||
"nf_max": 7,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_medium_gain",
|
||||
"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": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_low_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 23,
|
||||
"nf_min": 6.5,
|
||||
"nf_max": 11,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "high_power",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 25,
|
||||
"nf_min": 9,
|
||||
"nf_max": 15,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "std_fixed_gain",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5.5,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "4pumps_raman",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 12,
|
||||
"gain_min": 12,
|
||||
"p_max": 21,
|
||||
"nf0": -1,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "hybrid_4pumps_lowgain",
|
||||
"type_def": "dual_stage",
|
||||
"raman": true,
|
||||
"gain_min": 25,
|
||||
"preamp_variety": "4pumps_raman",
|
||||
"booster_variety": "std_low_gain",
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "hybrid_4pumps_mediumgain",
|
||||
"type_def": "dual_stage",
|
||||
"raman": true,
|
||||
"gain_min": 25,
|
||||
"preamp_variety": "4pumps_raman",
|
||||
"booster_variety": "std_medium_gain",
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "medium+low_gain",
|
||||
"type_def": "dual_stage",
|
||||
"gain_min": 25,
|
||||
"preamp_variety": "std_medium_gain",
|
||||
"booster_variety": "std_low_gain",
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "medium+high_power",
|
||||
"type_def": "dual_stage",
|
||||
"gain_min": 25,
|
||||
"preamp_variety": "std_medium_gain",
|
||||
"booster_variety": "high_power",
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber": [
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "NZDF",
|
||||
"dispersion": 0.5e-05,
|
||||
"effective_area": 72e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "LOF",
|
||||
"dispersion": 2.2e-05,
|
||||
"effective_area": 125e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"RamanFiber": [
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"Span": [
|
||||
{
|
||||
"power_mode": true,
|
||||
"delta_power_range_db": [
|
||||
-2,
|
||||
3,
|
||||
0.5
|
||||
],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm": [
|
||||
{
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type_variety": "roadm_type_1",
|
||||
"target_pch_out_db": -18,
|
||||
"add_drop_osnr": 35,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": []
|
||||
},
|
||||
{
|
||||
"type_variety": "detailed_impairments",
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": [
|
||||
{
|
||||
"roadm-path-impairments-id": 0,
|
||||
"roadm-express-path": [
|
||||
{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency":{
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode":[
|
||||
{
|
||||
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 37.5e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 75e9,
|
||||
"cost":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "Voyager",
|
||||
"frequency":{
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode":[
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 37.5e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 3",
|
||||
"baud_rate": 44e9,
|
||||
"OSNR": 18,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 62.5e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 75e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 4",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 16,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 75e9,
|
||||
"cost":1
|
||||
}
|
||||
]
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 16.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"roadm-path-impairments-id": 1,
|
||||
"roadm-add-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 11.5,
|
||||
"roadm-pmax": 2.5,
|
||||
"roadm-osnr": 41,
|
||||
"roadm-noise-figure": 23
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"roadm-path-impairments-id": 2,
|
||||
"roadm-drop-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 11.5,
|
||||
"roadm-minloss": 7.5,
|
||||
"roadm-typloss": 10,
|
||||
"roadm-pmin": -13.5,
|
||||
"roadm-pmax": -9.5,
|
||||
"roadm-ptyp": -12,
|
||||
"roadm-osnr": 41,
|
||||
"roadm-noise-figure": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
],
|
||||
"SI": [
|
||||
{
|
||||
"f_min": 191.3e12,
|
||||
"baud_rate": 32e9,
|
||||
"f_max": 195.1e12,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"power_range_db": [
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"tx_power_dbm": 0,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"sys_margins": 2
|
||||
}
|
||||
],
|
||||
"Transceiver": [
|
||||
{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 37.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "Voyager",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 37.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 3",
|
||||
"baud_rate": 44e9,
|
||||
"OSNR": 18,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 62.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 4",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 16,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
{ "Edfa":[
|
||||
{
|
||||
"type_variety": "openroadm_ila_low_noise",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [-8.104e-4,-6.221e-2,-5.889e-1,37.62],
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_ila_standard",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [-5.952e-4,-6.250e-2,-1.071,28.99],
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_preamp",
|
||||
"type_def": "openroadm_preamp",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_booster",
|
||||
"type_def": "openroadm_booster",
|
||||
"gain_flatmax": 32,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber":[
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"gamma": 0.00127,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "NZDF",
|
||||
"dispersion": 0.5e-05,
|
||||
"gamma": 0.00146,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "LOF",
|
||||
"dispersion": 2.2e-05,
|
||||
"gamma": 0.000843,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"RamanFiber":[
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"gamma": 0.00127,
|
||||
"pmd_coef": 1.265e-15,
|
||||
"raman_efficiency": {
|
||||
"cr":[
|
||||
0, 9.4E-06, 2.92E-05, 4.88E-05, 6.82E-05, 8.31E-05, 9.4E-05, 0.0001014, 0.0001069, 0.0001119,
|
||||
0.0001217, 0.0001268, 0.0001365, 0.000149, 0.000165, 0.000181, 0.0001977, 0.0002192, 0.0002469,
|
||||
0.0002749, 0.0002999, 0.0003206, 0.0003405, 0.0003592, 0.000374, 0.0003826, 0.0003841, 0.0003826,
|
||||
0.0003802, 0.0003756, 0.0003549, 0.0003795, 0.000344, 0.0002933, 0.0002024, 0.0001158, 8.46E-05,
|
||||
7.14E-05, 6.86E-05, 8.5E-05, 8.93E-05, 9.01E-05, 8.15E-05, 6.67E-05, 4.37E-05, 3.28E-05, 2.96E-05,
|
||||
2.65E-05, 2.57E-05, 2.81E-05, 3.08E-05, 3.67E-05, 5.85E-05, 6.63E-05, 6.36E-05, 5.5E-05, 4.06E-05,
|
||||
2.77E-05, 2.42E-05, 1.87E-05, 1.6E-05, 1.4E-05, 1.13E-05, 1.05E-05, 9.8E-06, 9.8E-06, 1.13E-05,
|
||||
1.64E-05, 1.95E-05, 2.38E-05, 2.26E-05, 2.03E-05, 1.48E-05, 1.09E-05, 9.8E-06, 1.05E-05, 1.17E-05,
|
||||
1.25E-05, 1.21E-05, 1.09E-05, 9.8E-06, 8.2E-06, 6.6E-06, 4.7E-06, 2.7E-06, 1.9E-06, 1.2E-06, 4E-07,
|
||||
2E-07, 1E-07
|
||||
],
|
||||
"frequency_offset":[
|
||||
0, 0.5e12, 1e12, 1.5e12, 2e12, 2.5e12, 3e12, 3.5e12, 4e12, 4.5e12, 5e12, 5.5e12, 6e12, 6.5e12, 7e12,
|
||||
7.5e12, 8e12, 8.5e12, 9e12, 9.5e12, 10e12, 10.5e12, 11e12, 11.5e12, 12e12, 12.5e12, 12.75e12,
|
||||
13e12, 13.25e12, 13.5e12, 14e12, 14.5e12, 14.75e12, 15e12, 15.5e12, 16e12, 16.5e12, 17e12,
|
||||
17.5e12, 18e12, 18.25e12, 18.5e12, 18.75e12, 19e12, 19.5e12, 20e12, 20.5e12, 21e12, 21.5e12,
|
||||
22e12, 22.5e12, 23e12, 23.5e12, 24e12, 24.5e12, 25e12, 25.5e12, 26e12, 26.5e12, 27e12, 27.5e12, 28e12,
|
||||
28.5e12, 29e12, 29.5e12, 30e12, 30.5e12, 31e12, 31.5e12, 32e12, 32.5e12, 33e12, 33.5e12, 34e12, 34.5e12,
|
||||
35e12, 35.5e12, 36e12, 36.5e12, 37e12, 37.5e12, 38e12, 38.5e12, 39e12, 39.5e12, 40e12, 40.5e12, 41e12,
|
||||
41.5e12, 42e12
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"Span":[
|
||||
{
|
||||
"power_mode":true,
|
||||
"delta_power_range_db": [0,0,0],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 0,
|
||||
"max_length": 135,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 11,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm":[
|
||||
{
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 30,
|
||||
"pmd": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list":["openroadm_mw_mw_preamp"],
|
||||
"booster_variety_list":["openroadm_mw_mw_booster"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"SI":[
|
||||
{
|
||||
"f_min": 191.3e12,
|
||||
"baud_rate": 31.57e9,
|
||||
"f_max":196.1e12,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 2,
|
||||
"power_range_db": [0,0,1],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 35,
|
||||
"sys_margins": 2
|
||||
}
|
||||
],
|
||||
"Transceiver":[
|
||||
{
|
||||
"type_variety": "OpenROADM MSA ver. 4.0",
|
||||
"frequency":{
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode":[
|
||||
{
|
||||
"format": "100 Gbit/s, 27.95 Gbaud, DP-QPSK",
|
||||
"baud_rate": 27.95e9,
|
||||
"OSNR": 17,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": null,
|
||||
"tx_osnr": 33,
|
||||
"min_spacing": 50e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "100 Gbit/s, 31.57 Gbaud, DP-QPSK",
|
||||
"baud_rate": 31.57e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 35,
|
||||
"min_spacing": 50e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "200 Gbit/s, DP-QPSK",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 17,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"min_spacing": 87.5e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "300 Gbit/s, DP-8QAM",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"min_spacing": 87.5e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "400 Gbit/s, DP-16QAM",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 24,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"min_spacing": 87.5e9,
|
||||
"cost":1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
371
gnpy/example-data/eqpt_config_openroadm_ver4.json
Normal file
371
gnpy/example-data/eqpt_config_openroadm_ver4.json
Normal file
@@ -0,0 +1,371 @@
|
||||
{
|
||||
"Edfa": [
|
||||
{
|
||||
"type_variety": "openroadm_ila_low_noise",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-8.104e-4,
|
||||
-6.221e-2,
|
||||
-5.889e-1,
|
||||
37.62
|
||||
],
|
||||
"pmd": 3e-12,
|
||||
"pdl": 0.7,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_ila_standard",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-5.952e-4,
|
||||
-6.250e-2,
|
||||
-1.071,
|
||||
28.99
|
||||
],
|
||||
"pmd": 3e-12,
|
||||
"pdl": 0.7,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_preamp",
|
||||
"type_def": "openroadm_preamp",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_booster",
|
||||
"type_def": "openroadm_booster",
|
||||
"gain_flatmax": 32,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber": [
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "NZDF",
|
||||
"dispersion": 0.5e-05,
|
||||
"effective_area": 72e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "LOF",
|
||||
"dispersion": 2.2e-05,
|
||||
"effective_area": 125e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"RamanFiber": [
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"Span": [
|
||||
{
|
||||
"power_mode": true,
|
||||
"delta_power_range_db": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 0,
|
||||
"max_length": 135,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 11,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm": [
|
||||
{
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 30,
|
||||
"pmd": 3e-12,
|
||||
"pdl": 1.5,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [
|
||||
"openroadm_mw_mw_preamp"
|
||||
],
|
||||
"booster_variety_list": [
|
||||
"openroadm_mw_mw_booster"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"SI": [
|
||||
{
|
||||
"f_min": 191.3e12,
|
||||
"baud_rate": 31.57e9,
|
||||
"f_max": 196.1e12,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 2,
|
||||
"power_range_db": [
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 35,
|
||||
"sys_margins": 2
|
||||
}
|
||||
],
|
||||
"Transceiver": [
|
||||
{
|
||||
"type_variety": "OpenROADM MSA ver. 4.0",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "100 Gbit/s, 27.95 Gbaud, DP-QPSK",
|
||||
"baud_rate": 27.95e9,
|
||||
"OSNR": 17,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": null,
|
||||
"tx_osnr": 33,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 18e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 30,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
},
|
||||
{
|
||||
"pdl": 6,
|
||||
"penalty_value": 4
|
||||
}
|
||||
],
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "100 Gbit/s, 31.57 Gbaud, DP-QPSK",
|
||||
"baud_rate": 31.57e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 35,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 40e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 30,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
},
|
||||
{
|
||||
"pdl": 6,
|
||||
"penalty_value": 4
|
||||
}
|
||||
],
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "200 Gbit/s, DP-QPSK",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 17,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 24e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 25,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
}
|
||||
],
|
||||
"min_spacing": 87.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "300 Gbit/s, DP-8QAM",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 18e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 25,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
}
|
||||
],
|
||||
"min_spacing": 87.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "400 Gbit/s, DP-16QAM",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 24,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 12e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 20,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
}
|
||||
],
|
||||
"min_spacing": 87.5e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
441
gnpy/example-data/eqpt_config_openroadm_ver5.json
Normal file
441
gnpy/example-data/eqpt_config_openroadm_ver5.json
Normal file
@@ -0,0 +1,441 @@
|
||||
{
|
||||
"Edfa": [
|
||||
{
|
||||
"type_variety": "openroadm_ila_low_noise",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-8.104e-4,
|
||||
-6.221e-2,
|
||||
-5.889e-1,
|
||||
37.62
|
||||
],
|
||||
"pmd": 3e-12,
|
||||
"pdl": 0.7,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_ila_standard",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-5.952e-4,
|
||||
-6.250e-2,
|
||||
-1.071,
|
||||
28.99
|
||||
],
|
||||
"pmd": 3e-12,
|
||||
"pdl": 0.7,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_preamp_typical_ver5",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-5.952e-4,
|
||||
-6.250e-2,
|
||||
-1.071,
|
||||
28.99
|
||||
],
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_preamp_worstcase_ver5",
|
||||
"type_def": "openroadm",
|
||||
"gain_flatmax": 27,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"nf_coef": [
|
||||
-5.952e-4,
|
||||
-6.250e-2,
|
||||
-1.071,
|
||||
27.99
|
||||
],
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"allowed_for_design": false
|
||||
},
|
||||
{
|
||||
"type_variety": "openroadm_mw_mw_booster",
|
||||
"type_def": "openroadm_booster",
|
||||
"gain_flatmax": 32,
|
||||
"gain_min": 0,
|
||||
"p_max": 22,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber": [
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "NZDF",
|
||||
"dispersion": 0.5e-05,
|
||||
"effective_area": 72e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
{
|
||||
"type_variety": "LOF",
|
||||
"dispersion": 2.2e-05,
|
||||
"effective_area": 125e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"RamanFiber": [
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"Span": [
|
||||
{
|
||||
"power_mode": true,
|
||||
"delta_power_range_db": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 0,
|
||||
"max_length": 135,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 11,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm": [
|
||||
{
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 33,
|
||||
"pmd": 3e-12,
|
||||
"pdl": 1.5,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [
|
||||
"openroadm_mw_mw_preamp_worstcase_ver5"
|
||||
],
|
||||
"booster_variety_list": [
|
||||
"openroadm_mw_mw_booster"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"SI": [
|
||||
{
|
||||
"f_min": 191.3e12,
|
||||
"baud_rate": 31.57e9,
|
||||
"f_max": 196.1e12,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 2,
|
||||
"power_range_db": [
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 35,
|
||||
"sys_margins": 2
|
||||
}
|
||||
],
|
||||
"Transceiver": [
|
||||
{
|
||||
"type_variety": "OpenROADM MSA ver. 5.0",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "100 Gbit/s, 27.95 Gbaud, DP-QPSK",
|
||||
"baud_rate": 27.95e9,
|
||||
"OSNR": 17,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": null,
|
||||
"tx_osnr": 33,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 18e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 30,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
},
|
||||
{
|
||||
"pdl": 6,
|
||||
"penalty_value": 4
|
||||
}
|
||||
],
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "100 Gbit/s, 31.57 Gbaud, DP-QPSK",
|
||||
"baud_rate": 31.57e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 48e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 30,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
},
|
||||
{
|
||||
"pdl": 6,
|
||||
"penalty_value": 4
|
||||
}
|
||||
],
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "200 Gbit/s, 31.57 Gbaud, DP-16QAM",
|
||||
"baud_rate": 31.57e9,
|
||||
"OSNR": 20.5,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 24e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 30,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
},
|
||||
{
|
||||
"pdl": 6,
|
||||
"penalty_value": 4
|
||||
}
|
||||
],
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "200 Gbit/s, DP-QPSK",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 17,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 24e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 25,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
}
|
||||
],
|
||||
"min_spacing": 87.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "300 Gbit/s, DP-8QAM",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 18e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 25,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
}
|
||||
],
|
||||
"min_spacing": 87.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "400 Gbit/s, DP-16QAM",
|
||||
"baud_rate": 63.1e9,
|
||||
"OSNR": 24,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 36,
|
||||
"penalties": [
|
||||
{
|
||||
"chromatic_dispersion": -1e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 4e3,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"chromatic_dispersion": 12e3,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pmd": 10,
|
||||
"penalty_value": 0
|
||||
},
|
||||
{
|
||||
"pmd": 20,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 1,
|
||||
"penalty_value": 0.5
|
||||
},
|
||||
{
|
||||
"pdl": 2,
|
||||
"penalty_value": 1
|
||||
},
|
||||
{
|
||||
"pdl": 4,
|
||||
"penalty_value": 2.5
|
||||
}
|
||||
],
|
||||
"min_spacing": 87.5e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
12
gnpy/example-data/initial_spectrum1.json
Normal file
12
gnpy/example-data/initial_spectrum1.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"spectrum": [
|
||||
{
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 195.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"slot_width": 50e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
}
|
||||
]
|
||||
}
|
||||
23
gnpy/example-data/initial_spectrum2.json
Normal file
23
gnpy/example-data/initial_spectrum2.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"spectrum": [
|
||||
{
|
||||
"f_min": 191.4e12,
|
||||
"f_max": 193.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"slot_width": 50e9,
|
||||
"delta_pdb": 0,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"label": "mode_1"
|
||||
},
|
||||
{
|
||||
"f_min": 193.1625e12,
|
||||
"f_max": 195e12,
|
||||
"baud_rate": 64e9,
|
||||
"slot_width": 75e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"label": "mode_2"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -14,8 +14,8 @@
|
||||
"trx_mode": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -39,8 +39,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -104,8 +104,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -129,8 +129,8 @@
|
||||
"trx_mode": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
@@ -154,8 +154,8 @@
|
||||
"trx_mode": "mode 2",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
@@ -179,8 +179,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -204,8 +204,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -229,8 +229,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
"temperature": 283,
|
||||
"raman_pumps": [
|
||||
{
|
||||
"power": 200e-3,
|
||||
"power": 224.403e-3,
|
||||
"frequency": 205e12,
|
||||
"propagation_direction": "counterprop"
|
||||
},
|
||||
{
|
||||
"power": 206e-3,
|
||||
"power": 231.135e-3,
|
||||
"frequency": 201e12,
|
||||
"propagation_direction": "counterprop"
|
||||
}
|
||||
@@ -49,6 +49,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Fused1",
|
||||
"type": "Fused",
|
||||
"params": {
|
||||
"loss": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 1.5,
|
||||
"longitude": 0,
|
||||
"city": null,
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
@@ -88,6 +103,10 @@
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Fused1"
|
||||
},
|
||||
{
|
||||
"from_node": "Fused1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
{
|
||||
"raman_parameters": {
|
||||
"flag_raman": true,
|
||||
"space_resolution": 10e3,
|
||||
"tolerance": 1e-8
|
||||
"raman_params": {
|
||||
"flag": true,
|
||||
"result_spatial_resolution": 10e3,
|
||||
"solver_spatial_resolution": 50
|
||||
},
|
||||
"nli_parameters": {
|
||||
"nli_method_name": "ggn_spectrally_separated",
|
||||
"wdm_grid_size": 50e9,
|
||||
"dispersion_tolerance": 1,
|
||||
"phase_shift_tolerance": 0.1,
|
||||
"computed_channels": [1, 18, 37, 56, 75]
|
||||
"nli_params": {
|
||||
"method": "ggn_spectrally_separated",
|
||||
"dispersion_tolerance": 1,
|
||||
"phase_shift_tolerance": 0.1,
|
||||
"computed_channels": [
|
||||
1,
|
||||
18,
|
||||
37,
|
||||
56,
|
||||
75
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,304 +1,304 @@
|
||||
{
|
||||
"nf_fit_coeff": [
|
||||
0.000168241,
|
||||
0.0469961,
|
||||
0.0359549,
|
||||
5.82851
|
||||
],
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 196.1e12,
|
||||
"nf_ripple": [
|
||||
0.4372876328262819,
|
||||
0.4372876328262819,
|
||||
0.41270842850729195,
|
||||
0.38814205928193013,
|
||||
0.36358851509924695,
|
||||
0.3390191214858807,
|
||||
0.30474360397422756,
|
||||
0.27048596623174515,
|
||||
0.23624619427167134,
|
||||
0.202035284929368,
|
||||
0.1694483010211072,
|
||||
0.13687829834471027,
|
||||
0.1043252636301016,
|
||||
0.07184040799914815,
|
||||
0.061288823415841555,
|
||||
0.050742731588695494,
|
||||
0.04020212822983975,
|
||||
0.029667009055877668,
|
||||
0.01913736978785662,
|
||||
0.00861320615127981,
|
||||
-0.010157321677553965,
|
||||
-0.028982516728038848,
|
||||
-0.04779792991567815,
|
||||
-0.06660356886269536,
|
||||
-0.06256260169582961,
|
||||
-0.05832916277634124,
|
||||
-0.05409792133358102,
|
||||
-0.04990610405914272,
|
||||
-0.05078533294804249,
|
||||
-0.05166410580536087,
|
||||
-0.05254242298580185,
|
||||
-0.05342028484370278,
|
||||
-0.051742390657545205,
|
||||
-0.050039429413028365,
|
||||
-0.048337350303318156,
|
||||
-0.04663615264317309,
|
||||
-0.04493583574805963,
|
||||
-0.043236398934156144,
|
||||
-0.035622012697103154,
|
||||
-0.027999803010447587,
|
||||
-0.02038153550619876,
|
||||
-0.012779471908040341,
|
||||
-0.006436207679519103,
|
||||
-9.622162373026585e-05,
|
||||
0.006240488799898697,
|
||||
0.012573926129294415,
|
||||
0.021418708618354456,
|
||||
0.030289222542492025,
|
||||
0.03915515813685565,
|
||||
0.047899419704645264,
|
||||
0.04256372893215024,
|
||||
0.03723078993416436,
|
||||
0.03190060058247842,
|
||||
0.02657315875107553,
|
||||
0.021248462316134083,
|
||||
0.01605877647020772,
|
||||
0.02326948274513522,
|
||||
0.03047647598902483,
|
||||
0.037679759069084225,
|
||||
0.044883315610536455,
|
||||
0.052470799141237305,
|
||||
0.06005437964543287,
|
||||
0.0676340601339394,
|
||||
0.07521193198077789,
|
||||
0.08415906712621996,
|
||||
0.09310160456603413,
|
||||
0.1020395478432815,
|
||||
0.11079585523492333,
|
||||
0.1018180306253394,
|
||||
0.09284481475528361,
|
||||
0.0838762040768461,
|
||||
0.07482015390297145,
|
||||
0.05670549786742816,
|
||||
0.03860013139908377,
|
||||
0.020504047353947653,
|
||||
0.0024172385953583004,
|
||||
-0.015660302006048,
|
||||
-0.03372858157230583,
|
||||
-0.07037375788020579,
|
||||
-0.10709599992470213,
|
||||
-0.14379944379052215,
|
||||
-0.18048410390821285,
|
||||
-0.20911178784023846,
|
||||
-0.23772399031437283,
|
||||
-0.26632156113294336,
|
||||
-0.2949045115165272,
|
||||
-0.30206775396360075,
|
||||
-0.30915729645781326,
|
||||
-0.31624321721895354,
|
||||
-0.3233255190215882,
|
||||
-0.32037911876162584,
|
||||
-0.3172854168606314,
|
||||
-0.31419329378173544,
|
||||
-0.31110274831665313,
|
||||
-0.3110761646066259,
|
||||
-0.3110761646066259
|
||||
],
|
||||
"dgt": [
|
||||
1.0,
|
||||
1.017807767853702,
|
||||
1.0356155337864215,
|
||||
1.0534217504465226,
|
||||
1.0712204022764056,
|
||||
1.0895983485572227,
|
||||
1.108555289615659,
|
||||
1.1280891949729075,
|
||||
1.1476135933863398,
|
||||
1.1672278304018044,
|
||||
1.1869318618366975,
|
||||
1.2067249615595257,
|
||||
1.2264996957264114,
|
||||
1.2428104897182262,
|
||||
1.2556591482982988,
|
||||
1.2650555289898042,
|
||||
1.2744470198196236,
|
||||
1.2838336236692311,
|
||||
1.2932153453410835,
|
||||
1.3040618749785347,
|
||||
1.316383926863083,
|
||||
1.3301807335621048,
|
||||
1.3439818461440451,
|
||||
1.3598972673004606,
|
||||
1.3779439775587023,
|
||||
1.3981208704326855,
|
||||
1.418273806730323,
|
||||
1.4340878115214444,
|
||||
1.445565137158368,
|
||||
1.45273959485914,
|
||||
1.4599103316162523,
|
||||
1.4670307626366115,
|
||||
1.474100442252211,
|
||||
1.48111939735681,
|
||||
1.488134243479226,
|
||||
1.495145456062699,
|
||||
1.502153039909686,
|
||||
1.5097346239790443,
|
||||
1.5178910621476225,
|
||||
1.5266220576235803,
|
||||
1.5353620432989845,
|
||||
1.545374152761467,
|
||||
1.5566577309558969,
|
||||
1.569199764184379,
|
||||
1.5817353179379183,
|
||||
1.5986915141218316,
|
||||
1.6201194134191075,
|
||||
1.6460167077689267,
|
||||
1.6719047669939942,
|
||||
1.6918150918099673,
|
||||
1.7057507692361864,
|
||||
1.7137640932265894,
|
||||
1.7217732861435076,
|
||||
1.7297783508684146,
|
||||
1.737780757913635,
|
||||
1.7459181197626403,
|
||||
1.7541903672600494,
|
||||
1.7625959636196327,
|
||||
1.7709972329654864,
|
||||
1.7793941781790852,
|
||||
1.7877868031023945,
|
||||
1.7961751115773796,
|
||||
1.8045606557581335,
|
||||
1.8139629377087627,
|
||||
1.824381436842932,
|
||||
1.835814081380705,
|
||||
1.847275503201129,
|
||||
1.862235672444246,
|
||||
1.8806927939516411,
|
||||
1.9026104247588487,
|
||||
1.9245345552113182,
|
||||
1.9482128147680253,
|
||||
1.9736443063300082,
|
||||
2.0008103857988204,
|
||||
2.0279625371819305,
|
||||
2.055100772005235,
|
||||
2.082225099873648,
|
||||
2.1183028432496016,
|
||||
2.16337565384239,
|
||||
2.2174389328192197,
|
||||
2.271520771371253,
|
||||
2.322373696229342,
|
||||
2.3699990328716107,
|
||||
2.414398437185221,
|
||||
2.4587748041127506,
|
||||
2.499446286796604,
|
||||
2.5364027376452056,
|
||||
2.5696460593920065,
|
||||
2.602860350286428,
|
||||
2.630396440815385,
|
||||
2.6521732021128046,
|
||||
2.6681935771243177,
|
||||
2.6841217449620203,
|
||||
2.6947834587664494,
|
||||
2.705443819238505,
|
||||
2.714526681131686
|
||||
],
|
||||
"gain_ripple": [
|
||||
0.07704745697916238,
|
||||
0.06479749697916048,
|
||||
0.05257029697916238,
|
||||
0.040326236979161934,
|
||||
0.028098946979159933,
|
||||
0.01393231697916164,
|
||||
-0.0021726530208390216,
|
||||
-0.01819858302084043,
|
||||
-0.03218106302083967,
|
||||
-0.042428283020839785,
|
||||
-0.05095282302083959,
|
||||
-0.05947139302083926,
|
||||
-0.06968090302083851,
|
||||
-0.07844600302084004,
|
||||
-0.08407607302083875,
|
||||
-0.0865687230208394,
|
||||
-0.08906007302083907,
|
||||
-0.0913487130208388,
|
||||
-0.09343261302083761,
|
||||
-0.09717347302083823,
|
||||
-0.1027863830208382,
|
||||
-0.11089282302084058,
|
||||
-0.11963431302083904,
|
||||
-0.1279646530208396,
|
||||
-0.13525493302083902,
|
||||
-0.1409032730208395,
|
||||
-0.14591937302083835,
|
||||
-0.14823350302084037,
|
||||
-0.1484450830208388,
|
||||
-0.1455411330208385,
|
||||
-0.14160178302083892,
|
||||
-0.1353792530208402,
|
||||
-0.12789859302083784,
|
||||
-0.11916081302083725,
|
||||
-0.11041488302083735,
|
||||
-0.10103437302083762,
|
||||
-0.09101254302083817,
|
||||
-0.07868024302083754,
|
||||
-0.06468462302083822,
|
||||
-0.051112303020840244,
|
||||
-0.039618433020837784,
|
||||
-0.028748483020837767,
|
||||
-0.016475303020840215,
|
||||
-0.006936193020838033,
|
||||
-0.0015763130208377163,
|
||||
0.0007104669791608842,
|
||||
0.0040435869791615175,
|
||||
0.006965146979162284,
|
||||
0.00842583697916055,
|
||||
0.00874012697916271,
|
||||
0.00936596697916059,
|
||||
0.01030063697916006,
|
||||
0.011234826979162449,
|
||||
0.013321846979160057,
|
||||
0.01659282697915998,
|
||||
0.023488786979161347,
|
||||
0.03285456697916089,
|
||||
0.04072968697916224,
|
||||
0.04467697697916151,
|
||||
0.04551704697916037,
|
||||
0.04717897697916129,
|
||||
0.04946107697915991,
|
||||
0.05154489697916276,
|
||||
0.05447361697916264,
|
||||
0.05848224697916038,
|
||||
0.06916723697916183,
|
||||
0.08548825697916129,
|
||||
0.10802383697916085,
|
||||
0.13114358697916018,
|
||||
0.15216302697916007,
|
||||
0.17037189697916233,
|
||||
0.1767381569791624,
|
||||
0.1739275269791598,
|
||||
0.15945681697916214,
|
||||
0.14239527697916188,
|
||||
0.12276252697916235,
|
||||
0.10313984697916112,
|
||||
0.08731066697916035,
|
||||
0.07533675697916209,
|
||||
0.07114372697916238,
|
||||
0.07094413697916124,
|
||||
0.07091459697916136,
|
||||
0.0670723869791594,
|
||||
0.054956336979159914,
|
||||
0.038328296979159404,
|
||||
0.017572956979162058,
|
||||
-0.0028138630208403015,
|
||||
-0.016792253020838643,
|
||||
-0.0246928330208398,
|
||||
-0.018326963020840026,
|
||||
-0.0036199830208403228,
|
||||
0.02602813697916062,
|
||||
0.06245819697916133,
|
||||
0.09542181697916163,
|
||||
0.11822862697916037,
|
||||
0.1359703369791596
|
||||
]
|
||||
"nf_fit_coeff": [
|
||||
0.000168241,
|
||||
0.0469961,
|
||||
0.0359549,
|
||||
5.82851
|
||||
],
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 196.1e12,
|
||||
"nf_ripple": [
|
||||
0.4372876328262819,
|
||||
0.4372876328262819,
|
||||
0.41270842850729195,
|
||||
0.38814205928193013,
|
||||
0.36358851509924695,
|
||||
0.3390191214858807,
|
||||
0.30474360397422756,
|
||||
0.27048596623174515,
|
||||
0.23624619427167134,
|
||||
0.202035284929368,
|
||||
0.1694483010211072,
|
||||
0.13687829834471027,
|
||||
0.1043252636301016,
|
||||
0.07184040799914815,
|
||||
0.061288823415841555,
|
||||
0.050742731588695494,
|
||||
0.04020212822983975,
|
||||
0.029667009055877668,
|
||||
0.01913736978785662,
|
||||
0.00861320615127981,
|
||||
-0.010157321677553965,
|
||||
-0.028982516728038848,
|
||||
-0.04779792991567815,
|
||||
-0.06660356886269536,
|
||||
-0.06256260169582961,
|
||||
-0.05832916277634124,
|
||||
-0.05409792133358102,
|
||||
-0.04990610405914272,
|
||||
-0.05078533294804249,
|
||||
-0.05166410580536087,
|
||||
-0.05254242298580185,
|
||||
-0.05342028484370278,
|
||||
-0.051742390657545205,
|
||||
-0.050039429413028365,
|
||||
-0.048337350303318156,
|
||||
-0.04663615264317309,
|
||||
-0.04493583574805963,
|
||||
-0.043236398934156144,
|
||||
-0.035622012697103154,
|
||||
-0.027999803010447587,
|
||||
-0.02038153550619876,
|
||||
-0.012779471908040341,
|
||||
-0.006436207679519103,
|
||||
-9.622162373026585e-05,
|
||||
0.006240488799898697,
|
||||
0.012573926129294415,
|
||||
0.021418708618354456,
|
||||
0.030289222542492025,
|
||||
0.03915515813685565,
|
||||
0.047899419704645264,
|
||||
0.04256372893215024,
|
||||
0.03723078993416436,
|
||||
0.03190060058247842,
|
||||
0.02657315875107553,
|
||||
0.021248462316134083,
|
||||
0.01605877647020772,
|
||||
0.02326948274513522,
|
||||
0.03047647598902483,
|
||||
0.037679759069084225,
|
||||
0.044883315610536455,
|
||||
0.052470799141237305,
|
||||
0.06005437964543287,
|
||||
0.0676340601339394,
|
||||
0.07521193198077789,
|
||||
0.08415906712621996,
|
||||
0.09310160456603413,
|
||||
0.1020395478432815,
|
||||
0.11079585523492333,
|
||||
0.1018180306253394,
|
||||
0.09284481475528361,
|
||||
0.0838762040768461,
|
||||
0.07482015390297145,
|
||||
0.05670549786742816,
|
||||
0.03860013139908377,
|
||||
0.020504047353947653,
|
||||
0.0024172385953583004,
|
||||
-0.015660302006048,
|
||||
-0.03372858157230583,
|
||||
-0.07037375788020579,
|
||||
-0.10709599992470213,
|
||||
-0.14379944379052215,
|
||||
-0.18048410390821285,
|
||||
-0.20911178784023846,
|
||||
-0.23772399031437283,
|
||||
-0.26632156113294336,
|
||||
-0.2949045115165272,
|
||||
-0.30206775396360075,
|
||||
-0.30915729645781326,
|
||||
-0.31624321721895354,
|
||||
-0.3233255190215882,
|
||||
-0.32037911876162584,
|
||||
-0.3172854168606314,
|
||||
-0.31419329378173544,
|
||||
-0.31110274831665313,
|
||||
-0.3110761646066259,
|
||||
-0.3110761646066259
|
||||
],
|
||||
"dgt": [
|
||||
1.0,
|
||||
1.017807767853702,
|
||||
1.0356155337864215,
|
||||
1.0534217504465226,
|
||||
1.0712204022764056,
|
||||
1.0895983485572227,
|
||||
1.108555289615659,
|
||||
1.1280891949729075,
|
||||
1.1476135933863398,
|
||||
1.1672278304018044,
|
||||
1.1869318618366975,
|
||||
1.2067249615595257,
|
||||
1.2264996957264114,
|
||||
1.2428104897182262,
|
||||
1.2556591482982988,
|
||||
1.2650555289898042,
|
||||
1.2744470198196236,
|
||||
1.2838336236692311,
|
||||
1.2932153453410835,
|
||||
1.3040618749785347,
|
||||
1.316383926863083,
|
||||
1.3301807335621048,
|
||||
1.3439818461440451,
|
||||
1.3598972673004606,
|
||||
1.3779439775587023,
|
||||
1.3981208704326855,
|
||||
1.418273806730323,
|
||||
1.4340878115214444,
|
||||
1.445565137158368,
|
||||
1.45273959485914,
|
||||
1.4599103316162523,
|
||||
1.4670307626366115,
|
||||
1.474100442252211,
|
||||
1.48111939735681,
|
||||
1.488134243479226,
|
||||
1.495145456062699,
|
||||
1.502153039909686,
|
||||
1.5097346239790443,
|
||||
1.5178910621476225,
|
||||
1.5266220576235803,
|
||||
1.5353620432989845,
|
||||
1.545374152761467,
|
||||
1.5566577309558969,
|
||||
1.569199764184379,
|
||||
1.5817353179379183,
|
||||
1.5986915141218316,
|
||||
1.6201194134191075,
|
||||
1.6460167077689267,
|
||||
1.6719047669939942,
|
||||
1.6918150918099673,
|
||||
1.7057507692361864,
|
||||
1.7137640932265894,
|
||||
1.7217732861435076,
|
||||
1.7297783508684146,
|
||||
1.737780757913635,
|
||||
1.7459181197626403,
|
||||
1.7541903672600494,
|
||||
1.7625959636196327,
|
||||
1.7709972329654864,
|
||||
1.7793941781790852,
|
||||
1.7877868031023945,
|
||||
1.7961751115773796,
|
||||
1.8045606557581335,
|
||||
1.8139629377087627,
|
||||
1.824381436842932,
|
||||
1.835814081380705,
|
||||
1.847275503201129,
|
||||
1.862235672444246,
|
||||
1.8806927939516411,
|
||||
1.9026104247588487,
|
||||
1.9245345552113182,
|
||||
1.9482128147680253,
|
||||
1.9736443063300082,
|
||||
2.0008103857988204,
|
||||
2.0279625371819305,
|
||||
2.055100772005235,
|
||||
2.082225099873648,
|
||||
2.1183028432496016,
|
||||
2.16337565384239,
|
||||
2.2174389328192197,
|
||||
2.271520771371253,
|
||||
2.322373696229342,
|
||||
2.3699990328716107,
|
||||
2.414398437185221,
|
||||
2.4587748041127506,
|
||||
2.499446286796604,
|
||||
2.5364027376452056,
|
||||
2.5696460593920065,
|
||||
2.602860350286428,
|
||||
2.630396440815385,
|
||||
2.6521732021128046,
|
||||
2.6681935771243177,
|
||||
2.6841217449620203,
|
||||
2.6947834587664494,
|
||||
2.705443819238505,
|
||||
2.714526681131686
|
||||
],
|
||||
"gain_ripple": [
|
||||
0.07704745697916238,
|
||||
0.06479749697916048,
|
||||
0.05257029697916238,
|
||||
0.040326236979161934,
|
||||
0.028098946979159933,
|
||||
0.01393231697916164,
|
||||
-0.0021726530208390216,
|
||||
-0.01819858302084043,
|
||||
-0.03218106302083967,
|
||||
-0.042428283020839785,
|
||||
-0.05095282302083959,
|
||||
-0.05947139302083926,
|
||||
-0.06968090302083851,
|
||||
-0.07844600302084004,
|
||||
-0.08407607302083875,
|
||||
-0.0865687230208394,
|
||||
-0.08906007302083907,
|
||||
-0.0913487130208388,
|
||||
-0.09343261302083761,
|
||||
-0.09717347302083823,
|
||||
-0.1027863830208382,
|
||||
-0.11089282302084058,
|
||||
-0.11963431302083904,
|
||||
-0.1279646530208396,
|
||||
-0.13525493302083902,
|
||||
-0.1409032730208395,
|
||||
-0.14591937302083835,
|
||||
-0.14823350302084037,
|
||||
-0.1484450830208388,
|
||||
-0.1455411330208385,
|
||||
-0.14160178302083892,
|
||||
-0.1353792530208402,
|
||||
-0.12789859302083784,
|
||||
-0.11916081302083725,
|
||||
-0.11041488302083735,
|
||||
-0.10103437302083762,
|
||||
-0.09101254302083817,
|
||||
-0.07868024302083754,
|
||||
-0.06468462302083822,
|
||||
-0.051112303020840244,
|
||||
-0.039618433020837784,
|
||||
-0.028748483020837767,
|
||||
-0.016475303020840215,
|
||||
-0.006936193020838033,
|
||||
-0.0015763130208377163,
|
||||
0.0007104669791608842,
|
||||
0.0040435869791615175,
|
||||
0.006965146979162284,
|
||||
0.00842583697916055,
|
||||
0.00874012697916271,
|
||||
0.00936596697916059,
|
||||
0.01030063697916006,
|
||||
0.011234826979162449,
|
||||
0.013321846979160057,
|
||||
0.01659282697915998,
|
||||
0.023488786979161347,
|
||||
0.03285456697916089,
|
||||
0.04072968697916224,
|
||||
0.04467697697916151,
|
||||
0.04551704697916037,
|
||||
0.04717897697916129,
|
||||
0.04946107697915991,
|
||||
0.05154489697916276,
|
||||
0.05447361697916264,
|
||||
0.05848224697916038,
|
||||
0.06916723697916183,
|
||||
0.08548825697916129,
|
||||
0.10802383697916085,
|
||||
0.13114358697916018,
|
||||
0.15216302697916007,
|
||||
0.17037189697916233,
|
||||
0.1767381569791624,
|
||||
0.1739275269791598,
|
||||
0.15945681697916214,
|
||||
0.14239527697916188,
|
||||
0.12276252697916235,
|
||||
0.10313984697916112,
|
||||
0.08731066697916035,
|
||||
0.07533675697916209,
|
||||
0.07114372697916238,
|
||||
0.07094413697916124,
|
||||
0.07091459697916136,
|
||||
0.0670723869791594,
|
||||
0.054956336979159914,
|
||||
0.038328296979159404,
|
||||
0.017572956979162058,
|
||||
-0.0028138630208403015,
|
||||
-0.016792253020838643,
|
||||
-0.0246928330208398,
|
||||
-0.018326963020840026,
|
||||
-0.0036199830208403228,
|
||||
0.02602813697916062,
|
||||
0.06245819697916133,
|
||||
0.09542181697916163,
|
||||
0.11822862697916037,
|
||||
0.1359703369791596
|
||||
]
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ from gnpy.tools.json_io import load_equipment
|
||||
from gnpy.topology.request import jsontocsv
|
||||
|
||||
|
||||
parser = ArgumentParser(description='A function that writes json path results in an excel sheet.')
|
||||
parser.add_argument('filename', nargs='?', type=Path)
|
||||
parser.add_argument('output_filename', nargs='?', type=Path)
|
||||
parser = ArgumentParser(description='Converting JSON path results into a CSV')
|
||||
parser.add_argument('filename', type=Path)
|
||||
parser.add_argument('output_filename', type=Path)
|
||||
parser.add_argument('eqpt_filename', nargs='?', type=Path, default=Path(__file__).parent / 'eqpt_config.json')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'''
|
||||
"""
|
||||
Processing of data via :py:mod:`.json_io`.
|
||||
Utilities for Excel conversion in :py:mod:`.convert` and :py:mod:`.service_sheet`.
|
||||
Example code in :py:mod:`.cli_examples` and :py:mod:`.plots`.
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
"""
|
||||
gnpy.tools.cli_examples
|
||||
=======================
|
||||
|
||||
Common code for CLI examples
|
||||
'''
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os.path
|
||||
import sys
|
||||
from math import ceil
|
||||
from numpy import linspace, mean
|
||||
from pathlib import Path
|
||||
|
||||
import gnpy.core.ansi_escapes as ansi_escapes
|
||||
from gnpy.core.elements import Transceiver, Fiber, RamanFiber
|
||||
from gnpy.core.equipment import trx_mode_params
|
||||
import gnpy.core.exceptions as exceptions
|
||||
from gnpy.core.network import build_network
|
||||
from gnpy.core.network import add_missing_elements_in_network, design_network
|
||||
from gnpy.core.parameters import SimParams
|
||||
from gnpy.core.science_utils import Simulation
|
||||
from gnpy.core.utils import db2lin, lin2db, automatic_nch
|
||||
from gnpy.core.utils import db2lin, lin2db, automatic_nch, watt2dbm, dbm2watt
|
||||
from gnpy.topology.request import (ResultElement, jsontocsv, compute_path_dsjctn, requests_aggregation,
|
||||
BLOCKING_NOPATH, correct_json_route_list,
|
||||
deduplicate_disjunctions, compute_path_with_disjunction,
|
||||
PathRequest, compute_constrained_path, propagate)
|
||||
from gnpy.topology.spectrum_assignment import build_oms_list, pth_assign_spectrum
|
||||
from gnpy.tools.json_io import load_equipment, load_network, load_json, load_requests, save_network, \
|
||||
requests_from_json, disjunctions_from_json, save_json
|
||||
from gnpy.tools.json_io import (load_equipment, load_network, load_json, load_requests, save_network,
|
||||
requests_from_json, disjunctions_from_json, save_json, load_initial_spectrum)
|
||||
from gnpy.tools.plots import plot_baseline, plot_results
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -49,7 +48,7 @@ def show_example_data_dir():
|
||||
|
||||
|
||||
def load_common_data(equipment_filename, topology_filename, simulation_filename, save_raw_network_filename):
|
||||
'''Load common configuration from JSON files'''
|
||||
"""Load common configuration from JSON files"""
|
||||
|
||||
try:
|
||||
equipment = load_equipment(equipment_filename)
|
||||
@@ -57,14 +56,15 @@ def load_common_data(equipment_filename, topology_filename, simulation_filename,
|
||||
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 not simulation_filename:
|
||||
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)
|
||||
sim_params = load_json(simulation_filename)
|
||||
SimParams.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)
|
||||
@@ -85,7 +85,7 @@ def load_common_data(equipment_filename, topology_filename, simulation_filename,
|
||||
|
||||
|
||||
def _setup_logging(args):
|
||||
logging.basicConfig(level={2: logging.DEBUG, 1: logging.INFO, 0: logging.CRITICAL}.get(args.verbose, logging.DEBUG))
|
||||
logging.basicConfig(level={2: logging.DEBUG, 1: logging.INFO, 0: logging.WARNING}.get(args.verbose, logging.DEBUG))
|
||||
|
||||
|
||||
def _add_common_options(parser: argparse.ArgumentParser, network_default: Path):
|
||||
@@ -103,6 +103,9 @@ def _add_common_options(parser: argparse.ArgumentParser, network_default: Path):
|
||||
help='Save the final network as a JSON file')
|
||||
parser.add_argument('--save-network-before-autodesign', type=Path, metavar=_help_fname_json,
|
||||
help='Dump the network into a JSON file prior to autodesign')
|
||||
parser.add_argument('--no-insert-edfas', action='store_true',
|
||||
help='Disable insertion of EDFAs after ROADMs and fibers '
|
||||
'as well as splitting of fibers by auto-design.')
|
||||
|
||||
|
||||
def transmission_main_example(args=None):
|
||||
@@ -116,6 +119,7 @@ def transmission_main_example(args=None):
|
||||
parser.add_argument('-pl', '--plot', action='store_true')
|
||||
parser.add_argument('-l', '--list-nodes', action='store_true', help='list all transceiver nodes')
|
||||
parser.add_argument('-po', '--power', default=0, help='channel ref power in dBm')
|
||||
parser.add_argument('--spectrum', type=Path, help='user defined mixed rate spectrum JSON file')
|
||||
parser.add_argument('source', nargs='?', help='source node')
|
||||
parser.add_argument('destination', nargs='?', help='destination node')
|
||||
|
||||
@@ -187,48 +191,81 @@ def transmission_main_example(args=None):
|
||||
params['loose_list'] = ['strict']
|
||||
params['format'] = ''
|
||||
params['path_bandwidth'] = 0
|
||||
params['effective_freq_slot'] = None
|
||||
trx_params = trx_mode_params(equipment)
|
||||
trx_params['power'] = dbm2watt(equipment['SI']['default'].power_dbm)
|
||||
trx_params['tx_power'] = dbm2watt(equipment['SI']['default'].power_dbm)
|
||||
if args.power:
|
||||
trx_params['power'] = db2lin(float(args.power)) * 1e-3
|
||||
trx_params['power'] = dbm2watt(float(args.power))
|
||||
trx_params['tx_power'] = dbm2watt(float(args.power))
|
||||
params.update(trx_params)
|
||||
initial_spectrum = None
|
||||
params['nb_channel'] = automatic_nch(trx_params['f_min'], trx_params['f_max'], trx_params['spacing'])
|
||||
# use ref_req to hold reference channel used for design and req for the propagation
|
||||
# and req to hold channels to be propagated
|
||||
# apply power sweep on the design and on the channels
|
||||
ref_req = PathRequest(**params)
|
||||
pref_ch_db = watt2dbm(ref_req.power)
|
||||
if args.spectrum:
|
||||
# use the spectrum defined by user for the propagation.
|
||||
# the nb of channel for design remains the one of the reference channel
|
||||
initial_spectrum = load_initial_spectrum(args.spectrum)
|
||||
params['nb_channel'] = len(initial_spectrum)
|
||||
print('User input for spectrum used for propagation instead of SI')
|
||||
req = PathRequest(**params)
|
||||
|
||||
p_ch_db = watt2dbm(req.power)
|
||||
req.initial_spectrum = initial_spectrum
|
||||
print(f'There are {req.nb_channel} channels propagating')
|
||||
power_mode = equipment['Span']['default'].power_mode
|
||||
print('\n'.join([f'Power mode is set to {power_mode}',
|
||||
f'=> it can be modified in eqpt_config.json - Span']))
|
||||
'=> it can be modified in eqpt_config.json - Span']))
|
||||
if not args.no_insert_edfas:
|
||||
try:
|
||||
add_missing_elements_in_network(network, equipment)
|
||||
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)
|
||||
|
||||
pref_ch_db = lin2db(req.power * 1e3) # reference channel power / span (SL=20dB)
|
||||
pref_total_db = pref_ch_db + lin2db(req.nb_channel) # reference total power / span (SL=20dB)
|
||||
path = compute_constrained_path(network, req)
|
||||
spans = [s.params.length for s in path if isinstance(s, RamanFiber) or isinstance(s, Fiber)]
|
||||
power_range = [0]
|
||||
if power_mode:
|
||||
# power cannot be changed in gain mode
|
||||
try:
|
||||
p_start, p_stop, p_step = equipment['SI']['default'].power_range_db
|
||||
p_num = abs(int(round((p_stop - p_start) / p_step))) + 1 if p_step != 0 else 1
|
||||
power_range = list(linspace(p_start, p_stop, p_num))
|
||||
except TypeError:
|
||||
print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]')
|
||||
# initial network is designed using req.power. that is that any missing information (amp gain or delta_p) is filled
|
||||
# using this req.power, previous to any sweep requested later on.
|
||||
try:
|
||||
build_network(network, equipment, pref_ch_db, pref_total_db)
|
||||
design_network(ref_req, network, equipment, set_connector_losses=True, verbose=True)
|
||||
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)
|
||||
path = compute_constrained_path(network, req)
|
||||
|
||||
spans = [s.params.length for s in path if isinstance(s, RamanFiber) or isinstance(s, Fiber)]
|
||||
print(f'\nThere are {len(spans)} fiber spans over {sum(spans)/1000:.0f} km between {source.uid} '
|
||||
f'and {destination.uid}')
|
||||
print(f'\nNow propagating between {source.uid} and {destination.uid}:')
|
||||
|
||||
try:
|
||||
p_start, p_stop, p_step = equipment['SI']['default'].power_range_db
|
||||
p_num = abs(int(round((p_stop - p_start) / p_step))) + 1 if p_step != 0 else 1
|
||||
power_range = list(linspace(p_start, p_stop, p_num))
|
||||
except TypeError:
|
||||
print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]')
|
||||
power_range = [0]
|
||||
|
||||
if not power_mode:
|
||||
# power cannot be changed in gain mode
|
||||
power_range = [0]
|
||||
for dp_db in power_range:
|
||||
req.power = db2lin(pref_ch_db + dp_db) * 1e-3
|
||||
ref_req.power = dbm2watt(pref_ch_db + dp_db)
|
||||
req.power = dbm2watt(p_ch_db + dp_db)
|
||||
design_network(ref_req, network, equipment, set_connector_losses=False, verbose=False)
|
||||
# if initial spectrum did not contain any power, now we need to use this one.
|
||||
# note the initial power defines a differential wrt req.power so that if req.power is set to 2mW (3dBm)
|
||||
# and initial spectrum was set to 0, this sets a initial per channel delta power to -3dB, so that
|
||||
# whatever the equalization, -3 dB is applied on all channels (ie initial power in initial spectrum pre-empts
|
||||
# "--power" option)
|
||||
if power_mode:
|
||||
print(f'\nPropagating with input power = {ansi_escapes.cyan}{lin2db(req.power*1e3):.2f} dBm{ansi_escapes.reset}:')
|
||||
print(f'\nPropagating with input power = {ansi_escapes.cyan}{watt2dbm(req.power):.2f} '
|
||||
+ f'dBm{ansi_escapes.reset}:')
|
||||
else:
|
||||
print(f'\nPropagating in {ansi_escapes.cyan}gain mode{ansi_escapes.reset}: power cannot be set manually')
|
||||
infos = propagate(path, req, equipment)
|
||||
@@ -262,9 +299,9 @@ def transmission_main_example(args=None):
|
||||
ch_freq = final_carrier.frequency * 1e-12
|
||||
ch_power = lin2db(final_carrier.power.signal * 1e3)
|
||||
print(
|
||||
'{:5}{:26.2f}{:26.2f}{:28.2f}{:28.2f}{:28.2f}' .format(
|
||||
'{:5}{:26.5f}{:26.2f}{:28.2f}{:28.2f}{:28.2f}' .format(
|
||||
final_carrier.channel_number, round(
|
||||
ch_freq, 2), round(
|
||||
ch_freq, 5), round(
|
||||
ch_power, 2), round(
|
||||
ch_osnr, 2), round(
|
||||
ch_snr_nl, 2), round(
|
||||
@@ -306,26 +343,52 @@ def path_requests_run(args=None):
|
||||
args = parser.parse_args(args if args is not None else sys.argv[1:])
|
||||
_setup_logging(args)
|
||||
|
||||
_logger.info(f'Computing path requests {args.service_filename} into JSON format')
|
||||
print(f'{ansi_escapes.blue}Computing path requests {os.path.relpath(args.service_filename)} into JSON format{ansi_escapes.reset}')
|
||||
_logger.info(f'Computing path requests {args.service_filename.name} into JSON format')
|
||||
|
||||
(equipment, network) = load_common_data(args.equipment, args.topology, args.sim_params, args.save_network_before_autodesign)
|
||||
|
||||
# Build the network once using the default power defined in SI in eqpt config
|
||||
# TODO 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
|
||||
if not args.no_insert_edfas:
|
||||
try:
|
||||
add_missing_elements_in_network(network, equipment)
|
||||
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)
|
||||
|
||||
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
|
||||
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
|
||||
params = {
|
||||
'request_id': 'reference',
|
||||
'trx_type': '',
|
||||
'trx_mode': '',
|
||||
'source': None,
|
||||
'destination': None,
|
||||
'bidir': False,
|
||||
'nodes_list': [],
|
||||
'loose_list': [],
|
||||
'format': '',
|
||||
'path_bandwidth': 0,
|
||||
'effective_freq_slot': None,
|
||||
'nb_channel': automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max,
|
||||
equipment['SI']['default'].spacing),
|
||||
'power': dbm2watt(equipment['SI']['default'].power_dbm),
|
||||
'tx_power': dbm2watt(equipment['SI']['default'].power_dbm)
|
||||
}
|
||||
trx_params = trx_mode_params(equipment)
|
||||
params.update(trx_params)
|
||||
reference_channel = PathRequest(**params)
|
||||
try:
|
||||
build_network(network, equipment, p_db, p_total_db)
|
||||
design_network(reference_channel, network, equipment, verbose=True)
|
||||
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)
|
||||
|
||||
if args.save_network is not None:
|
||||
save_network(network, args.save_network)
|
||||
print(f'{ansi_escapes.blue}Network (after autodesign) saved to {args.save_network}{ansi_escapes.reset}')
|
||||
|
||||
@@ -21,18 +21,22 @@ the "east" information so that it is possible to input undirected data.
|
||||
"""
|
||||
|
||||
from xlrd import open_workbook
|
||||
from logging import getLogger
|
||||
from argparse import ArgumentParser
|
||||
from collections import namedtuple, Counter, defaultdict
|
||||
from itertools import chain
|
||||
from json import dumps
|
||||
from pathlib import Path
|
||||
from copy import copy
|
||||
from gnpy.core import ansi_escapes
|
||||
|
||||
from gnpy.core.utils import silent_remove
|
||||
from gnpy.core.exceptions import NetworkTopologyError
|
||||
from gnpy.core.elements import Edfa, Fused, Fiber
|
||||
|
||||
|
||||
_logger = getLogger(__name__)
|
||||
|
||||
|
||||
def all_rows(sh, start=0):
|
||||
return (sh.row(x) for x in range(start, sh.nrows))
|
||||
|
||||
@@ -118,7 +122,7 @@ class Eqpt(object):
|
||||
'east_att_in': 0,
|
||||
'east_amp_gain': None,
|
||||
'east_amp_dp': None,
|
||||
'east_tilt': 0,
|
||||
'east_tilt_vs_wavelength': 0,
|
||||
'east_att_out': None
|
||||
}
|
||||
|
||||
@@ -183,18 +187,18 @@ def parse_headers(my_sheet, input_headers_dict, headers, start_line, slice_in):
|
||||
slice_out = read_slice(my_sheet, start_line + iteration, slice_in, h0)
|
||||
iteration += 1
|
||||
if slice_out == (-1, -1):
|
||||
msg = f'missing header {h0}'
|
||||
if h0 in ('east', 'Node A', 'Node Z', 'City'):
|
||||
print(f'{ansi_escapes.red}CRITICAL{ansi_escapes.reset}: missing _{h0}_ header: EXECUTION ENDS')
|
||||
raise NetworkTopologyError(f'Missing _{h0}_ header')
|
||||
raise NetworkTopologyError(msg)
|
||||
else:
|
||||
print(f'missing header {h0}')
|
||||
_logger.warning(msg)
|
||||
elif not isinstance(input_headers_dict[h0], dict):
|
||||
headers[slice_out[0]] = input_headers_dict[h0]
|
||||
else:
|
||||
headers = parse_headers(my_sheet, input_headers_dict[h0], headers, start_line + 1, slice_out)
|
||||
if headers == {}:
|
||||
print(f'{ansi_escapes.red}CRITICAL ERROR{ansi_escapes.reset}: could not find any header to read _ ABORT')
|
||||
raise NetworkTopologyError('Could not find any header to read')
|
||||
msg = 'CRITICAL ERROR: could not find any header to read _ ABORT'
|
||||
raise NetworkTopologyError(msg)
|
||||
return headers
|
||||
|
||||
|
||||
@@ -219,40 +223,76 @@ def sanity_check(nodes, links, nodes_by_city, links_by_city, eqpts_by_city):
|
||||
for l1 in links:
|
||||
for l2 in links:
|
||||
if l1 is not l2 and l1 == l2 and l2 not in duplicate_links:
|
||||
print(f'\nWARNING\n \
|
||||
_logger.warning(f'\nWARNING\n \
|
||||
link {l1.from_city}-{l1.to_city} is duplicate \
|
||||
\nthe 1st duplicate link will be removed but you should check Links sheet input')
|
||||
duplicate_links.append(l1)
|
||||
for l in duplicate_links:
|
||||
links.remove(l)
|
||||
links_by_city[l.from_city].remove(l)
|
||||
links_by_city[l.to_city].remove(l)
|
||||
|
||||
if duplicate_links:
|
||||
msg = 'XLS error: ' \
|
||||
+ f'links {_format_items([(d.from_city, d.to_city) for d in duplicate_links])} are duplicate'
|
||||
raise NetworkTopologyError(msg)
|
||||
unreferenced_nodes = [n for n in nodes_by_city if n not in links_by_city]
|
||||
if unreferenced_nodes:
|
||||
raise NetworkTopologyError(f'{ansi_escapes.red}XLS error:{ansi_escapes.reset} The following nodes are not '
|
||||
f'referenced from the {ansi_escapes.cyan}Links{ansi_escapes.reset} sheet. '
|
||||
f'If unused, remove them from the {ansi_escapes.cyan}Nodes{ansi_escapes.reset} '
|
||||
f'sheet:\n'
|
||||
+ _format_items(unreferenced_nodes))
|
||||
msg = 'XLS error: The following nodes are not ' \
|
||||
+ 'referenced from the Links sheet. ' \
|
||||
+ 'If unused, remove them from the Nodes sheet:\n' \
|
||||
+ _format_items(unreferenced_nodes)
|
||||
raise NetworkTopologyError(msg)
|
||||
# no need to check "Links" for invalid nodes because that's already in parse_excel()
|
||||
wrong_eqpt_from = [n for n in eqpts_by_city if n not in nodes_by_city]
|
||||
wrong_eqpt_to = [n.to_city for destinations in eqpts_by_city.values()
|
||||
for n in destinations if n.to_city not in nodes_by_city]
|
||||
wrong_eqpt = wrong_eqpt_from + wrong_eqpt_to
|
||||
if wrong_eqpt:
|
||||
raise NetworkTopologyError(f'{ansi_escapes.red}XLS error:{ansi_escapes.reset} '
|
||||
f'The {ansi_escapes.cyan}Eqpt{ansi_escapes.reset} sheet refers to nodes that '
|
||||
f'are not defined in the {ansi_escapes.cyan}Nodes{ansi_escapes.reset} sheet:\n'
|
||||
+ _format_items(wrong_eqpt))
|
||||
msg = 'XLS error: ' \
|
||||
+ 'The Eqpt sheet refers to nodes that ' \
|
||||
+ 'are not defined in the Nodes sheet:\n'\
|
||||
+ _format_items(wrong_eqpt)
|
||||
raise NetworkTopologyError(msg)
|
||||
# Now check links that are not listed in Links sheet, and duplicates
|
||||
bad_eqpt = []
|
||||
possible_links = [f'{e.from_city}|{e.to_city}' for e in links] + [f'{e.to_city}|{e.from_city}' for e in links]
|
||||
possible_eqpt = []
|
||||
duplicate_eqpt = []
|
||||
duplicate_ila = []
|
||||
for city, eqpts in eqpts_by_city.items():
|
||||
for eqpt in eqpts:
|
||||
# Check that each node_A-node_Z exists in links
|
||||
nodea_nodez = f'{eqpt.from_city}|{eqpt.to_city}'
|
||||
nodez_nodea = f'{eqpt.to_city}|{eqpt.from_city}'
|
||||
if nodea_nodez not in possible_links \
|
||||
or nodez_nodea not in possible_links:
|
||||
bad_eqpt.append([eqpt.from_city, eqpt.to_city])
|
||||
else:
|
||||
# Check that there are no duplicate lines in the Eqpt sheet
|
||||
if nodea_nodez in possible_eqpt:
|
||||
duplicate_eqpt.append([eqpt.from_city, eqpt.to_city])
|
||||
else:
|
||||
possible_eqpt.append(nodea_nodez)
|
||||
# check that there are no two lines defining an ILA with different directions
|
||||
if nodes_by_city[city].node_type == 'ILA' and len(eqpts) > 1:
|
||||
duplicate_ila.append(city)
|
||||
if bad_eqpt:
|
||||
msg = 'XLS error: ' \
|
||||
+ 'The Eqpt sheet references links that ' \
|
||||
+ 'are not defined in the Links sheet:\n' \
|
||||
+ _format_items(f'{item[0]} -> {item[1]}' for item in bad_eqpt)
|
||||
raise NetworkTopologyError(msg)
|
||||
if duplicate_eqpt:
|
||||
msg = 'XLS error: Duplicate lines in Eqpt sheet:' \
|
||||
+ _format_items(f'{item[0]} -> {item[1]}' for item in duplicate_eqpt)
|
||||
raise NetworkTopologyError(msg)
|
||||
if duplicate_ila:
|
||||
msg = 'XLS error: Duplicate ILA eqpt definition in Eqpt sheet:' \
|
||||
+ _format_items(duplicate_ila)
|
||||
raise NetworkTopologyError(msg)
|
||||
|
||||
for city, link in links_by_city.items():
|
||||
if nodes_by_city[city].node_type.lower() == 'ila' and len(link) != 2:
|
||||
# wrong input: ILA sites can only be Degree 2
|
||||
# => correct to make it a ROADM and remove entry in links_by_city
|
||||
# TODO: put in log rather than print
|
||||
print(f'invalid node type ({nodes_by_city[city].node_type})\
|
||||
specified in {city}, replaced by ROADM')
|
||||
_logger.warning(f'invalid node type ({nodes_by_city[city].node_type}) '
|
||||
+ f'specified in {city}, replaced by ROADM')
|
||||
nodes_by_city[city].node_type = 'ROADM'
|
||||
for n in nodes:
|
||||
if n.city == city:
|
||||
@@ -305,13 +345,13 @@ def create_east_eqpt_element(node):
|
||||
eqpt['type_variety'] = f'{node.east_amp_type}'
|
||||
eqpt['operational'] = {'gain_target': node.east_amp_gain,
|
||||
'delta_p': node.east_amp_dp,
|
||||
'tilt_target': node.east_tilt,
|
||||
'tilt_target': node.east_tilt_vs_wavelength,
|
||||
'out_voa': node.east_att_out}
|
||||
elif node.east_amp_type.lower() == '':
|
||||
eqpt['type'] = 'Edfa'
|
||||
eqpt['operational'] = {'gain_target': node.east_amp_gain,
|
||||
'delta_p': node.east_amp_dp,
|
||||
'tilt_target': node.east_tilt,
|
||||
'tilt_target': node.east_tilt_vs_wavelength,
|
||||
'out_voa': node.east_att_out}
|
||||
elif node.east_amp_type.lower() == 'fused':
|
||||
# fused edfa variety is a hack to indicate that there should not be
|
||||
@@ -338,12 +378,12 @@ def create_west_eqpt_element(node):
|
||||
eqpt['type_variety'] = f'{node.west_amp_type}'
|
||||
eqpt['operational'] = {'gain_target': node.west_amp_gain,
|
||||
'delta_p': node.west_amp_dp,
|
||||
'tilt_target': node.west_tilt,
|
||||
'tilt_target': node.west_tilt_vs_wavelength,
|
||||
'out_voa': node.west_att_out}
|
||||
elif node.west_amp_type.lower() == '':
|
||||
eqpt['operational'] = {'gain_target': node.west_amp_gain,
|
||||
'delta_p': node.west_amp_dp,
|
||||
'tilt_target': node.west_tilt,
|
||||
'tilt_target': node.west_tilt_vs_wavelength,
|
||||
'out_voa': node.west_att_out}
|
||||
elif node.west_amp_type.lower() == 'fused':
|
||||
eqpt['type'] = 'Fused'
|
||||
@@ -642,17 +682,19 @@ def parse_excel(input_filename):
|
||||
# sanity check
|
||||
all_cities = Counter(n.city for n in nodes)
|
||||
if len(all_cities) != len(nodes):
|
||||
raise ValueError(f'Duplicate city: {all_cities}')
|
||||
msg = f'Duplicate city: {all_cities}'
|
||||
raise NetworkTopologyError(msg)
|
||||
bad_links = []
|
||||
for lnk in links:
|
||||
if lnk.from_city not in all_cities or lnk.to_city not in all_cities:
|
||||
bad_links.append([lnk.from_city, lnk.to_city])
|
||||
|
||||
if bad_links:
|
||||
raise NetworkTopologyError(f'{ansi_escapes.red}XLS error:{ansi_escapes.reset} '
|
||||
f'The {ansi_escapes.cyan}Links{ansi_escapes.reset} sheet references nodes that '
|
||||
f'are not defined in the {ansi_escapes.cyan}Nodes{ansi_escapes.reset} sheet:\n'
|
||||
+ _format_items(f'{item[0]} -> {item[1]}' for item in bad_links))
|
||||
msg = 'XLS error: ' \
|
||||
+ 'The Links sheet references nodes that ' \
|
||||
+ 'are not defined in the Nodes sheet:\n' \
|
||||
+ _format_items(f'{item[0]} -> {item[1]}' for item in bad_links)
|
||||
raise NetworkTopologyError(msg)
|
||||
|
||||
return nodes, links, eqpts, roadms
|
||||
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
"""
|
||||
gnpy.tools.json_io
|
||||
==================
|
||||
|
||||
Loading and saving data from JSON files in GNPy's internal data format
|
||||
'''
|
||||
"""
|
||||
|
||||
from networkx import DiGraph
|
||||
from logging import getLogger
|
||||
from pathlib import Path
|
||||
import json
|
||||
from collections import namedtuple
|
||||
from gnpy.core import ansi_escapes, elements
|
||||
from numpy import arange
|
||||
|
||||
from gnpy.core import elements
|
||||
from gnpy.core.equipment import trx_mode_params
|
||||
from gnpy.core.exceptions import ConfigurationError, EquipmentConfigError, NetworkTopologyError, ServiceError
|
||||
from gnpy.core.science_utils import estimate_nf_model
|
||||
from gnpy.core.utils import automatic_nch, automatic_fmax, merge_amplifier_restrictions
|
||||
from gnpy.topology.request import PathRequest, Disjunction
|
||||
from gnpy.core.info import Carrier
|
||||
from gnpy.core.utils import automatic_nch, automatic_fmax, merge_amplifier_restrictions, dbm2watt
|
||||
from gnpy.core.parameters import DEFAULT_RAMAN_COEFFICIENT, EdfaParams
|
||||
from gnpy.topology.request import PathRequest, Disjunction, compute_spectrum_slot_vs_bandwidth
|
||||
from gnpy.topology.spectrum_assignment import mvalue_to_slots
|
||||
from gnpy.tools.convert import xls_to_json_data
|
||||
from gnpy.tools.service_sheet import read_service_sheet
|
||||
|
||||
@@ -33,16 +38,24 @@ Model_hybrid = namedtuple('Model_hybrid', 'nf_ram gain_ram edfa_variety')
|
||||
Model_dual_stage = namedtuple('Model_dual_stage', 'preamp_variety booster_variety')
|
||||
|
||||
|
||||
class Model_openroadm_preamp:
|
||||
pass
|
||||
|
||||
|
||||
class Model_openroadm_booster:
|
||||
pass
|
||||
|
||||
|
||||
class _JsonThing:
|
||||
def update_attr(self, default_values, kwargs, name):
|
||||
clean_kwargs = {k: v for k, v in kwargs.items() if v != ''}
|
||||
for k, v in default_values.items():
|
||||
setattr(self, k, clean_kwargs.get(k, v))
|
||||
if k not in clean_kwargs and name != 'Amp':
|
||||
print(ansi_escapes.red +
|
||||
f'\n WARNING missing {k} attribute in eqpt_config.json[{name}]' +
|
||||
f'\n default value is {k} = {v}' +
|
||||
ansi_escapes.reset)
|
||||
if k not in clean_kwargs and name != 'Amp' and v is not None and v != []:
|
||||
# do not show this warning if the default value is None
|
||||
msg = f'\n\tWARNING missing {k} attribute in eqpt_config.json[{name}]' \
|
||||
+ f'\n\tdefault value is {k} = {v}\n'
|
||||
_logger.warning(msg)
|
||||
|
||||
|
||||
class SI(_JsonThing):
|
||||
@@ -55,7 +68,8 @@ class SI(_JsonThing):
|
||||
"power_range_db": [0, 0, 0.5],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"sys_margins": 0
|
||||
"sys_margins": 0,
|
||||
"tx_power_dbm": None # optional value in SI
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -83,16 +97,33 @@ class Span(_JsonThing):
|
||||
|
||||
class Roadm(_JsonThing):
|
||||
default_values = {
|
||||
'target_pch_out_db': -17,
|
||||
'type_variety': 'default',
|
||||
'add_drop_osnr': 100,
|
||||
'pmd': 0,
|
||||
'pdl': 0,
|
||||
'restrictions': {
|
||||
'preamp_variety_list': [],
|
||||
'booster_variety_list': []
|
||||
}
|
||||
},
|
||||
'roadm-path-impairments': []
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
# If equalization is not defined in equipment, then raise an error.
|
||||
# Only one type of equalization must be defined.
|
||||
allowed_equalisations = ['target_pch_out_db', 'target_psd_out_mWperGHz', 'target_out_mWperSlotWidth']
|
||||
requested_eq_mask = [eq in kwargs for eq in allowed_equalisations]
|
||||
if sum(requested_eq_mask) > 1:
|
||||
msg = 'Only one equalization type should be set in ROADM, found: ' \
|
||||
+ ', '.join(eq for eq in allowed_equalisations if eq in kwargs)
|
||||
raise EquipmentConfigError(msg)
|
||||
if not any(requested_eq_mask):
|
||||
msg = 'No equalization type set in ROADM'
|
||||
raise EquipmentConfigError(msg)
|
||||
for key in allowed_equalisations:
|
||||
if key in kwargs:
|
||||
setattr(self, key, kwargs[key])
|
||||
break
|
||||
self.update_attr(self.default_values, kwargs, 'Roadm')
|
||||
|
||||
|
||||
@@ -105,57 +136,55 @@ class Transceiver(_JsonThing):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.update_attr(self.default_values, kwargs, 'Transceiver')
|
||||
for mode_params in self.mode:
|
||||
penalties = mode_params.get('penalties')
|
||||
mode_params['penalties'] = {}
|
||||
mode_params['equalization_offset_db'] = mode_params.get('equalization_offset_db', 0)
|
||||
if not penalties:
|
||||
continue
|
||||
for impairment in ('chromatic_dispersion', 'pmd', 'pdl'):
|
||||
imp_penalties = [p for p in penalties if impairment in p]
|
||||
if not imp_penalties:
|
||||
continue
|
||||
if all(p[impairment] > 0 for p in imp_penalties):
|
||||
# make sure the list of penalty values include a proper lower boundary
|
||||
# (we assume 0 penalty for 0 impairment)
|
||||
imp_penalties.insert(0, {impairment: 0, 'penalty_value': 0})
|
||||
# make sure the list of penalty values are sorted by impairment value
|
||||
imp_penalties.sort(key=lambda i: i[impairment])
|
||||
# rearrange as dict of lists instead of list of dicts
|
||||
mode_params['penalties'][impairment] = {
|
||||
'up_to_boundary': [p[impairment] for p in imp_penalties],
|
||||
'penalty_value': [p['penalty_value'] for p in imp_penalties]
|
||||
}
|
||||
|
||||
|
||||
class Fiber(_JsonThing):
|
||||
default_values = {
|
||||
'type_variety': '',
|
||||
'dispersion': None,
|
||||
'gamma': 0,
|
||||
'effective_area': None,
|
||||
'pmd_coef': 0
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.update_attr(self.default_values, kwargs, 'Fiber')
|
||||
self.update_attr(self.default_values, kwargs, self.__class__.__name__)
|
||||
if 'gamma' in kwargs:
|
||||
setattr(self, 'gamma', kwargs['gamma'])
|
||||
if 'raman_efficiency' in kwargs:
|
||||
raman_coefficient = kwargs['raman_efficiency']
|
||||
cr = raman_coefficient.pop('cr')
|
||||
raman_coefficient['g0'] = cr
|
||||
raman_coefficient['reference_frequency'] = DEFAULT_RAMAN_COEFFICIENT['reference_frequency']
|
||||
setattr(self, 'raman_coefficient', raman_coefficient)
|
||||
|
||||
|
||||
class RamanFiber(_JsonThing):
|
||||
default_values = {
|
||||
'type_variety': '',
|
||||
'dispersion': None,
|
||||
'gamma': 0,
|
||||
'pmd_coef': 0,
|
||||
'raman_efficiency': None
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.update_attr(self.default_values, kwargs, 'RamanFiber')
|
||||
for param in ('cr', 'frequency_offset'):
|
||||
if param not in self.raman_efficiency:
|
||||
raise EquipmentConfigError(f'RamanFiber.raman_efficiency: missing "{param}" parameter')
|
||||
if self.raman_efficiency['frequency_offset'] != sorted(self.raman_efficiency['frequency_offset']):
|
||||
raise EquipmentConfigError(f'RamanFiber.raman_efficiency.frequency_offset is not sorted')
|
||||
class RamanFiber(Fiber):
|
||||
pass
|
||||
|
||||
|
||||
class Amp(_JsonThing):
|
||||
default_values = {
|
||||
'f_min': 191.35e12,
|
||||
'f_max': 196.1e12,
|
||||
'type_variety': '',
|
||||
'type_def': '',
|
||||
'gain_flatmax': None,
|
||||
'gain_min': None,
|
||||
'p_max': None,
|
||||
'nf_model': None,
|
||||
'dual_stage_model': None,
|
||||
'nf_fit_coeff': None,
|
||||
'nf_ripple': None,
|
||||
'dgt': None,
|
||||
'gain_ripple': None,
|
||||
'out_voa_auto': False,
|
||||
'allowed_for_design': False,
|
||||
'raman': False
|
||||
}
|
||||
default_values = EdfaParams.default_values
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.update_attr(self.default_values, kwargs, 'Amp')
|
||||
@@ -173,7 +202,8 @@ class Amp(_JsonThing):
|
||||
try:
|
||||
nf0 = kwargs.pop('nf0')
|
||||
except KeyError: # nf0 is expected for a fixed gain amp
|
||||
raise EquipmentConfigError(f'missing nf0 value input for amplifier: {type_variety} in equipment config')
|
||||
msg = f'missing nf0 value input for amplifier: {type_variety} in equipment config'
|
||||
raise EquipmentConfigError(msg)
|
||||
for k in ('nf_min', 'nf_max'):
|
||||
try:
|
||||
del kwargs[k]
|
||||
@@ -188,7 +218,8 @@ class Amp(_JsonThing):
|
||||
nf_min = kwargs.pop('nf_min')
|
||||
nf_max = kwargs.pop('nf_max')
|
||||
except KeyError:
|
||||
raise EquipmentConfigError(f'missing nf_min or nf_max value input for amplifier: {type_variety} in equipment config')
|
||||
msg = f'missing nf_min or nf_max value input for amplifier: {type_variety} in equipment config'
|
||||
raise EquipmentConfigError(msg)
|
||||
try: # remove all remaining nf inputs
|
||||
del kwargs['nf0']
|
||||
except KeyError:
|
||||
@@ -201,14 +232,17 @@ class Amp(_JsonThing):
|
||||
except KeyError: # nf_coef is expected for openroadm amp
|
||||
raise EquipmentConfigError(f'missing nf_coef input for amplifier: {type_variety} in equipment config')
|
||||
nf_def = Model_openroadm_ila(nf_coef)
|
||||
elif type_def in ('openroadm_preamp', 'openroadm_booster'):
|
||||
pass # no extra parameters needed
|
||||
elif type_def == 'openroadm_preamp':
|
||||
nf_def = Model_openroadm_preamp()
|
||||
elif type_def == 'openroadm_booster':
|
||||
nf_def = Model_openroadm_booster()
|
||||
elif type_def == 'dual_stage':
|
||||
try: # nf_ram and gain_ram are expected for a hybrid amp
|
||||
preamp_variety = kwargs.pop('preamp_variety')
|
||||
booster_variety = kwargs.pop('booster_variety')
|
||||
except KeyError:
|
||||
raise EquipmentConfigError(f'missing preamp/booster variety input for amplifier: {type_variety} in equipment config')
|
||||
msg = f'missing preamp/booster variety input for amplifier: {type_variety} in equipment config'
|
||||
raise EquipmentConfigError(msg)
|
||||
dual_stage_def = Model_dual_stage(preamp_variety, booster_variety)
|
||||
else:
|
||||
raise EquipmentConfigError(f'Edfa type_def {type_def} does not exist')
|
||||
@@ -227,11 +261,93 @@ def _automatic_spacing(baud_rate):
|
||||
return min((s[1] for s in spacing_list if s[0] > baud_rate), default=baud_rate * 1.2)
|
||||
|
||||
|
||||
def _spectrum_from_json(json_data):
|
||||
"""JSON_data is a list of spectrum partitions each with
|
||||
{f_min, f_max, baud_rate, roll_off, delta_pdb, slot_width, tx_osnr, label}
|
||||
Creates the per freq Carrier's dict.
|
||||
f_min, f_max, baud_rate, slot_width and roll_off are mandatory
|
||||
label, tx_osnr and delta_pdb are created if not present
|
||||
label should be different for each partition
|
||||
>>> json_data = {'spectrum': \
|
||||
[{'f_min': 193.2e12, 'f_max': 193.4e12, 'slot_width': 50e9, 'baud_rate': 32e9, 'roll_off': 0.15, \
|
||||
'delta_pdb': 1, 'tx_osnr': 45, 'tx_power_dbm': -7},\
|
||||
{'f_min': 193.4625e12, 'f_max': 193.9875e12, 'slot_width': 75e9, 'baud_rate': 64e9, 'roll_off': 0.15},\
|
||||
{'f_min': 194.075e12, 'f_max': 194.075e12, 'slot_width': 100e9, 'baud_rate': 90e9, 'roll_off': 0.15},\
|
||||
{'f_min': 194.2e12, 'f_max': 194.35e12, 'slot_width': 50e9, 'baud_rate': 32e9, 'roll_off': 0.15}]}
|
||||
>>> spectrum = _spectrum_from_json(json_data['spectrum'])
|
||||
>>> for k, v in spectrum.items():
|
||||
... print(f'{k}: {v}')
|
||||
...
|
||||
193200000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, tx_power=0.00019952623149688798, label='0-32.00G')
|
||||
193250000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, tx_power=0.00019952623149688798, label='0-32.00G')
|
||||
193300000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, tx_power=0.00019952623149688798, label='0-32.00G')
|
||||
193350000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, tx_power=0.00019952623149688798, label='0-32.00G')
|
||||
193400000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, tx_power=0.00019952623149688798, label='0-32.00G')
|
||||
193462500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='1-64.00G')
|
||||
193537500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='1-64.00G')
|
||||
193612500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='1-64.00G')
|
||||
193687500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='1-64.00G')
|
||||
193762500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='1-64.00G')
|
||||
193837500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='1-64.00G')
|
||||
193912500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='1-64.00G')
|
||||
193987500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='1-64.00G')
|
||||
194075000000000.0: Carrier(delta_pdb=0, baud_rate=90000000000.0, slot_width=100000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='2-90.00G')
|
||||
194200000000000.0: Carrier(delta_pdb=0, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='3-32.00G')
|
||||
194250000000000.0: Carrier(delta_pdb=0, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='3-32.00G')
|
||||
194300000000000.0: Carrier(delta_pdb=0, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='3-32.00G')
|
||||
194350000000000.0: Carrier(delta_pdb=0, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=40, tx_power=0.001, label='3-32.00G')
|
||||
"""
|
||||
spectrum = {}
|
||||
json_data = sorted(json_data, key=lambda x: x['f_min'])
|
||||
# min freq of occupation is f_min - slot_width/2 (numbering starts at 0)
|
||||
previous_part_max_freq = 0.0
|
||||
for index, part in enumerate(json_data):
|
||||
# default delta_pdb is 0 dB
|
||||
if 'delta_pdb' not in part:
|
||||
part['delta_pdb'] = 0
|
||||
# add a label to the partition for the printings
|
||||
if 'label' not in part:
|
||||
part['label'] = f'{index}-{part["baud_rate"] * 1e-9 :.2f}G'
|
||||
# default tx_osnr is set to 40 dB
|
||||
if 'tx_osnr' not in part:
|
||||
part['tx_osnr'] = 40
|
||||
# default tx_power_dbm is set to 0 dBn
|
||||
if 'tx_power_dbm' not in part:
|
||||
part['tx_power_dbm'] = 0
|
||||
# starting freq is exactly f_min to be consistent with utils.automatic_nch
|
||||
# first partition min occupation is f_min - slot_width / 2 (central_frequency is f_min)
|
||||
# supposes that carriers are centered on frequency
|
||||
if previous_part_max_freq > (part['f_min'] - part['slot_width'] / 2):
|
||||
# check that previous part last channel does not overlap on next part first channel
|
||||
# max center of the part should be below part['f_max'] and aligned on the slot_width
|
||||
msg = 'Not a valid initial spectrum definition:\nprevious spectrum last carrier max occupation ' +\
|
||||
f'{previous_part_max_freq * 1e-12 :.5f}GHz ' +\
|
||||
'overlaps on next spectrum first carrier occupation ' +\
|
||||
f'{(part["f_min"] - part["slot_width"] / 2) * 1e-12 :.5f}GHz'
|
||||
raise ValueError(msg)
|
||||
|
||||
max_range = ((part['f_max'] - part['f_min']) // part['slot_width'] + 1) * part['slot_width']
|
||||
for current_freq in arange(part['f_min'],
|
||||
part['f_min'] + max_range,
|
||||
part['slot_width']):
|
||||
spectrum[current_freq] = Carrier(delta_pdb=part['delta_pdb'], baud_rate=part['baud_rate'],
|
||||
slot_width=part['slot_width'], roll_off=part['roll_off'],
|
||||
tx_osnr=part['tx_osnr'], tx_power=dbm2watt(part['tx_power_dbm']),
|
||||
label=part['label'])
|
||||
previous_part_max_freq = current_freq + part['slot_width'] / 2
|
||||
return spectrum
|
||||
|
||||
|
||||
def load_equipment(filename):
|
||||
json_data = load_json(filename)
|
||||
return _equipment_from_json(json_data, filename)
|
||||
|
||||
|
||||
def load_initial_spectrum(filename):
|
||||
json_data = load_json(filename)
|
||||
return _spectrum_from_json(json_data['spectrum'])
|
||||
|
||||
|
||||
def _update_dual_stage(equipment):
|
||||
edfa_dict = equipment['Edfa']
|
||||
for edfa in edfa_dict.values():
|
||||
@@ -252,14 +368,14 @@ def _update_dual_stage(equipment):
|
||||
|
||||
|
||||
def _roadm_restrictions_sanity_check(equipment):
|
||||
""" verifies that booster and preamp restrictions specified in roadm equipment are listed
|
||||
in the edfa.
|
||||
"""
|
||||
restrictions = equipment['Roadm']['default'].restrictions['booster_variety_list'] + \
|
||||
equipment['Roadm']['default'].restrictions['preamp_variety_list']
|
||||
for amp_name in restrictions:
|
||||
if amp_name not in equipment['Edfa']:
|
||||
raise EquipmentConfigError(f'ROADM restriction {amp_name} does not refer to a defined EDFA name')
|
||||
"""verifies that booster and preamp restrictions specified in roadm equipment are listed in the edfa."""
|
||||
for roadm_type, roadm_eqpt in equipment['Roadm'].items():
|
||||
restrictions = roadm_eqpt.restrictions['booster_variety_list'] + \
|
||||
roadm_eqpt.restrictions['preamp_variety_list']
|
||||
for amp_name in restrictions:
|
||||
if amp_name not in equipment['Edfa']:
|
||||
raise EquipmentConfigError(f'ROADM {roadm_type} restriction {amp_name} does not refer to a '
|
||||
+ 'defined EDFA name')
|
||||
|
||||
|
||||
def _check_fiber_vs_raman_fiber(equipment):
|
||||
@@ -267,7 +383,7 @@ def _check_fiber_vs_raman_fiber(equipment):
|
||||
if 'RamanFiber' not in equipment:
|
||||
return
|
||||
for fiber_type in set(equipment['Fiber'].keys()) & set(equipment['RamanFiber'].keys()):
|
||||
for attr in ('dispersion', 'dispersion-slope', 'gamma', 'pmd-coefficient'):
|
||||
for attr in ('dispersion', 'dispersion-slope', 'effective_area', 'gamma', 'pmd-coefficient'):
|
||||
fiber = equipment['Fiber'][fiber_type]
|
||||
raman = equipment['RamanFiber'][fiber_type]
|
||||
a = getattr(fiber, attr, None)
|
||||
@@ -300,6 +416,9 @@ def _equipment_from_json(json_data, filename):
|
||||
elif key == 'Roadm':
|
||||
equipment[key][subkey] = Roadm(**entry)
|
||||
elif key == 'SI':
|
||||
# use power_dbm value for tx_power_dbm if the key is not in 'SI'
|
||||
# if 'tx_power_dbm' not in entry.keys():
|
||||
# entry['tx_power_dbm'] = entry['power_dbm']
|
||||
equipment[key][subkey] = SI(**entry)
|
||||
elif key == 'Transceiver':
|
||||
equipment[key][subkey] = Transceiver(**entry)
|
||||
@@ -324,11 +443,11 @@ def load_network(filename, equipment):
|
||||
|
||||
|
||||
def save_network(network: DiGraph, filename: str):
|
||||
'''Dump the network into a JSON file
|
||||
"""Dump the network into a JSON file
|
||||
|
||||
:param network: network to work on
|
||||
:param filename: file to write to
|
||||
'''
|
||||
"""
|
||||
save_json(network_to_json(network), filename)
|
||||
|
||||
|
||||
@@ -362,14 +481,28 @@ def network_from_json(json_data, equipment):
|
||||
# well, there's no variety for the 'Fused' node type
|
||||
pass
|
||||
elif variety in equipment[typ]:
|
||||
extra_params = equipment[typ][variety]
|
||||
extra_params = equipment[typ][variety].__dict__
|
||||
temp = el_config.setdefault('params', {})
|
||||
temp = merge_amplifier_restrictions(temp, extra_params.__dict__)
|
||||
if typ == 'Roadm':
|
||||
# if equalization is defined, remove default equalization from the extra_params
|
||||
# If equalisation is not defined in the element config, then use the default one from equipment
|
||||
# if more than one equalization was defined in element config, then raise an error
|
||||
extra_params = merge_equalization(temp, extra_params)
|
||||
if not extra_params:
|
||||
msg = f'ROADM {el_config["uid"]}: invalid equalization settings'
|
||||
raise ConfigurationError(msg)
|
||||
temp = merge_amplifier_restrictions(temp, extra_params)
|
||||
el_config['params'] = temp
|
||||
el_config['type_variety'] = variety
|
||||
elif (typ in ['Fiber', 'RamanFiber']) or (typ == 'Edfa' and variety not in ['default', '']):
|
||||
elif (typ in ['Fiber', 'RamanFiber', 'Roadm']):
|
||||
raise ConfigurationError(f'The {typ} of variety type {variety} was not recognized:'
|
||||
'\nplease check it is properly defined in the eqpt_config json file')
|
||||
elif typ == 'Edfa':
|
||||
if variety in ['default', '']:
|
||||
el_config['params'] = Amp.default_values
|
||||
else:
|
||||
raise ConfigurationError(f'The Edfa of variety type {variety} was not recognized:'
|
||||
'\nplease check it is properly defined in the eqpt_config json file')
|
||||
el = cls(**el_config)
|
||||
g.add_node(el)
|
||||
|
||||
@@ -384,7 +517,8 @@ def network_from_json(json_data, equipment):
|
||||
edge_length = 0.01
|
||||
g.add_edge(nodes[from_node], nodes[to_node], weight=edge_length)
|
||||
except KeyError:
|
||||
raise NetworkTopologyError(f'can not find {from_node} or {to_node} defined in {cx}')
|
||||
msg = f'can not find {from_node} or {to_node} defined in {cx}'
|
||||
raise NetworkTopologyError(msg)
|
||||
|
||||
return g
|
||||
|
||||
@@ -415,15 +549,13 @@ def save_json(obj, filename):
|
||||
|
||||
|
||||
def load_requests(filename, eqpt, bidir, network, network_filename):
|
||||
""" loads the requests from a json or an excel file into a data string
|
||||
"""
|
||||
"""loads the requests from a json or an excel file into a data string"""
|
||||
if filename.suffix.lower() in ('.xls', '.xlsx'):
|
||||
_logger.info('Automatically converting requests from XLS to JSON')
|
||||
try:
|
||||
return convert_service_sheet(filename, eqpt, network, network_filename=network_filename, bidir=bidir)
|
||||
except ServiceError as this_e:
|
||||
print(f'{ansi_escapes.red}Service error:{ansi_escapes.reset} {this_e}')
|
||||
exit(1)
|
||||
raise ServiceError(f'Service error: {this_e}')
|
||||
else:
|
||||
return load_json(filename)
|
||||
|
||||
@@ -435,33 +567,36 @@ def requests_from_json(json_data, equipment):
|
||||
for req in json_data['path-request']:
|
||||
# init all params from request
|
||||
params = {}
|
||||
params['request_id'] = req['request-id']
|
||||
params['request_id'] = f'{req["request-id"]}'
|
||||
params['source'] = req['source']
|
||||
params['bidir'] = req['bidirectional']
|
||||
params['destination'] = req['destination']
|
||||
params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type']
|
||||
params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode']
|
||||
if params['trx_type'] is None:
|
||||
msg = f'Request {req["request-id"]} has no transceiver type defined.'
|
||||
raise ServiceError(msg)
|
||||
params['trx_mode'] = req['path-constraints']['te-bandwidth'].get('trx_mode', None)
|
||||
params['format'] = params['trx_mode']
|
||||
params['spacing'] = req['path-constraints']['te-bandwidth']['spacing']
|
||||
try:
|
||||
nd_list = req['explicit-route-objects']['route-object-include-exclude']
|
||||
nd_list = sorted(req['explicit-route-objects']['route-object-include-exclude'], key=lambda x: x['index'])
|
||||
except KeyError:
|
||||
nd_list = []
|
||||
params['nodes_list'] = [n['num-unnum-hop']['node-id'] for n in nd_list]
|
||||
params['loose_list'] = [n['num-unnum-hop']['hop-type'] for n in nd_list]
|
||||
# recover trx physical param (baudrate, ...) from type and mode
|
||||
# in trx_mode_params optical power is read from equipment['SI']['default'] and
|
||||
# nb_channel is computed based on min max frequency and spacing
|
||||
trx_params = trx_mode_params(equipment, params['trx_type'], params['trx_mode'], True)
|
||||
params.update(trx_params)
|
||||
# print(trx_params['min_spacing'])
|
||||
# optical power might be set differently in the request. if it is indicated then the
|
||||
# params['power'] is updated
|
||||
try:
|
||||
if req['path-constraints']['te-bandwidth']['output-power']:
|
||||
params['power'] = req['path-constraints']['te-bandwidth']['output-power']
|
||||
except KeyError:
|
||||
pass
|
||||
trx_params = trx_mode_params(equipment, params['trx_type'], params['trx_mode'], True)
|
||||
except EquipmentConfigError as e:
|
||||
msg = f'Equipment Config error in {req["request-id"]}: {e}'
|
||||
raise EquipmentConfigError(msg) from e
|
||||
params.update(trx_params)
|
||||
params['power'] = req['path-constraints']['te-bandwidth'].get('output-power')
|
||||
# params must not be None, but user can set to None: catch this case
|
||||
if params['power'] is None:
|
||||
params['power'] = dbm2watt(equipment['SI']['default'].power_dbm)
|
||||
|
||||
# same process for nb-channel
|
||||
f_min = params['f_min']
|
||||
f_max_from_si = params['f_max']
|
||||
@@ -475,12 +610,21 @@ def requests_from_json(json_data, equipment):
|
||||
params['nb_channel'] = automatic_nch(f_min, f_max_from_si, params['spacing'])
|
||||
except KeyError:
|
||||
params['nb_channel'] = automatic_nch(f_min, f_max_from_si, params['spacing'])
|
||||
_check_one_request(params, f_max_from_si)
|
||||
|
||||
params['effective_freq_slot'] = \
|
||||
req['path-constraints']['te-bandwidth'].get('effective-freq-slot', [{'N': None, 'M': None}])
|
||||
try:
|
||||
params['path_bandwidth'] = req['path-constraints']['te-bandwidth']['path_bandwidth']
|
||||
except KeyError:
|
||||
pass
|
||||
params['tx_power'] = req['path-constraints']['te-bandwidth'].get('tx_power')
|
||||
default_tx_power_dbm = equipment['SI']['default'].tx_power_dbm
|
||||
if params['tx_power'] is None:
|
||||
# use request's input power in span instead
|
||||
params['tx_power'] = params['power']
|
||||
if default_tx_power_dbm is not None:
|
||||
# use default tx power
|
||||
params['tx_power'] = dbm2watt(default_tx_power_dbm)
|
||||
_check_one_request(params, f_max_from_si)
|
||||
requests_list.append(PathRequest(**params))
|
||||
return requests_list
|
||||
|
||||
@@ -489,28 +633,66 @@ def _check_one_request(params, f_max_from_si):
|
||||
"""Checks that the requested parameters are consistant (spacing vs nb channel vs transponder mode...)"""
|
||||
f_min = params['f_min']
|
||||
f_max = params['f_max']
|
||||
max_recommanded_nb_channels = automatic_nch(f_min, f_max, params['spacing'])
|
||||
max_recommanded_nb_channels = automatic_nch(f_min, f_max_from_si, params['spacing'])
|
||||
if params['baud_rate'] is not None:
|
||||
# implicitly means that a mode is defined with min_spacing
|
||||
if params['min_spacing'] > params['spacing']:
|
||||
msg = f'Request {params["request_id"]} has spacing below transponder ' +\
|
||||
f'{params["trx_type"]} {params["trx_mode"]} min spacing value ' +\
|
||||
f'{params["min_spacing"]*1e-9}GHz.\nComputation stopped'
|
||||
print(msg)
|
||||
_logger.critical(msg)
|
||||
raise ServiceError(msg)
|
||||
if f_max > f_max_from_si:
|
||||
msg = f'''Requested channel number {params["nb_channel"]}, baud rate {params["baud_rate"]} GHz
|
||||
and requested spacing {params["spacing"]*1e-9}GHz is not consistent with frequency range
|
||||
{f_min*1e-12} THz, {f_max*1e-12} THz, min recommanded spacing {params["min_spacing"]*1e-9}GHz.
|
||||
max recommanded nb of channels is {max_recommanded_nb_channels}.'''
|
||||
_logger.critical(msg)
|
||||
msg = f'Requested channel number {params["nb_channel"]}, baud rate {params["baud_rate"] * 1e-9} GHz' \
|
||||
+ f' and requested spacing {params["spacing"]*1e-9}GHz is not consistent with frequency range' \
|
||||
+ f' {f_min*1e-12} THz, {f_max_from_si*1e-12} THz.' \
|
||||
+ f' Max recommanded nb of channels is {max_recommanded_nb_channels}.'
|
||||
raise ServiceError(msg)
|
||||
# Transponder mode already selected; will it fit to the requested bandwidth?
|
||||
if params['trx_mode'] is not None and params['effective_freq_slot'] is not None:
|
||||
required_nb_of_channels, requested_m = compute_spectrum_slot_vs_bandwidth(params['path_bandwidth'],
|
||||
params['spacing'],
|
||||
params['bit_rate'])
|
||||
_, per_channel_m = compute_spectrum_slot_vs_bandwidth(params['bit_rate'],
|
||||
params['spacing'],
|
||||
params['bit_rate'])
|
||||
# each M should fit one or more channels if it is not None
|
||||
# spectrum slots should not overlap
|
||||
# resulting nb of channels should be bigger than the nb computed with path_bandwidth
|
||||
# without being splitted
|
||||
# TODO: elaborate a more accurate estimate with nb_wl * tx_osnr + possibly guardbands in case of
|
||||
# superchannel closed packing.
|
||||
nb_of_channels = 0
|
||||
# order slots
|
||||
slots = sorted(params['effective_freq_slot'], key=lambda x: float('inf') if x['N'] is None else x['N'])
|
||||
for slot in slots:
|
||||
nb_of_channels = nb_of_channels + slot['M'] // per_channel_m if slot['M'] is not None \
|
||||
and nb_of_channels is not None else None
|
||||
if slot['M'] is not None and slot['M'] < per_channel_m:
|
||||
msg = f'Requested M {slot} number of slots for request' +\
|
||||
f' {params["request_id"]} should be greater than {per_channel_m} to support request' +\
|
||||
f'with {params["trx_type"]} {params["trx_mode"]}'
|
||||
_logger.critical(msg)
|
||||
if nb_of_channels is not None and nb_of_channels < required_nb_of_channels:
|
||||
msg = f'Requested M {slots} number of slots for request {params["request_id"]} support {nb_of_channels}' +\
|
||||
f' nb of channels while {required_nb_of_channels} are required to support request' +\
|
||||
f' {params["path_bandwidth"] * 1e-9} Gbit/s with {params["trx_type"]} {params["trx_mode"]}'
|
||||
raise ServiceError(msg)
|
||||
if nb_of_channels is not None:
|
||||
_, stop0n = mvalue_to_slots(slots[0]['N'], slots[0]['M'])
|
||||
i = 1
|
||||
while i < len(slots):
|
||||
slot = slots[i]
|
||||
startn, stopn = mvalue_to_slots(slot['N'], slot['M'])
|
||||
if startn <= stop0n:
|
||||
msg = f'Requested M {slots} for request {params["request_id"]} overlap'
|
||||
raise ServiceError(msg)
|
||||
_, stop0n = startn, stopn
|
||||
i += 1
|
||||
|
||||
|
||||
def disjunctions_from_json(json_data):
|
||||
""" reads the disjunction requests from the json dict and create the list
|
||||
of requested disjunctions for this set of requests
|
||||
"""reads the disjunction requests from the json dict and create the list
|
||||
of requested disjunctions for this set of requests
|
||||
"""
|
||||
disjunctions_list = []
|
||||
if 'synchronization' in json_data:
|
||||
@@ -538,3 +720,42 @@ def convert_service_sheet(
|
||||
data = read_service_sheet(input_filename, eqpt, network, network_filename, bidir)
|
||||
save_json(data, output_filename)
|
||||
return data
|
||||
|
||||
|
||||
def find_equalisation(params, equalization_types):
|
||||
"""Find the equalization(s) defined in params. params can be a dict or a Roadm object.
|
||||
|
||||
>>> roadm = {'add_drop_osnr': 100, 'pmd': 1, 'pdl': 0.5,
|
||||
... 'restrictions': {'preamp_variety_list': ['a'], 'booster_variety_list': ['b']},
|
||||
... 'target_psd_out_mWperGHz': 4e-4}
|
||||
>>> equalization_types = ['target_pch_out_db', 'target_psd_out_mWperGHz']
|
||||
>>> find_equalisation(roadm, equalization_types)
|
||||
{'target_pch_out_db': False, 'target_psd_out_mWperGHz': True}
|
||||
"""
|
||||
equalization = {e: False for e in equalization_types}
|
||||
for equ in equalization_types:
|
||||
if equ in params:
|
||||
equalization[equ] = True
|
||||
return equalization
|
||||
|
||||
|
||||
def merge_equalization(params, extra_params):
|
||||
"""params contains ROADM element config and extra_params default values from equipment library.
|
||||
If equalization is not defined in ROADM element use the one defined in equipment library.
|
||||
Only one type of equalization must be defined: power (target_pch_out_db) or PSD (target_psd_out_mWperGHz)
|
||||
or PSW (target_out_mWperSlotWidth)
|
||||
params and extra_params are dict
|
||||
"""
|
||||
equalization_types = ['target_pch_out_db', 'target_psd_out_mWperGHz', 'target_out_mWperSlotWidth']
|
||||
roadm_equalizations = find_equalisation(params, equalization_types)
|
||||
if sum(roadm_equalizations.values()) > 1:
|
||||
# if ROADM config contains more than one equalization type then this is an error
|
||||
return None
|
||||
if sum(roadm_equalizations.values()) == 1:
|
||||
# if ROADM config contains one equalization
|
||||
# don't use the default equalization
|
||||
return {k: v for k, v in extra_params.items() if k not in equalization_types}
|
||||
if sum(roadm_equalizations.values()) == 0:
|
||||
# If ROADM config doesn't contain any equalization type, keep the default one
|
||||
return extra_params
|
||||
return None
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
"""
|
||||
gnpy.tools.plots
|
||||
================
|
||||
|
||||
Graphs and plots usable from a CLI application
|
||||
'''
|
||||
"""
|
||||
|
||||
from matplotlib.pyplot import show, axis, figure, title, text
|
||||
from networkx import draw_networkx
|
||||
|
||||
@@ -18,7 +18,6 @@ from copy import deepcopy
|
||||
from gnpy.core.utils import db2lin
|
||||
from gnpy.core.exceptions import ServiceError
|
||||
from gnpy.core.elements import Transceiver, Roadm, Edfa, Fiber
|
||||
import gnpy.core.ansi_escapes as ansi_escapes
|
||||
from gnpy.tools.convert import corresp_names, corresp_next_node
|
||||
|
||||
SERVICES_COLUMN = 12
|
||||
@@ -68,24 +67,21 @@ class Request_element(Element):
|
||||
if [mode for mode in equipment['Transceiver'][Request.trx_type].mode if mode['format'] == Requestmode]:
|
||||
self.mode = Requestmode
|
||||
else:
|
||||
msg = f'Request Id: {self.request_id} - could not find tsp : \'{Request.trx_type}\' with mode: \'{Requestmode}\' in eqpt library \nComputation stopped.'
|
||||
# print(msg)
|
||||
logger.critical(msg)
|
||||
msg = f'Request Id: {self.request_id} - could not find tsp : \'{Request.trx_type}\' ' \
|
||||
+ f'with mode: \'{Requestmode}\' in eqpt library \nComputation stopped.'
|
||||
raise ServiceError(msg)
|
||||
else:
|
||||
Requestmode = None
|
||||
self.mode = Request.mode
|
||||
except KeyError:
|
||||
msg = f'Request Id: {self.request_id} - could not find tsp : \'{Request.trx_type}\' with mode: \'{Request.mode}\' in eqpt library \nComputation stopped.'
|
||||
# print(msg)
|
||||
logger.critical(msg)
|
||||
msg = f'Request Id: {self.request_id} - could not find tsp : \'{Request.trx_type}\' ' \
|
||||
+ f'with mode: \'{Request.mode}\' in eqpt library \nComputation stopped.'
|
||||
raise ServiceError(msg)
|
||||
# excel input are in GHz and dBm
|
||||
if Request.spacing is not None:
|
||||
self.spacing = Request.spacing * 1e9
|
||||
else:
|
||||
msg = f'Request {self.request_id} missing spacing: spacing is mandatory.\ncomputation stopped'
|
||||
logger.critical(msg)
|
||||
raise ServiceError(msg)
|
||||
if Request.power is not None:
|
||||
self.power = db2lin(Request.power) * 1e-3
|
||||
@@ -127,7 +123,7 @@ class Request_element(Element):
|
||||
'technology': 'flexi-grid',
|
||||
'trx_type': self.trx_type,
|
||||
'trx_mode': self.mode,
|
||||
'effective-freq-slot': [{'N': 'null', 'M': 'null'}],
|
||||
'effective-freq-slot': [{'N': None, 'M': None}],
|
||||
'spacing': self.spacing,
|
||||
'max-nb-of-channel': self.nb_channel,
|
||||
'output-power': self.power
|
||||
@@ -225,7 +221,7 @@ def parse_excel(input_filename):
|
||||
def parse_service_sheet(service_sheet):
|
||||
""" reads each column according to authorized fieldnames. order is not important.
|
||||
"""
|
||||
logger.info(f'Validating headers on {service_sheet.name!r}')
|
||||
logger.debug(f'Validating headers on {service_sheet.name!r}')
|
||||
# add a test on field to enable the '' field case that arises when columns on the
|
||||
# right hand side are used as comments or drawing in the excel sheet
|
||||
header = [x.value.strip() for x in service_sheet.row(4)[0:SERVICES_COLUMN]
|
||||
@@ -245,7 +241,6 @@ def parse_service_sheet(service_sheet):
|
||||
service_fieldnames = [authorized_fieldnames[e] for e in header]
|
||||
except KeyError:
|
||||
msg = f'Malformed header on Service sheet: {header} field not in {authorized_fieldnames}'
|
||||
logger.critical(msg)
|
||||
raise ValueError(msg)
|
||||
for row in all_rows(service_sheet, start=5):
|
||||
yield Request(**parse_row(row[0:SERVICES_COLUMN], service_fieldnames))
|
||||
@@ -273,15 +268,13 @@ def correct_xls_route_list(network_filename, network, pathreqlist):
|
||||
for pathreq in pathreqlist:
|
||||
# first check that source and dest are transceivers
|
||||
if pathreq.source not in transponders:
|
||||
msg = f'{ansi_escapes.red}Request: {pathreq.request_id}: could not find' +\
|
||||
f' transponder source : {pathreq.source}.{ansi_escapes.reset}'
|
||||
logger.critical(msg)
|
||||
msg = f'Request: {pathreq.request_id}: could not find' +\
|
||||
f' transponder source : {pathreq.source}.'
|
||||
raise ServiceError(msg)
|
||||
|
||||
if pathreq.destination not in transponders:
|
||||
msg = f'{ansi_escapes.red}Request: {pathreq.request_id}: could not find' +\
|
||||
f' transponder destination: {pathreq.destination}.{ansi_escapes.reset}'
|
||||
logger.critical(msg)
|
||||
msg = f'Request: {pathreq.request_id}: could not find' +\
|
||||
f' transponder destination: {pathreq.destination}.'
|
||||
raise ServiceError(msg)
|
||||
# silently pop source and dest nodes from the list if they were added by the user as first
|
||||
# and last elem in the constraints respectively. Other positions must lead to an error
|
||||
@@ -333,17 +326,16 @@ def correct_xls_route_list(network_filename, network, pathreqlist):
|
||||
# too much ambiguity, 'b' is an ila, its name can be:
|
||||
# Edfa0_fiber (a → b)-xx if next node is c or
|
||||
# Edfa0_fiber (c → b)-xx if next node is a
|
||||
msg = f'{ansi_escapes.yellow}Invalid route node specified:' +\
|
||||
f'\n\t\'{n_id}\', replaced with \'{new_n}\'{ansi_escapes.reset}'
|
||||
logger.info(msg)
|
||||
msg = f'Request {pathreq.request_id}: Invalid route node specified:' \
|
||||
+ f'\n\t\'{n_id}\', replaced with \'{new_n}\''
|
||||
logger.warning(msg)
|
||||
pathreq.nodes_list[pathreq.nodes_list.index(n_id)] = new_n
|
||||
except StopIteration:
|
||||
# shall not come in this case, unless requested direction does not exist
|
||||
msg = f'{ansi_escapes.yellow}Invalid route specified {n_id}: could' +\
|
||||
f' not decide on direction, skipped!.\nPlease add a valid' +\
|
||||
f' direction in constraints (next neighbour node){ansi_escapes.reset}'
|
||||
print(msg)
|
||||
logger.info(msg)
|
||||
msg = f'Request {pathreq.request_id}: Invalid route specified {n_id}: could' \
|
||||
+ ' not decide on direction, skipped!.\nPlease add a valid' \
|
||||
+ ' direction in constraints (next neighbour node)'
|
||||
logger.warning(msg)
|
||||
pathreq.loose_list.pop(pathreq.nodes_list.index(n_id))
|
||||
pathreq.nodes_list.remove(n_id)
|
||||
else:
|
||||
@@ -351,28 +343,24 @@ def correct_xls_route_list(network_filename, network, pathreqlist):
|
||||
# if no matching can be found in the network just ignore this constraint
|
||||
# if it is a loose constraint
|
||||
# warns the user that this node is not part of the topology
|
||||
msg = f'{ansi_escapes.yellow}Invalid node specified:\n\t\'{n_id}\'' +\
|
||||
f', could not use it as constraint, skipped!{ansi_escapes.reset}'
|
||||
print(msg)
|
||||
logger.info(msg)
|
||||
msg = f'Request {pathreq.request_id}: Invalid node specified:\n\t\'{n_id}\'' \
|
||||
+ ', could not use it as constraint, skipped!'
|
||||
logger.warning(msg)
|
||||
pathreq.loose_list.pop(pathreq.nodes_list.index(n_id))
|
||||
pathreq.nodes_list.remove(n_id)
|
||||
else:
|
||||
msg = f'{ansi_escapes.red}Could not find node:\n\t\'{n_id}\' in network' +\
|
||||
f' topology. Strict constraint can not be applied.{ansi_escapes.reset}'
|
||||
logger.critical(msg)
|
||||
msg = f'Request {pathreq.request_id}: Could not find node:\n\t\'{n_id}\' in network' \
|
||||
+ ' topology. Strict constraint can not be applied.'
|
||||
raise ServiceError(msg)
|
||||
else:
|
||||
if temp.loose_list[i] == 'LOOSE':
|
||||
print(f'{ansi_escapes.yellow}Invalid route node specified:\n\t\'{n_id}\'' +
|
||||
f' type is not supported as constraint with xls network input,' +
|
||||
f' skipped!{ansi_escapes.reset}')
|
||||
logger.warning(f'Request {pathreq.request_id}: Invalid route node specified:\n\t\'{n_id}\''
|
||||
+ ' type is not supported as constraint with xls network input, skipped!')
|
||||
pathreq.loose_list.pop(pathreq.nodes_list.index(n_id))
|
||||
pathreq.nodes_list.remove(n_id)
|
||||
else:
|
||||
msg = f'{ansi_escapes.red}Invalid route node specified \n\t\'{n_id}\'' +\
|
||||
f' type is not supported as constraint with xls network input,' +\
|
||||
f', Strict constraint can not be applied.{ansi_escapes.reset}'
|
||||
logger.critical(msg)
|
||||
msg = f'Invalid route node specified \n\t\'{n_id}\'' \
|
||||
+ ' type is not supported as constraint with xls network input,' \
|
||||
+ ', Strict constraint can not be applied.'
|
||||
raise ServiceError(msg)
|
||||
return pathreqlist
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
'''
|
||||
"""
|
||||
Tracking :py:mod:`.request` for spectrum and their :py:mod:`.spectrum_assignment`.
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -20,30 +20,29 @@ from logging import getLogger
|
||||
from networkx import (dijkstra_path, NetworkXNoPath,
|
||||
all_simple_paths, shortest_simple_paths)
|
||||
from networkx.utils import pairwise
|
||||
from numpy import mean
|
||||
from numpy import mean, argmin
|
||||
from gnpy.core.elements import Transceiver, Roadm
|
||||
from gnpy.core.utils import lin2db
|
||||
from gnpy.core.info import create_input_spectral_information
|
||||
from gnpy.core.info import create_input_spectral_information, carriers_to_spectral_information
|
||||
from gnpy.core import network as network_module
|
||||
from gnpy.core.exceptions import ServiceError, DisjunctionError
|
||||
import gnpy.core.ansi_escapes as ansi_escapes
|
||||
from copy import deepcopy
|
||||
from csv import writer
|
||||
from math import ceil
|
||||
|
||||
LOGGER = getLogger(__name__)
|
||||
|
||||
RequestParams = namedtuple('RequestParams', 'request_id source destination bidir trx_type' +
|
||||
' trx_mode nodes_list loose_list spacing power nb_channel f_min' +
|
||||
' f_max format baud_rate OSNR bit_rate roll_off tx_osnr' +
|
||||
' min_spacing cost path_bandwidth')
|
||||
DisjunctionParams = namedtuple('DisjunctionParams', 'disjunction_id relaxable link' +
|
||||
'_diverse node_diverse disjunctions_req')
|
||||
RequestParams = namedtuple('RequestParams', 'request_id source destination bidir trx_type'
|
||||
' trx_mode nodes_list loose_list spacing power nb_channel f_min'
|
||||
' f_max format baud_rate OSNR penalties bit_rate'
|
||||
' roll_off tx_osnr min_spacing cost path_bandwidth effective_freq_slot'
|
||||
' equalization_offset_db, tx_power')
|
||||
DisjunctionParams = namedtuple('DisjunctionParams', 'disjunction_id relaxable link_diverse'
|
||||
' node_diverse disjunctions_req')
|
||||
|
||||
|
||||
class PathRequest:
|
||||
""" the class that contains all attributes related to a request
|
||||
"""
|
||||
|
||||
"""the class that contains all attributes related to a request"""
|
||||
def __init__(self, *args, **params):
|
||||
params = RequestParams(**params)
|
||||
self.request_id = params.request_id
|
||||
@@ -62,12 +61,19 @@ class PathRequest:
|
||||
self.f_max = params.f_max
|
||||
self.format = params.format
|
||||
self.OSNR = params.OSNR
|
||||
self.penalties = params.penalties
|
||||
self.bit_rate = params.bit_rate
|
||||
self.roll_off = params.roll_off
|
||||
self.tx_osnr = params.tx_osnr
|
||||
self.tx_power = params.tx_power
|
||||
self.min_spacing = params.min_spacing
|
||||
self.cost = params.cost
|
||||
self.path_bandwidth = params.path_bandwidth
|
||||
if params.effective_freq_slot is not None:
|
||||
self.N = [s['N'] for s in params.effective_freq_slot]
|
||||
self.M = [s['M'] for s in params.effective_freq_slot]
|
||||
self.initial_spectrum = None
|
||||
self.offset_db = params.equalization_offset_db
|
||||
|
||||
def __str__(self):
|
||||
return '\n\t'.join([f'{type(self).__name__} {self.request_id}',
|
||||
@@ -75,7 +81,7 @@ class PathRequest:
|
||||
f'destination: {self.destination}'])
|
||||
|
||||
def __repr__(self):
|
||||
if self.baud_rate is not None:
|
||||
if self.baud_rate is not None and self.bit_rate is not None:
|
||||
temp = self.baud_rate * 1e-9
|
||||
temp2 = self.bit_rate * 1e-9
|
||||
else:
|
||||
@@ -90,7 +96,8 @@ class PathRequest:
|
||||
f'baud_rate:\t{temp} Gbaud',
|
||||
f'bit_rate:\t{temp2} Gb/s',
|
||||
f'spacing:\t{self.spacing * 1e-9} GHz',
|
||||
f'power: \t{round(lin2db(self.power)+30, 2)} dBm',
|
||||
f'power: \t{round(lin2db(self.power) + 30, 2)} dBm',
|
||||
f'tx_power_dbm: \t{round(lin2db(self.tx_power) + 30, 2)} dBm',
|
||||
f'nb channels: \t{self.nb_channel}',
|
||||
f'path_bandwidth: \t{round(self.path_bandwidth * 1e-9, 2)} Gbit/s',
|
||||
f'nodes-list:\t{self.nodes_list}',
|
||||
@@ -99,8 +106,7 @@ class PathRequest:
|
||||
|
||||
|
||||
class Disjunction:
|
||||
""" the class that contains all attributes related to disjunction constraints
|
||||
"""
|
||||
"""the class that contains all attributes related to disjunction constraints"""
|
||||
|
||||
def __init__(self, *args, **params):
|
||||
params = DisjunctionParams(**params)
|
||||
@@ -129,7 +135,7 @@ BLOCKING_NOPATH = ['NO_PATH', 'NO_PATH_WITH_CONSTRAINT',
|
||||
'NO_FEASIBLE_BAUDRATE_WITH_SPACING',
|
||||
'NO_COMPUTED_SNR']
|
||||
BLOCKING_NOMODE = ['NO_FEASIBLE_MODE', 'MODE_NOT_FEASIBLE']
|
||||
BLOCKING_NOSPECTRUM = 'NO_SPECTRUM'
|
||||
BLOCKING_NOSPECTRUM = ['NO_SPECTRUM', 'NOT_ENOUGH_RESERVED_SPECTRUM']
|
||||
|
||||
|
||||
class ResultElement:
|
||||
@@ -145,8 +151,7 @@ class ResultElement:
|
||||
|
||||
@property
|
||||
def detailed_path_json(self):
|
||||
""" a function that builds path object for normal and blocking cases
|
||||
"""
|
||||
"""a function that builds path object for normal and blocking cases"""
|
||||
index = 0
|
||||
pro_list = []
|
||||
for element in self.computed_path:
|
||||
@@ -162,24 +167,30 @@ class ResultElement:
|
||||
}
|
||||
pro_list.append(temp)
|
||||
index += 1
|
||||
if self.path_request.M > 0:
|
||||
if not hasattr(self.path_request, 'blocking_reason'):
|
||||
# M and N values should not be None at this point
|
||||
if self.path_request.M is None or self.path_request.N is None:
|
||||
raise ServiceError('request {self.path_id} should have positive non null n and m values.')
|
||||
|
||||
temp = {
|
||||
'path-route-object': {
|
||||
'index': index,
|
||||
"label-hop": {
|
||||
"N": self.path_request.N,
|
||||
"M": self.path_request.M
|
||||
},
|
||||
"label-hop": [{
|
||||
"N": n,
|
||||
"M": m
|
||||
} for n, m in zip(self.path_request.N, self.path_request.M)],
|
||||
}
|
||||
}
|
||||
pro_list.append(temp)
|
||||
index += 1
|
||||
elif self.path_request.M == 0 and hasattr(self.path_request, 'blocking_reason'):
|
||||
# if the path is blocked due to spectrum, no label object is created, but
|
||||
# the json response includes a detailed path for user infromation.
|
||||
pass
|
||||
else:
|
||||
raise ServiceError('request {self.path_id} should have positive path bandwidth value.')
|
||||
# if the path is blocked, no label object is created, but
|
||||
# the json response includes a detailed path for user information.
|
||||
# M and N values should be None at this point
|
||||
if self.path_request.M is not None or self.path_request.N is not None:
|
||||
raise ServiceError('request {self.path_id} should not have label M and N values at this point.')
|
||||
|
||||
|
||||
if isinstance(element, Transceiver):
|
||||
temp = {
|
||||
'path-route-object': {
|
||||
@@ -196,11 +207,9 @@ class ResultElement:
|
||||
|
||||
@property
|
||||
def path_properties(self):
|
||||
""" a function that returns the path properties (metrics, crossed elements) into a dict
|
||||
"""
|
||||
"""a function that returns the path properties (metrics, crossed elements) into a dict"""
|
||||
def path_metric(pth, req):
|
||||
""" creates the metrics dictionary
|
||||
"""
|
||||
"""creates the metrics dictionary"""
|
||||
return [
|
||||
{
|
||||
'metric-type': 'SNR-bandwidth',
|
||||
@@ -242,8 +251,7 @@ class ResultElement:
|
||||
|
||||
@property
|
||||
def pathresult(self):
|
||||
""" create the result dictionnary (response for a request)
|
||||
"""
|
||||
"""create the result dictionnary (response for a request)"""
|
||||
try:
|
||||
if self.path_request.blocking_reason in BLOCKING_NOPATH:
|
||||
response = {
|
||||
@@ -281,7 +289,6 @@ def compute_constrained_path(network, req):
|
||||
# been corrected and harmonized before
|
||||
msg = (f'Request {req.request_id} malformed list of nodes: last node should '
|
||||
'be destination trx')
|
||||
LOGGER.critical(msg)
|
||||
raise ValueError()
|
||||
|
||||
trx = [n for n in network if isinstance(n, Transceiver)]
|
||||
@@ -296,10 +303,9 @@ def compute_constrained_path(network, req):
|
||||
path_generator = shortest_simple_paths(network, source, destination, weight='weight')
|
||||
total_path = next(path for path in path_generator if ispart(nodes_list, path))
|
||||
except NetworkXNoPath:
|
||||
msg = (f'{ansi_escapes.yellow}Request {req.request_id} could not find a path from'
|
||||
f' {source.uid} to node: {destination.uid} in network topology{ansi_escapes.reset}')
|
||||
msg = (f'Request {req.request_id} could not find a path from'
|
||||
f' {source.uid} to node: {destination.uid} in network topology')
|
||||
LOGGER.critical(msg)
|
||||
print(msg)
|
||||
req.blocking_reason = 'NO_PATH'
|
||||
total_path = []
|
||||
except StopIteration:
|
||||
@@ -308,80 +314,94 @@ def compute_constrained_path(network, req):
|
||||
# last node which is the transceiver)
|
||||
# if all nodes i n node_list are LOOSE constraint, skip the constraints and find
|
||||
# a path w/o constraints, else there is no possible path
|
||||
print(f'{ansi_escapes.yellow}Request {req.request_id} could not find a path crossing '
|
||||
f'{[el.uid for el in nodes_list[:-1]]} in network topology{ansi_escapes.reset}')
|
||||
LOGGER.warning(f'Request {req.request_id} could not find a path crossing '
|
||||
f'{[el.uid for el in nodes_list[:-1]]} in network topology')
|
||||
|
||||
if 'STRICT' not in req.loose_list[:-1]:
|
||||
msg = (f'{ansi_escapes.yellow}Request {req.request_id} could not find a path with user_'
|
||||
f'include node constraints{ansi_escapes.reset}')
|
||||
LOGGER.info(msg)
|
||||
print(f'constraint ignored')
|
||||
msg = (f'Request {req.request_id} could not find a path with user_'
|
||||
f'include node constraints. Constraint ignored')
|
||||
LOGGER.warning(msg)
|
||||
total_path = dijkstra_path(network, source, destination, weight='weight')
|
||||
else:
|
||||
# one STRICT makes the whole list STRICT
|
||||
msg = (f'{ansi_escapes.yellow}Request {req.request_id} could not find a path with user '
|
||||
f'include node constraints.\nNo path computed{ansi_escapes.reset}')
|
||||
msg = (f'Request {req.request_id} could not find a path with user '
|
||||
f'include node constraints.\nNo path computed')
|
||||
LOGGER.critical(msg)
|
||||
print(msg)
|
||||
req.blocking_reason = 'NO_PATH_WITH_CONSTRAINT'
|
||||
total_path = []
|
||||
|
||||
return total_path
|
||||
|
||||
|
||||
def propagate(path, req, equipment):
|
||||
si = create_input_spectral_information(
|
||||
req.f_min, req.f_max, req.roll_off, req.baud_rate,
|
||||
req.power, req.spacing)
|
||||
"""propagates signals in each element according to initial spectrum set by user"""
|
||||
if req.initial_spectrum is not None:
|
||||
si = carriers_to_spectral_information(initial_spectrum=req.initial_spectrum, power=req.power)
|
||||
else:
|
||||
si = create_input_spectral_information(
|
||||
f_min=req.f_min, f_max=req.f_max, roll_off=req.roll_off, baud_rate=req.baud_rate,
|
||||
spacing=req.spacing, tx_osnr=req.tx_osnr, tx_power=req.tx_power, delta_pdb=req.offset_db)
|
||||
roadm_osnr = []
|
||||
for i, el in enumerate(path):
|
||||
if isinstance(el, Roadm):
|
||||
si = el(si, degree=path[i+1].uid)
|
||||
si = el(si, degree=path[i + 1].uid, from_degree=path[i - 1].uid)
|
||||
roadm_osnr.append(el.get_roadm_path(from_degree=path[i - 1].uid, to_degree=path[i + 1].uid).impairment.osnr)
|
||||
else:
|
||||
si = el(si)
|
||||
path[0].update_snr(req.tx_osnr)
|
||||
if any(isinstance(el, Roadm) for el in path):
|
||||
path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
|
||||
else:
|
||||
path[-1].update_snr(req.tx_osnr)
|
||||
path[0].update_snr(si.tx_osnr)
|
||||
path[0].calc_penalties(req.penalties)
|
||||
roadm_osnr.append(si.tx_osnr)
|
||||
path[-1].update_snr(*roadm_osnr)
|
||||
path[-1].calc_penalties(req.penalties)
|
||||
return si
|
||||
|
||||
|
||||
def propagate_and_optimize_mode(path, req, equipment):
|
||||
# if mode is unknown : loops on the modes starting from the highest baudrate fiting in the
|
||||
# step 1: create an ordered list of modes based on baudrate
|
||||
baudrate_to_explore = list(set([this_mode['baud_rate']
|
||||
for this_mode in equipment['Transceiver'][req.tsp].mode
|
||||
if float(this_mode['min_spacing']) <= req.spacing]))
|
||||
# step 1: create an ordered list of modes based on baudrate and power offset
|
||||
# order higher baudrate with higher power offset first
|
||||
baudrate_offset_to_explore = list(set([(this_mode['baud_rate'], this_mode['equalization_offset_db'])
|
||||
for this_mode in equipment['Transceiver'][req.tsp].mode
|
||||
if float(this_mode['min_spacing']) <= req.spacing]))
|
||||
# TODO be carefull on limits cases if spacing very close to req spacing eg 50.001 50.000
|
||||
baudrate_to_explore = sorted(baudrate_to_explore, reverse=True)
|
||||
if baudrate_to_explore:
|
||||
baudrate_offset_to_explore = sorted(baudrate_offset_to_explore, reverse=True)
|
||||
if baudrate_offset_to_explore:
|
||||
# at least 1 baudrate can be tested wrt spacing
|
||||
for this_br in baudrate_to_explore:
|
||||
for (this_br, this_offset) in baudrate_offset_to_explore:
|
||||
modes_to_explore = [this_mode for this_mode in equipment['Transceiver'][req.tsp].mode
|
||||
if this_mode['baud_rate'] == this_br and
|
||||
float(this_mode['min_spacing']) <= req.spacing]
|
||||
if this_mode['baud_rate'] == this_br
|
||||
and float(this_mode['min_spacing']) <= req.spacing]
|
||||
modes_to_explore = sorted(modes_to_explore,
|
||||
key=lambda x: x['bit_rate'], reverse=True)
|
||||
# print(modes_to_explore)
|
||||
key=lambda x: (x['bit_rate'], x['equalization_offset_db']), reverse=True)
|
||||
# step2: computes propagation for each baudrate: stop and select the first that passes
|
||||
# TODO: the case of roll of is not included: for now use SI one
|
||||
# TODO: the case of roll off is not included: for now use SI one
|
||||
# TODO: if the loop in mode optimization does not have a feasible path, then bugs
|
||||
spc_info = create_input_spectral_information(req.f_min, req.f_max,
|
||||
equipment['SI']['default'].roll_off,
|
||||
this_br, req.power, req.spacing)
|
||||
if req.initial_spectrum is not None:
|
||||
# this case is not yet handled: spectrum can not be defined for the path-request-run function
|
||||
# and this function is only called in this case. so coming here should not be considered yet.
|
||||
msg = f'Request: {req.request_id} contains a unexpected initial_spectrum.'
|
||||
raise ServiceError(msg)
|
||||
spc_info = create_input_spectral_information(f_min=req.f_min, f_max=req.f_max,
|
||||
roll_off=equipment['SI']['default'].roll_off,
|
||||
baud_rate=this_br, spacing=req.spacing,
|
||||
delta_pdb=this_offset, tx_osnr=req.tx_osnr,
|
||||
tx_power=req.tx_power)
|
||||
roadm_osnr = []
|
||||
for i, el in enumerate(path):
|
||||
if isinstance(el, Roadm):
|
||||
spc_info = el(spc_info, degree=path[i+1].uid)
|
||||
spc_info = el(spc_info, degree=path[i + 1].uid, from_degree=path[i - 1].uid)
|
||||
roadm_osnr.append(el.get_roadm_path(from_degree=path[i - 1].uid, to_degree=path[i + 1].uid).impairment.osnr)
|
||||
else:
|
||||
spc_info = el(spc_info)
|
||||
for this_mode in modes_to_explore:
|
||||
if path[-1].snr is not None:
|
||||
path[0].update_snr(this_mode['tx_osnr'])
|
||||
if any(isinstance(el, Roadm) for el in path):
|
||||
path[-1].update_snr(this_mode['tx_osnr'], equipment['Roadm']['default'].add_drop_osnr)
|
||||
else:
|
||||
path[-1].update_snr(this_mode['tx_osnr'])
|
||||
if round(min(path[-1].snr + lin2db(this_br / (12.5e9))), 2) \
|
||||
path[0].calc_penalties(this_mode['penalties'])
|
||||
roadm_osnr.append(this_mode['tx_osnr'])
|
||||
path[-1].update_snr(*roadm_osnr)
|
||||
# remove the tx_osnr from roadm_osnr list for the next iteration
|
||||
del roadm_osnr[-1]
|
||||
path[-1].calc_penalties(this_mode['penalties'])
|
||||
if round(min(path[-1].snr_01nm - path[-1].total_penalty), 2) \
|
||||
> this_mode['OSNR'] + equipment['SI']['default'].sys_margins:
|
||||
return path, this_mode
|
||||
else:
|
||||
@@ -389,27 +409,23 @@ def propagate_and_optimize_mode(path, req, equipment):
|
||||
else:
|
||||
req.blocking_reason = 'NO_COMPUTED_SNR'
|
||||
return path, None
|
||||
|
||||
# only get to this point if no baudrate/mode satisfies OSNR requirement
|
||||
|
||||
# returns the last propagated path and mode
|
||||
msg = f'\tWarning! Request {req.request_id}: no mode satisfies path SNR requirement.\n'
|
||||
print(msg)
|
||||
LOGGER.info(msg)
|
||||
LOGGER.warning(msg)
|
||||
req.blocking_reason = 'NO_FEASIBLE_MODE'
|
||||
return path, last_explored_mode
|
||||
else:
|
||||
# no baudrate satisfying spacing
|
||||
msg = f'\tWarning! Request {req.request_id}: no baudrate satisfies spacing requirement.\n'
|
||||
print(msg)
|
||||
LOGGER.info(msg)
|
||||
LOGGER.warning(msg)
|
||||
req.blocking_reason = 'NO_FEASIBLE_BAUDRATE_WITH_SPACING'
|
||||
return [], None
|
||||
|
||||
|
||||
def jsontopath_metric(path_metric):
|
||||
""" a functions that reads resulting metric from json string
|
||||
"""
|
||||
"""a functions that reads resulting metric from json string"""
|
||||
output_snr = next(e['accumulative-value']
|
||||
for e in path_metric if e['metric-type'] == 'SNR-0.1nm')
|
||||
output_snrbandwidth = next(e['accumulative-value']
|
||||
@@ -427,9 +443,7 @@ def jsontopath_metric(path_metric):
|
||||
|
||||
|
||||
def jsontoparams(my_p, tsp, mode, equipment):
|
||||
""" a function that derives optical params from transponder type and mode
|
||||
supports the no mode case
|
||||
"""
|
||||
"""a function that derives optical params from transponder type and mode supports the no mode case"""
|
||||
temp = []
|
||||
for elem in my_p['path-properties']['path-route-objects']:
|
||||
if 'num-unnum-hop' in elem['path-route-object']:
|
||||
@@ -439,8 +453,8 @@ def jsontoparams(my_p, tsp, mode, equipment):
|
||||
temp2 = []
|
||||
for elem in my_p['path-properties']['path-route-objects']:
|
||||
if 'label-hop' in elem['path-route-object'].keys():
|
||||
temp2.append(f'{elem["path-route-object"]["label-hop"]["N"]}, ' +
|
||||
f'{elem["path-route-object"]["label-hop"]["M"]}')
|
||||
temp2.append(f'{[e["N"] for e in elem["path-route-object"]["label-hop"]]}, '
|
||||
+ f'{[e["M"] for e in elem["path-route-object"]["label-hop"]]}')
|
||||
# OrderedDict.fromkeys returns the unique set of strings.
|
||||
# TODO: if spectrum changes along the path, we should be able to give the segments
|
||||
# eg for regeneration case
|
||||
@@ -464,10 +478,10 @@ def jsontoparams(my_p, tsp, mode, equipment):
|
||||
|
||||
|
||||
def jsontocsv(json_data, equipment, fileout):
|
||||
""" reads json path result file in accordance with:
|
||||
Yang model for requesting Path Computation
|
||||
draft-ietf-teas-yang-path-computation-01.txt.
|
||||
and write results in an CSV file
|
||||
"""reads json path result file in accordance with:
|
||||
Yang model for requesting Path Computation
|
||||
draft-ietf-teas-yang-path-computation-01.txt.
|
||||
and write results in an CSV file
|
||||
"""
|
||||
mywriter = writer(fileout)
|
||||
mywriter.writerow(('response-id', 'source', 'destination', 'path_bandwidth', 'Pass?',
|
||||
@@ -696,8 +710,8 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
||||
# in each loop, dpath is updated with a path for rq that satisfies
|
||||
# disjunction with each path in dpath
|
||||
# for example, assume set of requests in the vector (disjunction_list) is {rq1,rq2, rq3}
|
||||
# rq1 p1: abfhg
|
||||
# p2: aefhg
|
||||
# rq1 p1: aefhg
|
||||
# p2: abfhg
|
||||
# p3: abcg
|
||||
# rq2 p8: bf
|
||||
# rq3 p4: abcgh
|
||||
@@ -714,6 +728,7 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
||||
# after second loop:
|
||||
# dpath = [ p3 p8 p6 ]
|
||||
# since p1 and p4 are not disjoint
|
||||
# p1 and p6 are not disjoint
|
||||
# p1 and p7 are not disjoint
|
||||
# p3 and p4 are not disjoint
|
||||
# p3 and p7 are not disjoint
|
||||
@@ -737,7 +752,6 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
||||
temp.append(temp2)
|
||||
# print(f' coucou {elem1}: \t{temp}')
|
||||
dpath = temp
|
||||
# print(dpath)
|
||||
candidates[dis.disjunction_id] = dpath
|
||||
|
||||
# for i in disjunctions_list:
|
||||
@@ -778,9 +792,9 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
||||
if pth in cndt:
|
||||
candidates[this_id].remove(cndt)
|
||||
|
||||
# for i in disjunctions_list:
|
||||
# print(i.disjunction_id)
|
||||
# print(f'\n{candidates[i.disjunction_id]}')
|
||||
# for i in disjunctions_list:
|
||||
# print(i.disjunction_id)
|
||||
# print(f'\n{candidates[i.disjunction_id]}')
|
||||
|
||||
# step 4 apply route constraints: remove candidate path that do not satisfy
|
||||
# the constraint only in the case of disjounction: the simple path is processed in
|
||||
@@ -788,33 +802,34 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
||||
# TODO: keep a version without the loose constraint
|
||||
for this_d in disjunctions_list:
|
||||
temp = []
|
||||
alternatetemp = []
|
||||
for j, sol in enumerate(candidates[this_d.disjunction_id]):
|
||||
testispartok = True
|
||||
testispartnokloose = True
|
||||
for pth in sol:
|
||||
# print(f'test {allpaths[id(pth)].req.request_id}')
|
||||
# print(f'length of route {len(allpaths[id(pth)].req.nodes_list)}')
|
||||
if allpaths[id(pth)].req.nodes_list:
|
||||
# if pth does not containt the ordered list node, remove sol from the candidate
|
||||
# except if this was the last solution: then check if the constraint is loose
|
||||
# or not
|
||||
# if any pth from sol does not contain the ordered list node,
|
||||
# remove sol from the candidate, except if constraint was loose:
|
||||
# then keep sol as an alternate solution
|
||||
if not ispart(allpaths[id(pth)].req.nodes_list, pth):
|
||||
# print(f'nb of solutions {len(temp)}')
|
||||
if j < len(candidates[this_d.disjunction_id]) - 1:
|
||||
msg = f'removing {sol}'
|
||||
LOGGER.info(msg)
|
||||
testispartok = False
|
||||
# break
|
||||
else:
|
||||
if 'LOOSE' in allpaths[id(pth)].req.loose_list:
|
||||
LOGGER.info(f'Could not apply route constraint' +
|
||||
f'{allpaths[id(pth)].req.nodes_list} on request' +
|
||||
f' {allpaths[id(pth)].req.request_id}')
|
||||
else:
|
||||
LOGGER.info(f'removing last solution from candidate paths\n{sol}')
|
||||
testispartok = False
|
||||
testispartok = False
|
||||
if 'STRICT' in allpaths[id(pth)].req.loose_list:
|
||||
LOGGER.debug(f'removing solution from candidate paths\n{pth}')
|
||||
testispartnokloose = False
|
||||
break
|
||||
if testispartok:
|
||||
temp.append(sol)
|
||||
candidates[this_d.disjunction_id] = temp
|
||||
elif testispartnokloose:
|
||||
LOGGER.debug(f'Adding solution as alternate solution not satisfying constraint\n{pth}')
|
||||
alternatetemp.append(sol)
|
||||
if temp:
|
||||
candidates[this_d.disjunction_id] = temp
|
||||
elif alternatetemp:
|
||||
candidates[this_d.disjunction_id] = alternatetemp
|
||||
else:
|
||||
candidates[this_d.disjunction_id] = []
|
||||
|
||||
# step 5 select the first combination that works
|
||||
pathreslist_disjoint = {}
|
||||
@@ -829,9 +844,7 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
||||
# remove duplicated candidates
|
||||
candidates = remove_candidate(candidates, allpaths, allpaths[id(pth)].req, pth)
|
||||
else:
|
||||
msg = f'No disjoint path found with added constraint'
|
||||
LOGGER.critical(msg)
|
||||
print(f'{msg}\nComputation stopped.')
|
||||
msg = 'No disjoint path found with added constraint\nComputation stopped.'
|
||||
# TODO in this case: replay step 5 with the candidate without constraints
|
||||
raise DisjunctionError(msg)
|
||||
|
||||
@@ -852,8 +865,7 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
||||
|
||||
|
||||
def isdisjoint(pth1, pth2):
|
||||
""" returns 0 if disjoint
|
||||
"""
|
||||
"""returns 0 if disjoint"""
|
||||
edge1 = list(pairwise(pth1))
|
||||
edge2 = list(pairwise(pth2))
|
||||
for edge in edge1:
|
||||
@@ -863,9 +875,9 @@ def isdisjoint(pth1, pth2):
|
||||
|
||||
|
||||
def find_reversed_path(pth):
|
||||
""" select of intermediate roadms and find the path between them
|
||||
note that this function may not give an exact result in case of multiple
|
||||
links between two adjacent nodes.
|
||||
"""select of intermediate roadms and find the path between them
|
||||
note that this function may not give an exact result in case of multiple
|
||||
links between two adjacent nodes.
|
||||
"""
|
||||
# TODO add some indication on elements to indicate from which other they
|
||||
# are the reversed direction. This is partly done with oms indication
|
||||
@@ -888,9 +900,8 @@ def find_reversed_path(pth):
|
||||
# concatenation should be [roadma el1 el2 roadmb el3 el4 roadmc]
|
||||
reversed_path = list(OrderedDict.fromkeys(reversed_path))
|
||||
else:
|
||||
msg = f'Error while handling reversed path {pth[-1].uid} to {pth[0].uid}:' +\
|
||||
' can not handle unidir topology. TO DO.'
|
||||
LOGGER.critical(msg)
|
||||
msg = f'Error while handling reversed path {pth[-1].uid} to {pth[0].uid}:' \
|
||||
+ ' can not handle unidir topology. TO DO.'
|
||||
raise ValueError(msg)
|
||||
reversed_path.append(pth[0])
|
||||
|
||||
@@ -898,9 +909,7 @@ def find_reversed_path(pth):
|
||||
|
||||
|
||||
def ispart(ptha, pthb):
|
||||
""" the functions takes two paths a and b and retrns True
|
||||
if all a elements are part of b and in the same order
|
||||
"""
|
||||
"""the functions takes two paths a and b and retrns True if all a elements are part of b and in the same order"""
|
||||
j = 0
|
||||
for elem in ptha:
|
||||
if elem in pthb:
|
||||
@@ -914,8 +923,7 @@ def ispart(ptha, pthb):
|
||||
|
||||
|
||||
def remove_candidate(candidates, allpaths, rqst, pth):
|
||||
""" filter duplicate candidates
|
||||
"""
|
||||
"""filter duplicate candidates"""
|
||||
# print(f'coucou {rqst.request_id}')
|
||||
for key, candidate in candidates.items():
|
||||
temp = candidate.copy()
|
||||
@@ -930,8 +938,7 @@ def remove_candidate(candidates, allpaths, rqst, pth):
|
||||
|
||||
|
||||
def compare_reqs(req1, req2, disjlist):
|
||||
""" compare two requests: returns True or False
|
||||
"""
|
||||
"""compare two requests: returns True or False"""
|
||||
dis1 = [d for d in disjlist if req1.request_id in d.disjunctions_req]
|
||||
dis2 = [d for d in disjlist if req2.request_id in d.disjunctions_req]
|
||||
same_disj = False
|
||||
@@ -964,6 +971,7 @@ def compare_reqs(req1, req2, disjlist):
|
||||
req1.format == req2.format and \
|
||||
req1.OSNR == req2.OSNR and \
|
||||
req1.roll_off == req2.roll_off and \
|
||||
req1.tx_power == req2.tx_power and \
|
||||
same_disj:
|
||||
return True
|
||||
else:
|
||||
@@ -971,19 +979,24 @@ def compare_reqs(req1, req2, disjlist):
|
||||
|
||||
|
||||
def requests_aggregation(pathreqlist, disjlist):
|
||||
""" this function aggregates requests so that if several requests
|
||||
exist between same source and destination and with same transponder type
|
||||
"""this function aggregates requests so that if several requests
|
||||
exist between same source and destination and with same transponder type
|
||||
If transponder mode is defined and identical, then also agregates demands.
|
||||
"""
|
||||
# todo maybe add conditions on mode ??, spacing ...
|
||||
# currently if undefined takes the default values
|
||||
local_list = pathreqlist.copy()
|
||||
for req in pathreqlist:
|
||||
for this_r in local_list:
|
||||
if req.request_id != this_r.request_id and compare_reqs(req, this_r, disjlist):
|
||||
if req.request_id != this_r.request_id and compare_reqs(req, this_r, disjlist) and\
|
||||
this_r.tsp_mode is not None:
|
||||
# aggregate
|
||||
this_r.path_bandwidth += req.path_bandwidth
|
||||
this_r.N = this_r.N + req.N
|
||||
this_r.M = this_r.M + req.M
|
||||
temp_r_id = this_r.request_id
|
||||
this_r.request_id = ' | '.join((this_r.request_id, req.request_id))
|
||||
|
||||
# remove request from list
|
||||
local_list.remove(req)
|
||||
# todo change also disjunction req with new demand
|
||||
@@ -1000,23 +1013,22 @@ def requests_aggregation(pathreqlist, disjlist):
|
||||
|
||||
|
||||
def correct_json_route_list(network, pathreqlist):
|
||||
""" all names in list should be exact name in the network, and there is no ambiguity
|
||||
This function only checks that list is correct, warns user if the name is incorrect and
|
||||
suppresses the constraint it it is loose or raises an error if it is strict
|
||||
"""all names in list should be exact name in the network, and there is no ambiguity
|
||||
|
||||
This function only checks that list is correct, warns user if the name is incorrect and
|
||||
suppresses the constraint it it is loose or raises an error if it is strict
|
||||
"""
|
||||
all_uid = [n.uid for n in network.nodes()]
|
||||
transponders = [n.uid for n in network.nodes() if isinstance(n, Transceiver)]
|
||||
for pathreq in pathreqlist:
|
||||
if pathreq.source not in transponders:
|
||||
msg = f'{ansi_escapes.red}Request: {pathreq.request_id}: could not find transponder' +\
|
||||
f' source : {pathreq.source}.{ansi_escapes.reset}'
|
||||
LOGGER.critical(msg)
|
||||
msg = f'Request: {pathreq.request_id}: could not find transponder' \
|
||||
+ f' source : {pathreq.source}.'
|
||||
raise ServiceError(msg)
|
||||
|
||||
if pathreq.destination not in transponders:
|
||||
msg = f'{ansi_escapes.red}Request: {pathreq.request_id}: could not find transponder' +\
|
||||
f' destination : {pathreq.destination}.{ansi_escapes.reset}'
|
||||
LOGGER.critical(msg)
|
||||
msg = f'Request: {pathreq.request_id}: could not find transponder' \
|
||||
+ f' destination : {pathreq.destination}.'
|
||||
raise ServiceError(msg)
|
||||
|
||||
# silently remove source and dest nodes from the list
|
||||
@@ -1035,24 +1047,21 @@ def correct_json_route_list(network, pathreqlist):
|
||||
# if no matching can be found in the network just ignore this constraint
|
||||
# if it is a loose constraint
|
||||
# warns the user that this node is not part of the topology
|
||||
msg = f'{ansi_escapes.yellow}invalid route node specified:\n\t\'{n_id}\',' +\
|
||||
f' could not use it as constraint, skipped!{ansi_escapes.reset}'
|
||||
print(msg)
|
||||
LOGGER.info(msg)
|
||||
msg = f'invalid route node specified:\n\t\'{n_id}\',' \
|
||||
+ ' could not use it as constraint, skipped!'
|
||||
LOGGER.warning(msg)
|
||||
pathreq.loose_list.pop(pathreq.nodes_list.index(n_id))
|
||||
pathreq.nodes_list.remove(n_id)
|
||||
else:
|
||||
msg = f'{ansi_escapes.red}could not find node:\n\t \'{n_id}\' in network' +\
|
||||
f' topology. Strict constraint can not be applied.{ansi_escapes.reset}'
|
||||
LOGGER.critical(msg)
|
||||
msg = f'could not find node:\n\t \'{n_id}\' in network' \
|
||||
+ ' topology. Strict constraint can not be applied.'
|
||||
raise ServiceError(msg)
|
||||
|
||||
return pathreqlist
|
||||
|
||||
|
||||
def deduplicate_disjunctions(disjn):
|
||||
""" clean disjunctions to remove possible repetition
|
||||
"""
|
||||
"""clean disjunctions to remove possible repetition"""
|
||||
local_disjn = disjn.copy()
|
||||
for elem in local_disjn:
|
||||
for dis_elem in local_disjn:
|
||||
@@ -1063,8 +1072,9 @@ def deduplicate_disjunctions(disjn):
|
||||
|
||||
|
||||
def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
""" use a list but a dictionnary might be helpful to find path based on request_id
|
||||
TODO change all these req, dsjct, res lists into dict !
|
||||
"""use a list but a dictionnary might be helpful to find path based on request_id
|
||||
|
||||
TODO change all these req, dsjct, res lists into dict !
|
||||
"""
|
||||
path_res_list = []
|
||||
reversed_path_res_list = []
|
||||
@@ -1075,10 +1085,10 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
# use the power specified in requests but might be different from the one
|
||||
# specified for design the power is an optional parameter for requests
|
||||
# definition if optional, use the one defines in eqt_config.json
|
||||
print(f'request {pathreq.request_id}')
|
||||
print(f'Computing path from {pathreq.source} to {pathreq.destination}')
|
||||
# adding first node to be clearer on the output
|
||||
print(f'with path constraint: {[pathreq.source] + pathreq.nodes_list}')
|
||||
msg = f'\n\trequest {pathreq.request_id}\n' \
|
||||
+ f'\tComputing path from {pathreq.source} to {pathreq.destination}\n' \
|
||||
+ f'\twith path constraint: {[pathreq.source] + pathreq.nodes_list}'
|
||||
# # adding first node to be clearer on the output
|
||||
|
||||
# pathlist[i] contains the whole path information for request i
|
||||
# last element is a transciver and where the result of the propagation is
|
||||
@@ -1087,8 +1097,10 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
# elements to simulate performance, several demands having the same destination
|
||||
# may use the same transponder for the performance simulation. This is why
|
||||
# we use deepcopy: to ensure that each propagation is recorded and not overwritten
|
||||
network_module.design_network(pathreq, network, equipment, set_connector_losses=False, verbose=False)
|
||||
total_path = deepcopy(pathlist[i])
|
||||
print(f'Computed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}')
|
||||
msg = msg + f'\n\tComputed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}'
|
||||
LOGGER.info(msg)
|
||||
# for debug
|
||||
# print(f'{pathreq.baud_rate} {pathreq.power} {pathreq.spacing} {pathreq.nb_channel}')
|
||||
if total_path:
|
||||
@@ -1096,13 +1108,15 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
# means that at this point the mode was entered/forced by user and thus a
|
||||
# baud_rate was defined
|
||||
propagate(total_path, pathreq, equipment)
|
||||
temp_snr01nm = round(mean(total_path[-1].snr+lin2db(pathreq.baud_rate/(12.5e9))), 2)
|
||||
if temp_snr01nm < pathreq.OSNR + equipment['SI']['default'].sys_margins:
|
||||
msg = f'\tWarning! Request {pathreq.request_id} computed path from' +\
|
||||
f' {pathreq.source} to {pathreq.destination} does not pass with' +\
|
||||
f' {pathreq.tsp_mode}\n\tcomputedSNR in 0.1nm = {temp_snr01nm} ' +\
|
||||
f'- required osnr {pathreq.OSNR} + {equipment["SI"]["default"].sys_margins} margin'
|
||||
print(msg)
|
||||
snr01nm_with_penalty = total_path[-1].snr_01nm - total_path[-1].total_penalty
|
||||
min_ind = argmin(snr01nm_with_penalty)
|
||||
if round(snr01nm_with_penalty[min_ind], 2) < pathreq.OSNR + equipment['SI']['default'].sys_margins:
|
||||
msg = f'\tWarning! Request {pathreq.request_id} computed path from' \
|
||||
+ f' {pathreq.source} to {pathreq.destination} does not pass with {pathreq.tsp_mode}' \
|
||||
+ f'\n\tcomputed SNR in 0.1nm = {round(total_path[-1].snr_01nm[min_ind], 2)}'
|
||||
msg = _penalty_msg(total_path, msg, min_ind) \
|
||||
+ f'\n\trequired osnr = {pathreq.OSNR}' \
|
||||
+ f'\n\tsystem margin = {equipment["SI"]["default"].sys_margins}'
|
||||
LOGGER.warning(msg)
|
||||
pathreq.blocking_reason = 'MODE_NOT_FEASIBLE'
|
||||
else:
|
||||
@@ -1122,6 +1136,7 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
pathreq.OSNR = mode['OSNR']
|
||||
pathreq.tx_osnr = mode['tx_osnr']
|
||||
pathreq.bit_rate = mode['bit_rate']
|
||||
pathreq.penalties = mode['penalties']
|
||||
# other blocking reason should not appear at this point
|
||||
except AttributeError:
|
||||
pathreq.baud_rate = mode['baud_rate']
|
||||
@@ -1130,35 +1145,36 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
pathreq.OSNR = mode['OSNR']
|
||||
pathreq.tx_osnr = mode['tx_osnr']
|
||||
pathreq.bit_rate = mode['bit_rate']
|
||||
pathreq.penalties = mode['penalties']
|
||||
|
||||
# reversed path is needed for correct spectrum assignment
|
||||
reversed_path = find_reversed_path(pathlist[i])
|
||||
if pathreq.bidir and pathreq.baud_rate is not None:
|
||||
# Both directions requested, and a feasible mode was found
|
||||
rev_p = deepcopy(reversed_path)
|
||||
|
||||
print(f'\n\tPropagating Z to A direction {pathreq.destination} to {pathreq.source}')
|
||||
print(f'\tPath (roadsm) {[r.uid for r in rev_p if isinstance(r,Roadm)]}\n')
|
||||
msg = f'\n\tPropagating Z to A direction {pathreq.destination} to {pathreq.source}\n' \
|
||||
+ f'\tPath (roadms) {[r.uid for r in rev_p if isinstance(r,Roadm)]}\n'
|
||||
LOGGER.info(msg)
|
||||
propagate(rev_p, pathreq, equipment)
|
||||
propagated_reversed_path = rev_p
|
||||
temp_snr01nm = round(mean(propagated_reversed_path[-1].snr +\
|
||||
lin2db(pathreq.baud_rate/(12.5e9))), 2)
|
||||
if temp_snr01nm < pathreq.OSNR + equipment['SI']['default'].sys_margins:
|
||||
msg = f'\tWarning! Request {pathreq.request_id} computed path from' +\
|
||||
f' {pathreq.source} to {pathreq.destination} does not pass with' +\
|
||||
f' {pathreq.tsp_mode}\n' +\
|
||||
f'\tcomputedSNR in 0.1nm = {temp_snr01nm} -' \
|
||||
f' required osnr {pathreq.OSNR} + {equipment["SI"]["default"].sys_margins} margin'
|
||||
print(msg)
|
||||
snr01nm_with_penalty = rev_p[-1].snr_01nm - rev_p[-1].total_penalty
|
||||
min_ind = argmin(snr01nm_with_penalty)
|
||||
if round(snr01nm_with_penalty[min_ind], 2) < pathreq.OSNR + equipment['SI']['default'].sys_margins:
|
||||
msg = f'\tWarning! Request {pathreq.request_id} computed path from' \
|
||||
+ f' {pathreq.destination} to {pathreq.source} does not pass with {pathreq.tsp_mode}' \
|
||||
+ f'\n\tcomputed SNR in 0.1nm = {round(rev_p[-1].snr_01nm[min_ind], 2)}'
|
||||
msg = _penalty_msg(rev_p, msg, min_ind) \
|
||||
+ f'\n\trequired osnr = {pathreq.OSNR}' \
|
||||
+ f'\n\tsystem margin = {equipment["SI"]["default"].sys_margins}'
|
||||
LOGGER.warning(msg)
|
||||
# TODO selection of mode should also be on reversed direction !!
|
||||
pathreq.blocking_reason = 'MODE_NOT_FEASIBLE'
|
||||
if not hasattr(pathreq, 'blocking_reason'):
|
||||
pathreq.blocking_reason = 'MODE_NOT_FEASIBLE'
|
||||
else:
|
||||
propagated_reversed_path = []
|
||||
else:
|
||||
msg = 'Total path is empty. No propagation'
|
||||
print(msg)
|
||||
LOGGER.info(msg)
|
||||
msg = f'Request {pathreq.request_id}: Total path is empty. No propagation'
|
||||
LOGGER.warning(msg)
|
||||
reversed_path = []
|
||||
propagated_reversed_path = []
|
||||
|
||||
@@ -1166,5 +1182,33 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
reversed_path_res_list.append(reversed_path)
|
||||
propagated_reversed_path_res_list.append(propagated_reversed_path)
|
||||
# print to have a nice output
|
||||
print('')
|
||||
return path_res_list, reversed_path_res_list, propagated_reversed_path_res_list
|
||||
|
||||
|
||||
def compute_spectrum_slot_vs_bandwidth(bandwidth, spacing, bit_rate, slot_width=0.0125e12):
|
||||
"""Compute the number of required wavelengths and the M value (number of consumed slots)
|
||||
|
||||
Each wavelength consumes one `spacing`, and the result is rounded up to consume a natural number of slots.
|
||||
|
||||
>>> compute_spectrum_slot_vs_bandwidth(400e9, 50e9, 200e9)
|
||||
(2, 8)
|
||||
"""
|
||||
number_of_wavelengths = ceil(bandwidth / bit_rate)
|
||||
total_number_of_slots = ceil(spacing / slot_width) * number_of_wavelengths
|
||||
return number_of_wavelengths, total_number_of_slots
|
||||
|
||||
|
||||
def _penalty_msg(total_path, msg, min_ind):
|
||||
"""formatting helper for reporting unfeasible paths
|
||||
|
||||
The penalty info are optional, so this checks that penalty exists before creating a message."""
|
||||
penalty_dict = {
|
||||
'pdl': 'PDL',
|
||||
'chromatic_dispersion': 'CD',
|
||||
'pmd': 'PMD'}
|
||||
for key, pretty in penalty_dict.items():
|
||||
if key in total_path[-1].penalties:
|
||||
msg += f'\n\t{pretty} penalty = {round(total_path[-1].penalties[key][min_ind], 2)}'
|
||||
else:
|
||||
msg += f'\n\t{pretty} penalty not evaluated'
|
||||
return msg
|
||||
|
||||
@@ -15,16 +15,16 @@ element/oms correspondace
|
||||
|
||||
from collections import namedtuple
|
||||
from logging import getLogger
|
||||
from math import ceil
|
||||
from gnpy.core.elements import Roadm, Transceiver
|
||||
from gnpy.core.exceptions import ServiceError, SpectrumError
|
||||
from gnpy.core.utils import order_slots, restore_order
|
||||
from gnpy.topology.request import compute_spectrum_slot_vs_bandwidth
|
||||
|
||||
LOGGER = getLogger(__name__)
|
||||
|
||||
|
||||
class Bitmap:
|
||||
""" records the spectrum occupation
|
||||
"""
|
||||
"""records the spectrum occupation"""
|
||||
|
||||
def __init__(self, f_min, f_max, grid, guardband=0.15e12, bitmap=None):
|
||||
# n is the min index including guardband. Guardband is require to be sure
|
||||
@@ -45,26 +45,22 @@ class Bitmap:
|
||||
raise SpectrumError(f'bitmap is not consistant with f_min{f_min} - n: {n_min} and f_max{f_max}- n :{n_max}')
|
||||
|
||||
def getn(self, i):
|
||||
""" converts the n (itu grid) into a local index
|
||||
"""
|
||||
"""converts the n (itu grid) into a local index"""
|
||||
return self.freq_index[i]
|
||||
|
||||
def geti(self, nvalue):
|
||||
""" converts the local index into n (itu grid)
|
||||
"""
|
||||
"""converts the local index into n (itu grid)"""
|
||||
return self.freq_index.index(nvalue)
|
||||
|
||||
def insert_left(self, newbitmap):
|
||||
""" insert bitmap on the left to align oms bitmaps if their start frequencies are different
|
||||
"""
|
||||
"""insert bitmap on the left to align oms bitmaps if their start frequencies are different"""
|
||||
self.bitmap = newbitmap + self.bitmap
|
||||
temp = list(range(self.n_min - len(newbitmap), self.n_min))
|
||||
self.freq_index = temp + self.freq_index
|
||||
self.n_min = self.freq_index[0]
|
||||
|
||||
def insert_right(self, newbitmap):
|
||||
""" insert bitmap on the right to align oms bitmaps if their stop frequencies are different
|
||||
"""
|
||||
"""insert bitmap on the right to align oms bitmaps if their stop frequencies are different"""
|
||||
self.bitmap = self.bitmap + newbitmap
|
||||
self.freq_index = self.freq_index + list(range(self.n_max, self.n_max + len(newbitmap)))
|
||||
self.n_max = self.freq_index[-1]
|
||||
@@ -75,8 +71,8 @@ OMSParams = namedtuple('OMSParams', 'oms_id el_id_list el_list')
|
||||
|
||||
|
||||
class OMS:
|
||||
""" OMS class is the logical container that represent a link between two adjacent ROADMs and
|
||||
records the crossed elements and the occupied spectrum
|
||||
"""OMS class is the logical container that represent a link between two adjacent ROADMs and
|
||||
records the crossed elements and the occupied spectrum
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **params):
|
||||
@@ -98,36 +94,28 @@ class OMS:
|
||||
f'{self.el_id_list[0]} - {self.el_id_list[-1]}', '\n'])
|
||||
|
||||
def add_element(self, elem):
|
||||
""" records oms elements
|
||||
"""
|
||||
"""records oms elements"""
|
||||
self.el_id_list.append(elem.uid)
|
||||
self.el_list.append(elem)
|
||||
|
||||
def update_spectrum(self, f_min, f_max, guardband=0.15e12, existing_spectrum=None,
|
||||
grid=0.00625e12):
|
||||
""" frequencies expressed in Hz
|
||||
def update_spectrum(self, f_min, f_max, guardband=0.15e12, existing_spectrum=None, grid=0.00625e12):
|
||||
"""Frequencies expressed in Hz.
|
||||
Add 150 GHz margin to enable a center channel on f_min
|
||||
Use ITU-T G694.1 Flexible DWDM grid definition
|
||||
For the flexible DWDM grid, the allowed frequency slots have a nominal central frequency (in THz) defined by:
|
||||
193.1 + n × 0.00625 where n is a positive or negative integer including 0
|
||||
and 0.00625 is the nominal central frequency granularity in THz
|
||||
and a slot width defined by:
|
||||
12.5 × m where m is a positive integer and 12.5 is the slot width granularity in GHz.
|
||||
Any combination of frequency slots is allowed as long as no two frequency slots overlap.
|
||||
If bitmap is not None, then use it: Bitmap checks its consistency with f_min f_max
|
||||
else a brand new bitmap is created
|
||||
"""
|
||||
if existing_spectrum is None:
|
||||
# add some 150 GHz margin to enable a center channel on f_min
|
||||
# use ITU-T G694.1
|
||||
# Flexible DWDM grid definition
|
||||
# For the flexible DWDM grid, the allowed frequency slots have a nominal
|
||||
# central frequency (in THz) defined by:
|
||||
# 193.1 + n × 0.00625 where n is a positive or negative integer including 0
|
||||
# and 0.00625 is the nominal central frequency granularity in THz
|
||||
# and a slot width defined by:
|
||||
# 12.5 × m where m is a positive integer and 12.5 is the slot width granularity in
|
||||
# GHz.
|
||||
# Any combination of frequency slots is allowed as long as no two frequency
|
||||
# slots overlap.
|
||||
|
||||
# TODO : add explaination on that / parametrize ....
|
||||
self.spectrum_bitmap = Bitmap(f_min, f_max, grid, guardband)
|
||||
# print(len(self.spectrum_bitmap.bitmap))
|
||||
self.spectrum_bitmap = Bitmap(f_min=f_min, f_max=f_max, grid=grid, guardband=guardband,
|
||||
bitmap=existing_spectrum)
|
||||
|
||||
def assign_spectrum(self, nvalue, mvalue):
|
||||
""" change oms spectrum to mark spectrum assigned
|
||||
"""
|
||||
"""change oms spectrum to mark spectrum assigned"""
|
||||
if not isinstance(nvalue, int):
|
||||
raise SpectrumError(f'N must be a signed integer, got {nvalue}')
|
||||
if not isinstance(mvalue, int):
|
||||
@@ -146,16 +134,16 @@ class OMS:
|
||||
self.spectrum_bitmap.bitmap[self.spectrum_bitmap.geti(startn):self.spectrum_bitmap.geti(stopn) + 1] = [0] * (stopn - startn + 1)
|
||||
|
||||
def add_service(self, service_id, nb_wl):
|
||||
""" record service and mark spectrum as occupied
|
||||
"""
|
||||
"""record service and mark spectrum as occupied"""
|
||||
self.service_list.append(service_id)
|
||||
self.nb_channels += nb_wl
|
||||
|
||||
|
||||
def frequency_to_n(freq, grid=0.00625e12):
|
||||
""" converts frequency into the n value (ITU grid)
|
||||
reference to Recommendation G.694.1 (02/12), Figure I.3
|
||||
https://www.itu.int/rec/T-REC-G.694.1-201202-I/en
|
||||
"""converts frequency into the n value (ITU grid)
|
||||
|
||||
reference to Recommendation G.694.1 (02/12), Figure I.3
|
||||
https://www.itu.int/rec/T-REC-G.694.1-201202-I/en
|
||||
|
||||
>>> frequency_to_n(193.1375e12)
|
||||
6
|
||||
@@ -167,9 +155,10 @@ def frequency_to_n(freq, grid=0.00625e12):
|
||||
|
||||
|
||||
def nvalue_to_frequency(nvalue, grid=0.00625e12):
|
||||
""" converts n value into a frequency
|
||||
reference to Recommendation G.694.1 (02/12), Table 1
|
||||
https://www.itu.int/rec/T-REC-G.694.1-201202-I/en
|
||||
"""converts n value into a frequency
|
||||
|
||||
reference to Recommendation G.694.1 (02/12), Table 1
|
||||
https://www.itu.int/rec/T-REC-G.694.1-201202-I/en
|
||||
|
||||
>>> nvalue_to_frequency(6)
|
||||
193137500000000.0
|
||||
@@ -181,17 +170,17 @@ def nvalue_to_frequency(nvalue, grid=0.00625e12):
|
||||
|
||||
|
||||
def mvalue_to_slots(nvalue, mvalue):
|
||||
""" convert center n an m into start and stop n
|
||||
"""
|
||||
"""convert center n an m into start and stop n"""
|
||||
startn = nvalue - mvalue
|
||||
stopn = nvalue + mvalue - 1
|
||||
return startn, stopn
|
||||
|
||||
|
||||
def slots_to_m(startn, stopn):
|
||||
""" converts the start and stop n values to the center n and m value
|
||||
reference to Recommendation G.694.1 (02/12), Figure I.3
|
||||
https://www.itu.int/rec/T-REC-G.694.1-201202-I/en
|
||||
"""converts the start and stop n values to the center n and m value
|
||||
|
||||
reference to Recommendation G.694.1 (02/12), Figure I.3
|
||||
https://www.itu.int/rec/T-REC-G.694.1-201202-I/en
|
||||
|
||||
>>> nval, mval = slots_to_m(6, 20)
|
||||
>>> nval
|
||||
@@ -206,10 +195,11 @@ def slots_to_m(startn, stopn):
|
||||
|
||||
|
||||
def m_to_freq(nvalue, mvalue, grid=0.00625e12):
|
||||
""" converts m into frequency range
|
||||
spectrum(13,7) is (193137500000000.0, 193225000000000.0)
|
||||
reference to Recommendation G.694.1 (02/12), Figure I.3
|
||||
https://www.itu.int/rec/T-REC-G.694.1-201202-I/en
|
||||
"""converts m into frequency range
|
||||
|
||||
spectrum(13,7) is (193137500000000.0, 193225000000000.0)
|
||||
reference to Recommendation G.694.1 (02/12), Figure I.3
|
||||
https://www.itu.int/rec/T-REC-G.694.1-201202-I/en
|
||||
|
||||
>>> fstart, fstop = m_to_freq(13, 7)
|
||||
>>> fstart
|
||||
@@ -225,9 +215,7 @@ def m_to_freq(nvalue, mvalue, grid=0.00625e12):
|
||||
|
||||
|
||||
def align_grids(oms_list):
|
||||
""" used to apply same grid to all oms : same starting n, stop n and slot size
|
||||
out of grid slots are set to 0
|
||||
"""
|
||||
"""Used to apply same grid to all oms : same starting n, stop n and slot size. Out of grid slots are set to 0."""
|
||||
n_min = min([o.spectrum_bitmap.n_min for o in oms_list])
|
||||
n_max = max([o.spectrum_bitmap.n_max for o in oms_list])
|
||||
for this_o in oms_list:
|
||||
@@ -239,12 +227,13 @@ def align_grids(oms_list):
|
||||
|
||||
|
||||
def build_oms_list(network, equipment):
|
||||
""" initialization of OMS list in the network
|
||||
an oms is build reading all intermediate nodes between two adjacent ROADMs
|
||||
each element within the list is being added an oms and oms_id to record the
|
||||
oms it belongs to.
|
||||
the function supports different spectrum width and supposes that the whole network
|
||||
works with the min range among OMSs
|
||||
"""initialization of OMS list in the network
|
||||
|
||||
an oms is build reading all intermediate nodes between two adjacent ROADMs
|
||||
each element within the list is being added an oms and oms_id to record the
|
||||
oms it belongs to.
|
||||
the function supports different spectrum width and supposes that the whole network
|
||||
works with the min range among OMSs
|
||||
"""
|
||||
oms_id = 0
|
||||
oms_list = []
|
||||
@@ -296,8 +285,9 @@ def build_oms_list(network, equipment):
|
||||
|
||||
|
||||
def reversed_oms(oms_list):
|
||||
""" identifies reversed OMS
|
||||
only applicable for non parallel OMS
|
||||
"""identifies reversed OMS
|
||||
|
||||
only applicable for non parallel OMS
|
||||
"""
|
||||
for oms in oms_list:
|
||||
has_reversed = False
|
||||
@@ -322,28 +312,41 @@ def bitmap_sum(band1, band2):
|
||||
return res
|
||||
|
||||
|
||||
def spectrum_selection(pth, oms_list, requested_m, requested_n=None):
|
||||
"""Collects spectrum availability and call the select_candidate function"""
|
||||
|
||||
# use indexes instead of ITU-T n values
|
||||
def build_path_oms_id_list(pth):
|
||||
path_oms = []
|
||||
for elem in pth:
|
||||
if not isinstance(elem, Roadm) and not isinstance(elem, Transceiver):
|
||||
# only edfa, fused and fibers have oms_id attribute
|
||||
path_oms.append(elem.oms_id)
|
||||
# remove duplicate oms_id, order is not important
|
||||
path_oms = list(set(path_oms))
|
||||
# assuming all oms have same freq index
|
||||
if not path_oms:
|
||||
candidate = (None, None, None)
|
||||
return candidate, path_oms
|
||||
freq_index = oms_list[path_oms[0]].spectrum_bitmap.freq_index
|
||||
freq_index_min = oms_list[path_oms[0]].spectrum_bitmap.freq_index_min
|
||||
freq_index_max = oms_list[path_oms[0]].spectrum_bitmap.freq_index_max
|
||||
return list(set(path_oms))
|
||||
|
||||
freq_availability = oms_list[path_oms[0]].spectrum_bitmap.bitmap
|
||||
|
||||
def aggregate_oms_bitmap(path_oms, oms_list):
|
||||
spectrum = oms_list[path_oms[0]].spectrum_bitmap
|
||||
bitmap = spectrum.bitmap
|
||||
# assuming all oms have same freq indices
|
||||
for oms in path_oms[1:]:
|
||||
freq_availability = bitmap_sum(oms_list[oms].spectrum_bitmap.bitmap, freq_availability)
|
||||
bitmap = bitmap_sum(oms_list[oms].spectrum_bitmap.bitmap, bitmap)
|
||||
params = {
|
||||
'oms_id': 0,
|
||||
'el_id_list': 0,
|
||||
'el_list': []
|
||||
}
|
||||
freq_min = nvalue_to_frequency(spectrum.freq_index_min)
|
||||
freq_max = nvalue_to_frequency(spectrum.freq_index_max)
|
||||
aggregate_oms = OMS(**params)
|
||||
aggregate_oms.update_spectrum(freq_min, freq_max, grid=0.00625e12, existing_spectrum=bitmap)
|
||||
return aggregate_oms
|
||||
|
||||
|
||||
def spectrum_selection(test_oms, requested_m, requested_n=None):
|
||||
"""Collects spectrum availability and call the select_candidate function"""
|
||||
freq_index = test_oms.spectrum_bitmap.freq_index
|
||||
freq_index_min = test_oms.spectrum_bitmap.freq_index_min
|
||||
freq_index_max = test_oms.spectrum_bitmap.freq_index_max
|
||||
freq_availability = test_oms.spectrum_bitmap.bitmap
|
||||
|
||||
if requested_n is None:
|
||||
# avoid slots reserved on the edge 0.15e-12 on both sides -> 24
|
||||
candidates = [(freq_index[i] + requested_m, freq_index[i], freq_index[i] + 2 * requested_m - 1)
|
||||
@@ -354,29 +357,36 @@ def spectrum_selection(pth, oms_list, requested_m, requested_n=None):
|
||||
|
||||
candidate = select_candidate(candidates, policy='first_fit')
|
||||
else:
|
||||
i = oms_list[path_oms[0]].spectrum_bitmap.geti(requested_n)
|
||||
# print(f'N {requested_n} i {i}')
|
||||
# print(freq_availability[i-m:i+m] )
|
||||
# print(freq_index[i-m:i+m])
|
||||
if (freq_availability[i - requested_m:i + requested_m] == [1] * (2 * requested_m) and
|
||||
freq_index[i - requested_m] >= freq_index_min
|
||||
i = test_oms.spectrum_bitmap.geti(requested_n)
|
||||
if (freq_availability[i - requested_m:i + requested_m] == [1] * (2 * requested_m)
|
||||
and freq_index[i - requested_m] >= freq_index_min
|
||||
and freq_index[i + requested_m - 1] <= freq_index_max):
|
||||
# candidate is the triplet center_n, startn and stopn
|
||||
candidate = (requested_n, requested_n - requested_m, requested_n + requested_m - 1)
|
||||
else:
|
||||
candidate = (None, None, None)
|
||||
# print("coucou11")
|
||||
# print(candidate)
|
||||
# print(freq_availability[321:321+2*m])
|
||||
# a = [i+321 for i in range(2*m)]
|
||||
# print(a)
|
||||
# print(candidate)
|
||||
return candidate, path_oms
|
||||
return candidate
|
||||
|
||||
|
||||
def determine_slot_numbers(test_oms, requested_n, required_m, per_channel_m):
|
||||
"""determines max availability around requested_n. requested_n should not be None"""
|
||||
bitmap = test_oms.spectrum_bitmap
|
||||
freq_index = bitmap.freq_index
|
||||
freq_index_min = bitmap.freq_index_min
|
||||
freq_index_max = bitmap.freq_index_max
|
||||
freq_availability = bitmap.bitmap
|
||||
center_i = bitmap.geti(requested_n)
|
||||
i = per_channel_m
|
||||
while (freq_availability[center_i - i:center_i + i] == [1] * (2 * i)
|
||||
and freq_index[center_i - i] >= freq_index_min
|
||||
and freq_index[center_i + i - 1] <= freq_index_max
|
||||
and i <= required_m):
|
||||
i += per_channel_m
|
||||
return i - per_channel_m
|
||||
|
||||
|
||||
def select_candidate(candidates, policy):
|
||||
""" selects a candidate among all available spectrum
|
||||
"""
|
||||
"""selects a candidate among all available spectrum"""
|
||||
if policy == 'first_fit':
|
||||
if candidates:
|
||||
return candidates[0]
|
||||
@@ -386,46 +396,112 @@ def select_candidate(candidates, policy):
|
||||
raise ServiceError('Only first_fit spectrum assignment policy is implemented.')
|
||||
|
||||
|
||||
def pth_assign_spectrum(pths, rqs, oms_list, rpths):
|
||||
""" basic first fit assignment
|
||||
if reversed path are provided, means that occupation is bidir
|
||||
"""
|
||||
for i, pth in enumerate(pths):
|
||||
# computes the number of channels required
|
||||
try:
|
||||
if rqs[i].blocking_reason:
|
||||
rqs[i].blocked = True
|
||||
rqs[i].N = 0
|
||||
rqs[i].M = 0
|
||||
except AttributeError:
|
||||
nb_wl = ceil(rqs[i].path_bandwidth / rqs[i].bit_rate)
|
||||
# computes the total nb of slots according to requested spacing
|
||||
# TODO : express superchannels
|
||||
# assumes that all channels must be grouped
|
||||
# TODO : enables non contiguous reservation in case of blocking
|
||||
requested_m = ceil(rqs[i].spacing / 0.0125e12) * nb_wl
|
||||
# concatenate all path and reversed path elements to derive slots availability
|
||||
(center_n, startn, stopn), path_oms = spectrum_selection(pth + rpths[i], oms_list, requested_m,
|
||||
requested_n=None)
|
||||
# checks that requested_m is fitting startm and stopm
|
||||
# if not None, center_n and start, stop frequencies are applicable to all oms of pth
|
||||
# checks that spectrum is not None else indicate blocking reason
|
||||
if center_n is not None:
|
||||
# checks that requested_m is fitting startm and stopm
|
||||
if 2 * requested_m > (stopn - startn + 1):
|
||||
msg = f'candidate: {(center_n, startn, stopn)} is not consistant ' +\
|
||||
f'with {requested_m}'
|
||||
LOGGER.critical(msg)
|
||||
raise ValueError(msg)
|
||||
def compute_n_m(required_m, rq, path_oms, oms_list, per_channel_m, policy='first_fit'):
|
||||
""" based on requested path_bandwidth fill in M=None values with uint values, using per_channel_m
|
||||
and center frequency, with first fit strategy. The function checks the available spectrum but check
|
||||
consistencies among M values of the request, but not with other requests.
|
||||
For example, if request is for 32 slots corresponding to 8 x 4 slots of 32Gbauds channels,
|
||||
the following frequency slots will result in the following assignment
|
||||
|
||||
for oms_elem in path_oms:
|
||||
oms_list[oms_elem].assign_spectrum(center_n, requested_m)
|
||||
oms_list[oms_elem].add_service(rqs[i].request_id, nb_wl)
|
||||
rqs[i].blocked = False
|
||||
rqs[i].N = center_n
|
||||
rqs[i].M = requested_m
|
||||
N = 0, 8, 16, 32 -> 0, 8, 16, 32
|
||||
M = 8, None, 8, None -> 8, 8, 8, 8
|
||||
|
||||
N = 0, 8, 16, 32 -> 0, , 16
|
||||
M = None, None, 8, None -> 24, , 8
|
||||
"""
|
||||
selected_m = []
|
||||
selected_n = []
|
||||
remaining_slots_to_serve = required_m
|
||||
# order slots for the computation: assign biggest m first
|
||||
rq_N, rq_M, order = order_slots([{'N': n, 'M': m} for n, m in zip(rq.N, rq.M)])
|
||||
# Create an oms that represents current assignments of all oms listed in path_oms, and test N and M on it.
|
||||
# If M is defined, checks that proposed N, M is free
|
||||
test_oms = aggregate_oms_bitmap(path_oms, oms_list)
|
||||
for n, m in zip(rq_N, rq_M):
|
||||
if m is not None and n is not None:
|
||||
# check availabilityfor this n, m
|
||||
available_slots = determine_slot_numbers(test_oms, n, m, m)
|
||||
if available_slots == 0:
|
||||
# if n, m are not feasible, break at this point no have non zero remaining_slots_to_serve
|
||||
# in order to blocks the request (even is other N,M where feasible)
|
||||
break
|
||||
elif m is not None and n is None:
|
||||
# find a candidate n
|
||||
n, _, _ = spectrum_selection(test_oms, m, None)
|
||||
if n is None:
|
||||
# if no n is feasible for the m, block the request
|
||||
break
|
||||
elif m is None and n is not None:
|
||||
# find a feasible m for this n. If None is found, then block the request
|
||||
m = determine_slot_numbers(test_oms, n, remaining_slots_to_serve, per_channel_m)
|
||||
if m == 0 or remaining_slots_to_serve == 0:
|
||||
break
|
||||
else:
|
||||
# if n and m are not defined, try to find a single assignment to fits the remaining slots to serve
|
||||
# (first fit strategy)
|
||||
n, _, _ = spectrum_selection(test_oms, remaining_slots_to_serve, None)
|
||||
if n is None or remaining_slots_to_serve == 0:
|
||||
break
|
||||
else:
|
||||
rqs[i].blocked = True
|
||||
rqs[i].N = 0
|
||||
rqs[i].M = 0
|
||||
rqs[i].blocking_reason = 'NO_SPECTRUM'
|
||||
m = remaining_slots_to_serve
|
||||
selected_m.append(m)
|
||||
selected_n.append(n)
|
||||
test_oms.assign_spectrum(n, m)
|
||||
remaining_slots_to_serve = remaining_slots_to_serve - m
|
||||
|
||||
# re-order selected_m and selected_n according to initial request N, M order, ignoring None values
|
||||
not_selected = [None for i in range(len(rq_N) - len(selected_n))]
|
||||
selected_m = restore_order(selected_m + not_selected, order)
|
||||
selected_n = restore_order(selected_n + not_selected, order)
|
||||
return selected_n, selected_m, remaining_slots_to_serve
|
||||
|
||||
|
||||
def pth_assign_spectrum(pths, rqs, oms_list, rpths):
|
||||
"""basic first fit assignment
|
||||
|
||||
if reversed path are provided, means that occupation is bidir
|
||||
"""
|
||||
for pth, rq, rpth in zip(pths, rqs, rpths):
|
||||
if hasattr(rq, 'blocking_reason'):
|
||||
rq.N = None
|
||||
rq.M = None
|
||||
else:
|
||||
# computes the number of channels required for path_bandwidth and the min required nb of slots
|
||||
# for one channel (corresponds to the spacing)
|
||||
nb_wl, required_m = compute_spectrum_slot_vs_bandwidth(rq.path_bandwidth,
|
||||
rq.spacing, rq.bit_rate)
|
||||
_, per_channel_m = compute_spectrum_slot_vs_bandwidth(rq.bit_rate,
|
||||
rq.spacing, rq.bit_rate)
|
||||
# find oms ids that are concerned both by pth and rpth
|
||||
path_oms = build_path_oms_id_list(pth + rpth)
|
||||
if getattr(rq, 'M', None) is not None and all(rq.M):
|
||||
# if all M are well defined: Consistency check that the requested M are enough to carry the nb_wl:
|
||||
# check that the integer number of per_channel_m carried in each M value is enough to carry nb_wl.
|
||||
# if not, blocks the demand
|
||||
nb_channels_of_request = sum([m // per_channel_m for m in rq.M])
|
||||
# TODO: elaborate a more accurate estimate with nb_wl * min_spacing + possibly guardbands in case of
|
||||
# superchannel closed packing.
|
||||
if nb_wl > nb_channels_of_request:
|
||||
rq.N = None
|
||||
rq.M = None
|
||||
rq.blocking_reason = 'NOT_ENOUGH_RESERVED_SPECTRUM'
|
||||
# need to stop here for this request and not go though spectrum selection process
|
||||
continue
|
||||
# Use the req.M even if nb_wl and required_m are smaller.
|
||||
# first fit strategy: assign as many lambda as possible in the None remaining N, M values
|
||||
selected_n, selected_m, remaining_slots_to_serve = \
|
||||
compute_n_m(required_m, rq, path_oms, oms_list, per_channel_m)
|
||||
# if there are some remaining_slots_to_serve, this means that provided rq.M and rq.N values were
|
||||
# not possible. Then do not go though spectrum assignment process and blocks the demand
|
||||
if remaining_slots_to_serve > 0:
|
||||
rq.N = None
|
||||
rq.M = None
|
||||
rq.blocking_reason = 'NO_SPECTRUM'
|
||||
continue
|
||||
for oms_elem in path_oms:
|
||||
for this_n, this_m in zip(selected_n, selected_m):
|
||||
if this_m is not None:
|
||||
oms_list[oms_elem].assign_spectrum(this_n, this_m)
|
||||
oms_list[oms_elem].add_service(rq.request_id, nb_wl)
|
||||
rq.N = selected_n
|
||||
rq.M = selected_m
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
matplotlib>=3.3.3,<4
|
||||
networkx>=2.5,<3
|
||||
numpy>=1.19.4,<2
|
||||
pandas>=1.1.5,<2
|
||||
pbr>=5.5.1,<6
|
||||
scipy>=1.5.4,<2
|
||||
xlrd>=1.2.0,<2
|
||||
44
setup.cfg
44
setup.cfg
@@ -3,13 +3,13 @@ name = gnpy
|
||||
description-file = README.md
|
||||
description-content-type = text/markdown; variant=GFM
|
||||
author = Telecom Infra Project
|
||||
author-email = jan.kundrat@telecominfraproject.com
|
||||
author-email = jkt@jankundrat.com
|
||||
license = BSD-3-Clause
|
||||
home-page = https://github.com/Telecominfraproject/oopt-gnpy
|
||||
project_urls =
|
||||
Bug Tracker = https://github.com/Telecominfraproject/oopt-gnpy/issues
|
||||
Documentation = https://gnpy.readthedocs.io/
|
||||
python-requires = >=3.6
|
||||
python-requires = >=3.8
|
||||
classifier =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Intended Audience :: Developers
|
||||
@@ -19,10 +19,11 @@ classifier =
|
||||
Natural Language :: English
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
Programming Language :: Python :: 3.12
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Topic :: Scientific/Engineering
|
||||
Topic :: Scientific/Engineering :: Physics
|
||||
@@ -41,9 +42,6 @@ warnerrors = True
|
||||
|
||||
[files]
|
||||
packages = gnpy
|
||||
data_files =
|
||||
examples = examples/*
|
||||
# FIXME: solve example data files
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
@@ -51,3 +49,35 @@ console_scripts =
|
||||
gnpy-transmission-example = gnpy.tools.cli_examples:transmission_main_example
|
||||
gnpy-path-request = gnpy.tools.cli_examples:path_requests_run
|
||||
gnpy-convert-xls = gnpy.tools.convert:_do_convert
|
||||
|
||||
[options]
|
||||
install_requires =
|
||||
# matplotlib 3.8 removed support for Python 3.8
|
||||
matplotlib>=3.7.3,<4
|
||||
# networkx 3.2 removed support for Python 3.8
|
||||
networkx>=3.1,<4
|
||||
# numpy 1.25 removed support for Python 3.8
|
||||
numpy>=1.24.4,<2
|
||||
pbr>=6.0.0,<7
|
||||
# scipy 1.11 removed support for Python 3.8
|
||||
scipy>=1.10.1,<2
|
||||
# xlrd 2.x removed support for .xlsx, it's only .xls now
|
||||
xlrd>=1.2.0,<2
|
||||
|
||||
[options.extras_require]
|
||||
tests =
|
||||
build>=1.0.3,<2
|
||||
pytest>=7.4.3,<8
|
||||
# pandas 2.1 removed support for Python 3.8
|
||||
pandas>=2.0.3,<3
|
||||
# flake v6 killed the --diff option
|
||||
flake8>=5.0.4,<6
|
||||
|
||||
docs =
|
||||
alabaster>=0.7.12,<1
|
||||
docutils>=0.17.1,<1
|
||||
myst-parser>=0.16.1,<1
|
||||
Pygments>=2.11.2,<3
|
||||
rstcheck
|
||||
Sphinx>=5.3.0,<6
|
||||
sphinxcontrib-bibtex>=2.4.1,<3
|
||||
|
||||
135
tests/compare.py
135
tests/compare.py
@@ -1,135 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from json import dump
|
||||
from pathlib import Path
|
||||
from argparse import ArgumentParser
|
||||
from collections import namedtuple
|
||||
from gnpy.tools.json_io import load_json
|
||||
|
||||
|
||||
class Results(namedtuple('Results', 'missing extra different expected actual')):
|
||||
def _asdict(self):
|
||||
return {'missing': self.missing,
|
||||
'extra': self.extra,
|
||||
'different': self.different}
|
||||
|
||||
def __str__(self):
|
||||
rv = []
|
||||
if self.missing:
|
||||
rv.append('Missing: {len(self.missing)}/{len(self.expected)}')
|
||||
rv.extend(f'\t{x}' for x in sorted(self.missing))
|
||||
if self.extra:
|
||||
rv.append('Extra: {len(self.extra)}/{len(self.expected)}')
|
||||
rv.extend(f'\t{x}' for x in sorted(self.extra))
|
||||
if self.different:
|
||||
rv.append('Different: {len(self.different)}/{len(self.expected)}')
|
||||
rv.extend(f'\tExpected: {x}\n\tActual: {y}' for x, y in self.different)
|
||||
if not self.missing and not self.extra and not self.different:
|
||||
rv.append('All match!')
|
||||
return '\n'.join(rv)
|
||||
|
||||
|
||||
class NetworksResults(namedtuple('NetworksResult', 'elements connections')):
|
||||
def _asdict(self):
|
||||
return {'elements': self.elements._asdict(),
|
||||
'connections': self.connections._asdict()}
|
||||
|
||||
def __str__(self):
|
||||
return '\n'.join([
|
||||
'Elements'.center(40, '='),
|
||||
str(self.elements),
|
||||
'Connections'.center(40, '='),
|
||||
str(self.connections),
|
||||
])
|
||||
|
||||
|
||||
class ServicesResults(namedtuple('ServicesResult', 'requests synchronizations')):
|
||||
def _asdict(self):
|
||||
return {'requests': self.requests.asdict(),
|
||||
'synchronizations': self.synchronizations.asdict()}
|
||||
|
||||
def __str__(self):
|
||||
return '\n'.join([
|
||||
'Requests'.center(40, '='),
|
||||
str(self.requests),
|
||||
'Synchronizations'.center(40, '='),
|
||||
str(self.synchronizations),
|
||||
])
|
||||
|
||||
|
||||
class PathsResults(namedtuple('PathsResults', 'paths')):
|
||||
def _asdict(self):
|
||||
return {'paths': self.paths.asdict()}
|
||||
|
||||
def __str__(self):
|
||||
return '\n'.join([
|
||||
'Paths'.center(40, '='),
|
||||
str(self.paths),
|
||||
])
|
||||
|
||||
|
||||
def compare(expected, actual, key=lambda x: x):
|
||||
expected = {key(el): el for el in expected}
|
||||
actual = {key(el): el for el in actual}
|
||||
missing = set(expected) - set(actual)
|
||||
extra = set(actual) - set(expected)
|
||||
different = [(expected[x], actual[x]) for
|
||||
x in set(expected) & set(actual)
|
||||
if expected[x] != actual[x]]
|
||||
return Results(missing, extra, different, expected, actual)
|
||||
|
||||
|
||||
def compare_networks(expected, actual):
|
||||
elements = compare(expected['elements'], actual['elements'],
|
||||
key=lambda el: el['uid'])
|
||||
connections = compare(expected['connections'], actual['connections'],
|
||||
key=lambda el: (el['from_node'], el['to_node']))
|
||||
return NetworksResults(elements, connections)
|
||||
|
||||
|
||||
def compare_services(expected, actual):
|
||||
requests = compare(expected['path-request'], actual['path-request'],
|
||||
key=lambda el: el['request-id'])
|
||||
synchronizations = compare(expected['path-request'], expected['path-request'],
|
||||
key=lambda el: el['request-id'])
|
||||
if 'synchronization' in expected.keys():
|
||||
synchronizations = compare(expected['synchronization'], actual['synchronization'],
|
||||
key=lambda el: el['synchronization-id'])
|
||||
return ServicesResults(requests, synchronizations)
|
||||
|
||||
|
||||
def compare_paths(expected_output, actual_output):
|
||||
paths = compare(expected['path'], actual['path'], key=lambda el: el['path-id'])
|
||||
return PathsResults(paths)
|
||||
|
||||
|
||||
COMPARISONS = {
|
||||
'networks': compare_networks,
|
||||
'services': compare_services,
|
||||
'paths': compare_paths,
|
||||
}
|
||||
|
||||
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))
|
||||
13
tests/conftest.py
Normal file
13
tests/conftest.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
# Copyright (C) 2020 Telecom Infra Project and GNPy contributors
|
||||
# see LICENSE.md for a list of contributors
|
||||
#
|
||||
|
||||
import pytest
|
||||
from gnpy.core.parameters import SimParams, NLIParams, RamanParams
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def set_sim_params(monkeypatch):
|
||||
monkeypatch.setattr(SimParams, '_shared_dict', {'nli_params': NLIParams(), 'raman_params': RamanParams()})
|
||||
File diff suppressed because it is too large
Load Diff
21
tests/data/CORONET_services.json
Normal file
21
tests/data/CORONET_services.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"path-request": [
|
||||
{
|
||||
"request-id": "0",
|
||||
"source": "trx Abilene",
|
||||
"destination": "trx Albany",
|
||||
"src-tp-id": "trx Abilene",
|
||||
"dst-tp-id": "trx Albany",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 3",
|
||||
"spacing": 62500000000.0,
|
||||
"path_bandwidth": 100000000000.0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 196.1e12,
|
||||
"nf_ripple": [
|
||||
0.0,
|
||||
0.0,
|
||||
@@ -196,101 +198,101 @@
|
||||
0.0
|
||||
],
|
||||
"dgt": [
|
||||
2.714526681131686,
|
||||
2.705443819238505,
|
||||
2.6947834587664494,
|
||||
2.6841217449620203,
|
||||
2.6681935771243177,
|
||||
2.6521732021128046,
|
||||
2.630396440815385,
|
||||
2.602860350286428,
|
||||
2.5696460593920065,
|
||||
2.5364027376452056,
|
||||
2.499446286796604,
|
||||
2.4587748041127506,
|
||||
2.414398437185221,
|
||||
2.3699990328716107,
|
||||
2.322373696229342,
|
||||
2.271520771371253,
|
||||
2.2174389328192197,
|
||||
2.16337565384239,
|
||||
2.1183028432496016,
|
||||
2.082225099873648,
|
||||
2.055100772005235,
|
||||
2.0279625371819305,
|
||||
2.0008103857988204,
|
||||
1.9736443063300082,
|
||||
1.9482128147680253,
|
||||
1.9245345552113182,
|
||||
1.9026104247588487,
|
||||
1.8806927939516411,
|
||||
1.862235672444246,
|
||||
1.847275503201129,
|
||||
1.835814081380705,
|
||||
1.824381436842932,
|
||||
1.8139629377087627,
|
||||
1.8045606557581335,
|
||||
1.7961751115773796,
|
||||
1.7877868031023945,
|
||||
1.7793941781790852,
|
||||
1.7709972329654864,
|
||||
1.7625959636196327,
|
||||
1.7541903672600494,
|
||||
1.7459181197626403,
|
||||
1.737780757913635,
|
||||
1.7297783508684146,
|
||||
1.7217732861435076,
|
||||
1.7137640932265894,
|
||||
1.7057507692361864,
|
||||
1.6918150918099673,
|
||||
1.6719047669939942,
|
||||
1.6460167077689267,
|
||||
1.6201194134191075,
|
||||
1.5986915141218316,
|
||||
1.5817353179379183,
|
||||
1.569199764184379,
|
||||
1.5566577309558969,
|
||||
1.545374152761467,
|
||||
1.5353620432989845,
|
||||
1.5266220576235803,
|
||||
1.5178910621476225,
|
||||
1.5097346239790443,
|
||||
1.502153039909686,
|
||||
1.495145456062699,
|
||||
1.488134243479226,
|
||||
1.48111939735681,
|
||||
1.474100442252211,
|
||||
1.4670307626366115,
|
||||
1.4599103316162523,
|
||||
1.45273959485914,
|
||||
1.445565137158368,
|
||||
1.4340878115214444,
|
||||
1.418273806730323,
|
||||
1.3981208704326855,
|
||||
1.3779439775587023,
|
||||
1.3598972673004606,
|
||||
1.3439818461440451,
|
||||
1.3301807335621048,
|
||||
1.316383926863083,
|
||||
1.3040618749785347,
|
||||
1.2932153453410835,
|
||||
1.2838336236692311,
|
||||
1.2744470198196236,
|
||||
1.2650555289898042,
|
||||
1.2556591482982988,
|
||||
1.2428104897182262,
|
||||
1.2264996957264114,
|
||||
1.2067249615595257,
|
||||
1.1869318618366975,
|
||||
1.1672278304018044,
|
||||
1.1476135933863398,
|
||||
1.1280891949729075,
|
||||
1.108555289615659,
|
||||
1.0895983485572227,
|
||||
1.0712204022764056,
|
||||
1.0534217504465226,
|
||||
1.0356155337864215,
|
||||
1.0,
|
||||
1.017807767853702,
|
||||
1.0
|
||||
1.0356155337864215,
|
||||
1.0534217504465226,
|
||||
1.0712204022764056,
|
||||
1.0895983485572227,
|
||||
1.108555289615659,
|
||||
1.1280891949729075,
|
||||
1.1476135933863398,
|
||||
1.1672278304018044,
|
||||
1.1869318618366975,
|
||||
1.2067249615595257,
|
||||
1.2264996957264114,
|
||||
1.2428104897182262,
|
||||
1.2556591482982988,
|
||||
1.2650555289898042,
|
||||
1.2744470198196236,
|
||||
1.2838336236692311,
|
||||
1.2932153453410835,
|
||||
1.3040618749785347,
|
||||
1.316383926863083,
|
||||
1.3301807335621048,
|
||||
1.3439818461440451,
|
||||
1.3598972673004606,
|
||||
1.3779439775587023,
|
||||
1.3981208704326855,
|
||||
1.418273806730323,
|
||||
1.4340878115214444,
|
||||
1.445565137158368,
|
||||
1.45273959485914,
|
||||
1.4599103316162523,
|
||||
1.4670307626366115,
|
||||
1.474100442252211,
|
||||
1.48111939735681,
|
||||
1.488134243479226,
|
||||
1.495145456062699,
|
||||
1.502153039909686,
|
||||
1.5097346239790443,
|
||||
1.5178910621476225,
|
||||
1.5266220576235803,
|
||||
1.5353620432989845,
|
||||
1.545374152761467,
|
||||
1.5566577309558969,
|
||||
1.569199764184379,
|
||||
1.5817353179379183,
|
||||
1.5986915141218316,
|
||||
1.6201194134191075,
|
||||
1.6460167077689267,
|
||||
1.6719047669939942,
|
||||
1.6918150918099673,
|
||||
1.7057507692361864,
|
||||
1.7137640932265894,
|
||||
1.7217732861435076,
|
||||
1.7297783508684146,
|
||||
1.737780757913635,
|
||||
1.7459181197626403,
|
||||
1.7541903672600494,
|
||||
1.7625959636196327,
|
||||
1.7709972329654864,
|
||||
1.7793941781790852,
|
||||
1.7877868031023945,
|
||||
1.7961751115773796,
|
||||
1.8045606557581335,
|
||||
1.8139629377087627,
|
||||
1.824381436842932,
|
||||
1.835814081380705,
|
||||
1.847275503201129,
|
||||
1.862235672444246,
|
||||
1.8806927939516411,
|
||||
1.9026104247588487,
|
||||
1.9245345552113182,
|
||||
1.9482128147680253,
|
||||
1.9736443063300082,
|
||||
2.0008103857988204,
|
||||
2.0279625371819305,
|
||||
2.055100772005235,
|
||||
2.082225099873648,
|
||||
2.1183028432496016,
|
||||
2.16337565384239,
|
||||
2.2174389328192197,
|
||||
2.271520771371253,
|
||||
2.322373696229342,
|
||||
2.3699990328716107,
|
||||
2.414398437185221,
|
||||
2.4587748041127506,
|
||||
2.499446286796604,
|
||||
2.5364027376452056,
|
||||
2.5696460593920065,
|
||||
2.602860350286428,
|
||||
2.630396440815385,
|
||||
2.6521732021128046,
|
||||
2.6681935771243177,
|
||||
2.6841217449620203,
|
||||
2.6947834587664494,
|
||||
2.705443819238505,
|
||||
2.714526681131686
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{ "Edfa":[{
|
||||
{
|
||||
"Edfa": [{
|
||||
"type_variety": "CienaDB_medium_gain",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
@@ -7,10 +8,9 @@
|
||||
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
}, {
|
||||
"type_variety": "std_medium_gain",
|
||||
"type_def": "variable_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 26,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
@@ -18,10 +18,9 @@
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
}, {
|
||||
"type_variety": "std_low_gain",
|
||||
"type_def": "variable_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 21,
|
||||
@@ -29,8 +28,7 @@
|
||||
"nf_max": 11,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
}, {
|
||||
"type_variety": "test",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 25,
|
||||
@@ -40,8 +38,7 @@
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
}, {
|
||||
"type_variety": "test_fixed_gain",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
@@ -49,8 +46,7 @@
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
}, {
|
||||
"type_variety": "std_booster",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
@@ -58,18 +54,18 @@
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber":[{
|
||||
}
|
||||
],
|
||||
"Fiber": [{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"gamma": 0.00127,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"Span":[{
|
||||
"power_mode":true,
|
||||
"delta_power_range_db": [0,0,0.5],
|
||||
}
|
||||
],
|
||||
"Span": [{
|
||||
"power_mode": true,
|
||||
"delta_power_range_db": [0, 0, 0.5],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
@@ -79,156 +75,218 @@
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm":[{
|
||||
}
|
||||
],
|
||||
"Roadm": [{
|
||||
"type_variety": "example_test",
|
||||
"target_pch_out_db": -18,
|
||||
"add_drop_osnr": 35,
|
||||
"pmd": 1e-12,
|
||||
"pdl": 0.5,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": []
|
||||
}, {
|
||||
"type_variety": "example_detailed_impairments",
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 35,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list":[],
|
||||
"booster_variety_list":[]
|
||||
},
|
||||
"roadm-path-impairments": [
|
||||
{
|
||||
"roadm-path-impairments-id": 0,
|
||||
"roadm-express-path": [{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 16.5
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"roadm-path-impairments-id": 1,
|
||||
"roadm-add-path": [{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 11.5,
|
||||
"roadm-pmax": 2.5,
|
||||
"roadm-osnr": 41,
|
||||
"roadm-noise-figure": 23
|
||||
}]
|
||||
}, {
|
||||
"roadm-path-impairments-id": 2,
|
||||
"roadm-drop-path": [{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 11.5,
|
||||
"roadm-minloss": 7.5,
|
||||
"roadm-typloss": 10,
|
||||
"roadm-pmin": -13.5,
|
||||
"roadm-pmax": -9.5,
|
||||
"roadm-ptyp": -12,
|
||||
"roadm-osnr": 41,
|
||||
"roadm-noise-figure": 15
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list":[],
|
||||
"booster_variety_list":[]
|
||||
}
|
||||
}],
|
||||
"SI":[{
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"SI": [{
|
||||
"f_min": 191.3e12,
|
||||
"f_max":196.1e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"power_range_db": [0,0,0.5],
|
||||
"power_range_db": [0, 0, 0.5],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
"sys_margins": 0
|
||||
}],
|
||||
"Transceiver":[
|
||||
{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency":{
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode":[
|
||||
{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost":1
|
||||
}
|
||||
]
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
{
|
||||
"mode": [{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"type_variety": "Voyager_16QAM",
|
||||
"frequency":{
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode":[
|
||||
{
|
||||
"format": "16QAM",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 19,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost":1
|
||||
}
|
||||
]
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
{
|
||||
"mode": [{
|
||||
"format": "16QAM",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 19,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"type_variety": "Voyager",
|
||||
"frequency":{
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode":[
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 50e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 3",
|
||||
"baud_rate": 44e9,
|
||||
"OSNR": 18,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 62.5e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 2 - fake",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost":1
|
||||
},
|
||||
{
|
||||
"format": "mode 4",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 16,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost":1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 3",
|
||||
"baud_rate": 44e9,
|
||||
"OSNR": 18,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 62.5e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2 - fake",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 4",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 16,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
220
tests/data/eqpt_config_psd.json
Normal file
220
tests/data/eqpt_config_psd.json
Normal file
@@ -0,0 +1,220 @@
|
||||
{
|
||||
"Edfa": [{
|
||||
"type_variety": "CienaDB_medium_gain",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "std_medium_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 26,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"nf_min": 6,
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "std_low_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 21,
|
||||
"nf_min": 7,
|
||||
"nf_max": 11,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "test",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"nf_min": 5.8,
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "test_fixed_gain",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "std_booster",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber": [{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"Span": [{
|
||||
"power_mode": true,
|
||||
"delta_power_range_db": [0, 0, 0.5],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm": [{
|
||||
"target_psd_out_mWperGHz": 3.125e-4,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"SI": [{
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"power_range_db": [0, 0, 0.5],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
}
|
||||
],
|
||||
"Transceiver": [{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency": {
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"type_variety": "Voyager_16QAM",
|
||||
"frequency": {
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [{
|
||||
"format": "16QAM",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 19,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"type_variety": "Voyager",
|
||||
"frequency": {
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 3",
|
||||
"baud_rate": 44e9,
|
||||
"OSNR": 18,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 62.5e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2 - fake",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 4",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 16,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
220
tests/data/eqpt_config_psw.json
Normal file
220
tests/data/eqpt_config_psw.json
Normal file
@@ -0,0 +1,220 @@
|
||||
{
|
||||
"Edfa": [{
|
||||
"type_variety": "CienaDB_medium_gain",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "std_medium_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 26,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"nf_min": 6,
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "std_low_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 21,
|
||||
"nf_min": 7,
|
||||
"nf_max": 11,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "test",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"nf_min": 5.8,
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "test_fixed_gain",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": true
|
||||
}, {
|
||||
"type_variety": "std_booster",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber": [{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"Span": [{
|
||||
"power_mode": true,
|
||||
"delta_power_range_db": [0, 0, 0.5],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm": [{
|
||||
"target_out_mWperSlotWidth": 2.0e-4,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"SI": [{
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"power_range_db": [0, 0, 0.5],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
}
|
||||
],
|
||||
"Transceiver": [{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency": {
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"type_variety": "Voyager_16QAM",
|
||||
"frequency": {
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [{
|
||||
"format": "16QAM",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 19,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"type_variety": "Voyager",
|
||||
"frequency": {
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 3",
|
||||
"baud_rate": 44e9,
|
||||
"OSNR": 18,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 62.5e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 2 - fake",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "mode 4",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 16,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
238
tests/data/eqpt_config_sweep.json
Normal file
238
tests/data/eqpt_config_sweep.json
Normal file
@@ -0,0 +1,238 @@
|
||||
{
|
||||
"Edfa": [{
|
||||
"type_variety": "CienaDB_medium_gain",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_medium_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 26,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"nf_min": 6,
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_low_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 21,
|
||||
"nf_min": 7,
|
||||
"nf_max": 11,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "test",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"nf_min": 5.8,
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "test_fixed_gain",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_booster",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber": [{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"Span": [{
|
||||
"power_mode":true,
|
||||
"delta_power_range_db": [0,0,0.5],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm": [{
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list":[],
|
||||
"booster_variety_list":[]
|
||||
}
|
||||
}
|
||||
],
|
||||
"SI": [{
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"power_range_db": [-6,0,0.5],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
}
|
||||
],
|
||||
"Transceiver":[
|
||||
{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency":{
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode":[
|
||||
{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "Voyager_16QAM",
|
||||
"frequency": {
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "16QAM",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 19,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "Voyager",
|
||||
"frequency": {
|
||||
"min": 191.4e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 3",
|
||||
"baud_rate": 44e9,
|
||||
"OSNR": 18,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 62.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 2 - fake",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 4",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 16,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
@@ -63,6 +63,7 @@
|
||||
{
|
||||
"uid": "roadm Lannion_CAS",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -18.6,
|
||||
"restrictions": {
|
||||
@@ -87,6 +88,7 @@
|
||||
{
|
||||
"uid": "roadm Lorient_KMA",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -111,6 +113,7 @@
|
||||
{
|
||||
"uid": "roadm Vannes_KBE",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -134,6 +137,7 @@
|
||||
{
|
||||
"uid": "roadm Rennes_STA",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -157,6 +161,7 @@
|
||||
{
|
||||
"uid": "roadm Brest_KLA",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -1668,4 +1673,4 @@
|
||||
"to_node": "fiber (Ploermel → Vannes_KBE)-"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
{
|
||||
"uid": "Span1",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.5,
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 0.0000167,
|
||||
"gamma": 0.00127,
|
||||
"pmd_coef": 1.265e-15,
|
||||
"raman_efficiency": {
|
||||
"cr": [
|
||||
0,
|
||||
0.0000094,
|
||||
0.0000292,
|
||||
0.0000488,
|
||||
0.0000682,
|
||||
0.0000831,
|
||||
0.000094,
|
||||
0.0001014,
|
||||
0.0001069,
|
||||
0.0001119,
|
||||
0.0001217,
|
||||
0.0001268,
|
||||
0.0001365,
|
||||
0.000149,
|
||||
0.000165,
|
||||
0.000181,
|
||||
0.0001977,
|
||||
0.0002192,
|
||||
0.0002469,
|
||||
0.0002749,
|
||||
0.0002999,
|
||||
0.0003206,
|
||||
0.0003405,
|
||||
0.0003592,
|
||||
0.000374,
|
||||
0.0003826,
|
||||
0.0003841,
|
||||
0.0003826,
|
||||
0.0003802,
|
||||
0.0003756,
|
||||
0.0003549,
|
||||
0.0003795,
|
||||
0.000344,
|
||||
0.0002933,
|
||||
0.0002024,
|
||||
0.0001158,
|
||||
0.0000846,
|
||||
0.0000714,
|
||||
0.0000686,
|
||||
0.000085,
|
||||
0.0000893,
|
||||
0.0000901,
|
||||
0.0000815,
|
||||
0.0000667,
|
||||
0.0000437,
|
||||
0.0000328,
|
||||
0.0000296,
|
||||
0.0000265,
|
||||
0.0000257,
|
||||
0.0000281,
|
||||
0.0000308,
|
||||
0.0000367,
|
||||
0.0000585,
|
||||
0.0000663,
|
||||
0.0000636,
|
||||
0.000055,
|
||||
0.0000406,
|
||||
0.0000277,
|
||||
0.0000242,
|
||||
0.0000187,
|
||||
0.000016,
|
||||
0.000014,
|
||||
0.0000113,
|
||||
0.0000105,
|
||||
0.0000098,
|
||||
0.0000098,
|
||||
0.0000113,
|
||||
0.0000164,
|
||||
0.0000195,
|
||||
0.0000238,
|
||||
0.0000226,
|
||||
0.0000203,
|
||||
0.0000148,
|
||||
0.0000109,
|
||||
0.0000098,
|
||||
0.0000105,
|
||||
0.0000117,
|
||||
0.0000125,
|
||||
0.0000121,
|
||||
0.0000109,
|
||||
0.0000098,
|
||||
0.0000082,
|
||||
0.0000066,
|
||||
0.0000047,
|
||||
0.0000027,
|
||||
0.0000019,
|
||||
0.0000012,
|
||||
4e-7,
|
||||
2e-7,
|
||||
1e-7
|
||||
],
|
||||
"frequency_offset": [
|
||||
0,
|
||||
500000000000,
|
||||
1000000000000,
|
||||
1500000000000,
|
||||
2000000000000,
|
||||
2500000000000,
|
||||
3000000000000,
|
||||
3500000000000,
|
||||
4000000000000,
|
||||
4500000000000,
|
||||
5000000000000,
|
||||
5500000000000,
|
||||
6000000000000,
|
||||
6500000000000,
|
||||
7000000000000,
|
||||
7500000000000,
|
||||
8000000000000,
|
||||
8500000000000,
|
||||
9000000000000,
|
||||
9500000000000,
|
||||
10000000000000,
|
||||
10500000000000,
|
||||
11000000000000,
|
||||
11500000000000,
|
||||
12000000000000,
|
||||
12500000000000,
|
||||
12750000000000,
|
||||
13000000000000,
|
||||
13250000000000,
|
||||
13500000000000,
|
||||
14000000000000,
|
||||
14500000000000,
|
||||
14750000000000,
|
||||
15000000000000,
|
||||
15500000000000,
|
||||
16000000000000,
|
||||
16500000000000,
|
||||
17000000000000,
|
||||
17500000000000,
|
||||
18000000000000,
|
||||
18250000000000,
|
||||
18500000000000,
|
||||
18750000000000,
|
||||
19000000000000,
|
||||
19500000000000,
|
||||
20000000000000,
|
||||
20500000000000,
|
||||
21000000000000,
|
||||
21500000000000,
|
||||
22000000000000,
|
||||
22500000000000,
|
||||
23000000000000,
|
||||
23500000000000,
|
||||
24000000000000,
|
||||
24500000000000,
|
||||
25000000000000,
|
||||
25500000000000,
|
||||
26000000000000,
|
||||
26500000000000,
|
||||
27000000000000,
|
||||
27500000000000,
|
||||
28000000000000,
|
||||
28500000000000,
|
||||
29000000000000,
|
||||
29500000000000,
|
||||
30000000000000,
|
||||
30500000000000,
|
||||
31000000000000,
|
||||
31500000000000,
|
||||
32000000000000,
|
||||
32500000000000,
|
||||
33000000000000,
|
||||
33500000000000,
|
||||
34000000000000,
|
||||
34500000000000,
|
||||
35000000000000,
|
||||
35500000000000,
|
||||
36000000000000,
|
||||
36500000000000,
|
||||
37000000000000,
|
||||
37500000000000,
|
||||
38000000000000,
|
||||
38500000000000,
|
||||
39000000000000,
|
||||
39500000000000,
|
||||
40000000000000,
|
||||
40500000000000,
|
||||
41000000000000,
|
||||
41500000000000,
|
||||
42000000000000
|
||||
]
|
||||
}
|
||||
},
|
||||
"operational": {
|
||||
"temperature": 283,
|
||||
"raman_pumps": [
|
||||
{
|
||||
"power": 0.2,
|
||||
"frequency": 205000000000000,
|
||||
"propagation_direction": "counterprop"
|
||||
},
|
||||
{
|
||||
"power": 0.206,
|
||||
"frequency": 201000000000000,
|
||||
"propagation_direction": "counterprop"
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 1,
|
||||
"longitude": 0,
|
||||
"city": null,
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
{
|
||||
"raman_parameters": {
|
||||
"flag_raman": true,
|
||||
"space_resolution": 10e3,
|
||||
"tolerance": 1e-8
|
||||
"raman_params": {
|
||||
"flag": true,
|
||||
"result_spatial_resolution": 10e3,
|
||||
"solver_spatial_resolution": 50
|
||||
},
|
||||
"nli_parameters": {
|
||||
"nli_method_name": "ggn_spectrally_separated",
|
||||
"wdm_grid_size": 50e9,
|
||||
"nli_params": {
|
||||
"method": "ggn_spectrally_separated",
|
||||
"dispersion_tolerance": 1,
|
||||
"phase_shift_tolerance": 0.1,
|
||||
"computed_channels": [1, 18, 37, 56, 75]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -39,8 +39,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -64,8 +64,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
{
|
||||
"uid": "roadm Lannion_CAS",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -183,6 +184,7 @@
|
||||
{
|
||||
"uid": "roadm Lorient_KMA",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -207,6 +209,7 @@
|
||||
{
|
||||
"uid": "roadm Vannes_KBE",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -230,6 +233,7 @@
|
||||
{
|
||||
"uid": "roadm Rennes_STA",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -240,7 +244,6 @@
|
||||
"east edfa in Rennes_STA to Stbrieuc": -20,
|
||||
"east edfa in Rennes_STA to Ploermel": -20
|
||||
}
|
||||
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
@@ -254,6 +257,7 @@
|
||||
{
|
||||
"uid": "roadm Brest_KLA",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -277,6 +281,7 @@
|
||||
{
|
||||
"uid": "roadm a",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -302,6 +307,7 @@
|
||||
{
|
||||
"uid": "roadm b",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -310,7 +316,7 @@
|
||||
],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db":{
|
||||
"per_degree_pch_out_db": {
|
||||
"east edfa in b to a": -20,
|
||||
"east edfa in b to f": -20
|
||||
}
|
||||
@@ -327,13 +333,14 @@
|
||||
{
|
||||
"uid": "roadm c",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db":{
|
||||
"per_degree_pch_out_db": {
|
||||
"east edfa in c to a": -20,
|
||||
"east edfa in c to d": -20,
|
||||
"east edfa in c to f": -20
|
||||
@@ -351,6 +358,7 @@
|
||||
{
|
||||
"uid": "roadm d",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -374,6 +382,7 @@
|
||||
{
|
||||
"uid": "roadm e",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -397,6 +406,7 @@
|
||||
{
|
||||
"uid": "roadm f",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -421,6 +431,7 @@
|
||||
{
|
||||
"uid": "roadm g",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -430,7 +441,7 @@
|
||||
"per_degree_pch_out_db": {
|
||||
"east edfa in g to e": -20,
|
||||
"east edfa in g to h": -20
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
@@ -444,6 +455,7 @@
|
||||
{
|
||||
"uid": "roadm h",
|
||||
"type": "Roadm",
|
||||
"type_variety": "default",
|
||||
"params": {
|
||||
"target_pch_out_db": -20,
|
||||
"restrictions": {
|
||||
@@ -1593,7 +1605,7 @@
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 18.5,
|
||||
"gain_target": 13.177288,
|
||||
"delta_p": null,
|
||||
"tilt_target": 0,
|
||||
"out_voa": 0
|
||||
@@ -2235,7 +2247,7 @@
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": 6.5,
|
||||
"gain_target": 11.822712,
|
||||
"delta_p": null,
|
||||
"tilt_target": 0,
|
||||
"out_voa": 0
|
||||
@@ -2292,7 +2304,7 @@
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": 13.82,
|
||||
"gain_target": 13.822712,
|
||||
"delta_p": null,
|
||||
"tilt_target": 0,
|
||||
"out_voa": 0
|
||||
@@ -2311,7 +2323,7 @@
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 15.18,
|
||||
"gain_target": 15.177288,
|
||||
"delta_p": null,
|
||||
"tilt_target": 0,
|
||||
"out_voa": 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
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
|
||||
0,trx Lorient_KMA,trx Vannes_KBE,100.0,True,1,1,Voyager,mode 1,30.84,30.84,26.75,32.0,0.0,trx Lorient_KMA | roadm Lorient_KMA | east edfa in Lorient_KMA to Vannes_KBE | fiber (Lorient_KMA → Vannes_KBE)-F055 | west edfa in Vannes_KBE to Lorient_KMA | roadm Vannes_KBE | trx Vannes_KBE,"-284, 4",,,
|
||||
1,trx Brest_KLA,trx Vannes_KBE,10.0,True,1,1,Voyager,mode 1,22.65,22.11,18.03,32.0,1.0,trx Brest_KLA | roadm Brest_KLA | east edfa in Brest_KLA to Morlaix | fiber (Brest_KLA → Morlaix)-F060 | east fused spans in Morlaix | fiber (Morlaix → Lannion_CAS)-F059 | west edfa in Lannion_CAS to Morlaix | roadm Lannion_CAS | east edfa in Lannion_CAS to Corlay | fiber (Lannion_CAS → Corlay)-F061 | west fused spans in Corlay | fiber (Corlay → Loudeac)-F010 | west fused spans in Loudeac | fiber (Loudeac → Lorient_KMA)-F054 | west edfa in Lorient_KMA to Loudeac | roadm Lorient_KMA | east edfa in Lorient_KMA to Vannes_KBE | fiber (Lorient_KMA → Vannes_KBE)-F055 | west edfa in Vannes_KBE to Lorient_KMA | roadm Vannes_KBE | trx Vannes_KBE,"-276, 4",,,
|
||||
3,trx Lannion_CAS,trx Rennes_STA,60.0,True,1,1,vendorA_trx-type1,mode 1,28.29,25.85,21.77,32.0,1.0,trx Lannion_CAS | roadm Lannion_CAS | east edfa in Lannion_CAS to Stbrieuc | fiber (Lannion_CAS → Stbrieuc)-F056 | east edfa in Stbrieuc to Rennes_STA | fiber (Stbrieuc → Rennes_STA)-F057 | west edfa in Rennes_STA to Stbrieuc | roadm Rennes_STA | trx Rennes_STA,"-284, 4",,,
|
||||
4,trx Rennes_STA,trx Lannion_CAS,150.0,True,1,1,vendorA_trx-type1,mode 2,22.27,22.15,15.05,64.0,0.0,trx Rennes_STA | roadm Rennes_STA | east edfa in Rennes_STA to Ploermel | fiber (Rennes_STA → Ploermel)- | east edfa in Ploermel to Vannes_KBE | fiber (Ploermel → Vannes_KBE)- | west edfa in Vannes_KBE to Ploermel | roadm Vannes_KBE | east edfa in Vannes_KBE to Lorient_KMA | fiber (Vannes_KBE → Lorient_KMA)-F055 | west edfa in Lorient_KMA to Vannes_KBE | roadm Lorient_KMA | east edfa in Lorient_KMA to Loudeac | fiber (Lorient_KMA → Loudeac)-F054 | east fused spans in Loudeac | fiber (Loudeac → Corlay)-F010 | east fused spans in Corlay | fiber (Corlay → Lannion_CAS)-F061 | west edfa in Lannion_CAS to Corlay | roadm Lannion_CAS | trx Lannion_CAS,"-266, 6",,,
|
||||
5,trx Rennes_STA,trx Lannion_CAS,20.0,True,1,1,vendorA_trx-type1,mode 2,30.79,28.77,21.68,64.0,3.0,trx Rennes_STA | roadm Rennes_STA | east edfa in Rennes_STA to Stbrieuc | fiber (Rennes_STA → Stbrieuc)-F057 | west edfa in Stbrieuc to Rennes_STA | fiber (Stbrieuc → Lannion_CAS)-F056 | west edfa in Lannion_CAS to Stbrieuc | roadm Lannion_CAS | trx Lannion_CAS,"-274, 6",,,
|
||||
0,trx Lorient_KMA,trx Vannes_KBE,100.0,True,1,1,Voyager,mode 1,30.84,30.84,26.75,32.0,0.0,trx Lorient_KMA | roadm Lorient_KMA | east edfa in Lorient_KMA to Vannes_KBE | fiber (Lorient_KMA → Vannes_KBE)-F055 | west edfa in Vannes_KBE to Lorient_KMA | roadm Vannes_KBE | trx Vannes_KBE,"[-284], [4]",,,
|
||||
1,trx Brest_KLA,trx Vannes_KBE,10.0,True,1,1,Voyager,mode 1,22.65,22.11,18.03,32.0,1.0,trx Brest_KLA | roadm Brest_KLA | east edfa in Brest_KLA to Morlaix | fiber (Brest_KLA → Morlaix)-F060 | east fused spans in Morlaix | fiber (Morlaix → Lannion_CAS)-F059 | west edfa in Lannion_CAS to Morlaix | roadm Lannion_CAS | east edfa in Lannion_CAS to Corlay | fiber (Lannion_CAS → Corlay)-F061 | west fused spans in Corlay | fiber (Corlay → Loudeac)-F010 | west fused spans in Loudeac | fiber (Loudeac → Lorient_KMA)-F054 | west edfa in Lorient_KMA to Loudeac | roadm Lorient_KMA | east edfa in Lorient_KMA to Vannes_KBE | fiber (Lorient_KMA → Vannes_KBE)-F055 | west edfa in Vannes_KBE to Lorient_KMA | roadm Vannes_KBE | trx Vannes_KBE,"[-276], [4]",,,
|
||||
3,trx Lannion_CAS,trx Rennes_STA,60.0,True,1,1,vendorA_trx-type1,mode 1,28.29,25.85,21.77,32.0,1.0,trx Lannion_CAS | roadm Lannion_CAS | east edfa in Lannion_CAS to Stbrieuc | fiber (Lannion_CAS → Stbrieuc)-F056 | east edfa in Stbrieuc to Rennes_STA | fiber (Stbrieuc → Rennes_STA)-F057 | west edfa in Rennes_STA to Stbrieuc | roadm Rennes_STA | trx Rennes_STA,"[-284], [4]",,,
|
||||
4,trx Rennes_STA,trx Lannion_CAS,150.0,True,1,1,vendorA_trx-type1,mode 2,22.27,22.14,15.05,64.0,0.0,trx Rennes_STA | roadm Rennes_STA | east edfa in Rennes_STA to Ploermel | fiber (Rennes_STA → Ploermel)- | east edfa in Ploermel to Vannes_KBE | fiber (Ploermel → Vannes_KBE)- | west edfa in Vannes_KBE to Ploermel | roadm Vannes_KBE | east edfa in Vannes_KBE to Lorient_KMA | fiber (Vannes_KBE → Lorient_KMA)-F055 | west edfa in Lorient_KMA to Vannes_KBE | roadm Lorient_KMA | east edfa in Lorient_KMA to Loudeac | fiber (Lorient_KMA → Loudeac)-F054 | east fused spans in Loudeac | fiber (Loudeac → Corlay)-F010 | east fused spans in Corlay | fiber (Corlay → Lannion_CAS)-F061 | west edfa in Lannion_CAS to Corlay | roadm Lannion_CAS | trx Lannion_CAS,"[-266], [6]",,,
|
||||
5,trx Rennes_STA,trx Lannion_CAS,20.0,True,1,1,vendorA_trx-type1,mode 2,30.79,28.76,21.67,64.0,3.0,trx Rennes_STA | roadm Rennes_STA | east edfa in Rennes_STA to Stbrieuc | fiber (Rennes_STA → Stbrieuc)-F057 | west edfa in Stbrieuc to Rennes_STA | fiber (Stbrieuc → Lannion_CAS)-F056 | west edfa in Lannion_CAS to Stbrieuc | roadm Lannion_CAS | trx Lannion_CAS,"[-274], [6]",,,
|
||||
6,,,,NO_PATH,,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -14,8 +14,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -39,8 +39,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -104,8 +104,8 @@
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
@@ -129,8 +129,8 @@
|
||||
"trx_mode": "mode 2",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
@@ -154,8 +154,8 @@
|
||||
"trx_mode": "mode 2",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
@@ -179,8 +179,8 @@
|
||||
"trx_mode": "mode 2",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": "null",
|
||||
"M": "null"
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
|
||||
@@ -12,12 +12,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager_16QAM",
|
||||
"trx_mode": "16QAM",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
@@ -37,12 +31,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
@@ -62,12 +50,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
@@ -87,12 +69,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
@@ -133,12 +109,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 2 - fake",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": 0.001,
|
||||
@@ -158,12 +128,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 2",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": 0.001,
|
||||
@@ -183,12 +147,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
@@ -221,12 +179,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 3",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 62500000000.0,
|
||||
"max-nb-of-channel": 76,
|
||||
"output-power": 0.001,
|
||||
@@ -259,12 +211,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
@@ -284,12 +230,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
@@ -330,12 +270,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager_16QAM",
|
||||
"trx_mode": "16QAM",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": null,
|
||||
@@ -355,12 +289,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": 0.001,
|
||||
@@ -380,12 +308,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null,
|
||||
@@ -405,12 +327,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
@@ -451,12 +367,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": 0.001,
|
||||
@@ -476,12 +386,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": null,
|
||||
@@ -501,12 +405,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null,
|
||||
@@ -526,12 +424,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 75000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null,
|
||||
@@ -551,12 +443,6 @@
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"n": "null",
|
||||
"m": "null"
|
||||
}
|
||||
],
|
||||
"spacing": 30000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null,
|
||||
|
||||
97
tests/data/test_fiber_fix_expected_results.csv
Normal file
97
tests/data/test_fiber_fix_expected_results.csv
Normal file
@@ -0,0 +1,97 @@
|
||||
signal,nli
|
||||
1.9952623149688796e-05,1.0570305869494063e-08
|
||||
1.9952623149688796e-05,1.1989102199581664e-08
|
||||
1.9952623149688796e-05,1.2687787891259665e-08
|
||||
1.9952623149688796e-05,1.3153676763101585e-08
|
||||
1.9952623149688796e-05,1.3504001312414315e-08
|
||||
1.9952623149688796e-05,1.378517965356758e-08
|
||||
1.9952623149688796e-05,1.4020312829929705e-08
|
||||
1.9952623149688796e-05,1.4222564206194578e-08
|
||||
1.9952623149688796e-05,1.440014394542033e-08
|
||||
1.9952623149688796e-05,1.4558516068269932e-08
|
||||
1.9952623149688796e-05,1.4701499315172012e-08
|
||||
1.9952623149688796e-05,1.4831866587815758e-08
|
||||
1.9952623149688796e-05,1.4951694168451522e-08
|
||||
1.9952623149688796e-05,1.506257639956634e-08
|
||||
1.9952623149688796e-05,1.5165763570833366e-08
|
||||
1.9952623149688796e-05,1.5262253772723937e-08
|
||||
1.9952623149688796e-05,1.535285600134073e-08
|
||||
1.9952623149688796e-05,1.543823467328411e-08
|
||||
1.9952623149688796e-05,1.551894175425445e-08
|
||||
1.9952623149688796e-05,1.5595440417063968e-08
|
||||
1.9952623149688796e-05,1.5668122772822936e-08
|
||||
1.9952623149688796e-05,1.5737323370281063e-08
|
||||
1.9952623149688796e-05,1.5803329618444796e-08
|
||||
1.9952623149688796e-05,1.5866389935670908e-08
|
||||
1.9952623149688796e-05,1.592672019391794e-08
|
||||
1.9952623149688796e-05,1.598450886742589e-08
|
||||
1.9952623149688796e-05,1.6039921184766554e-08
|
||||
1.9952623149688796e-05,1.609310250559421e-08
|
||||
1.9952623149688796e-05,1.61441810880001e-08
|
||||
1.9952623149688796e-05,1.6193270372246937e-08
|
||||
1.9952623149688796e-05,1.6240470877236143e-08
|
||||
1.9952623149688796e-05,1.6285871784230113e-08
|
||||
1.9952623149688796e-05,1.6329552265978812e-08
|
||||
1.9952623149688796e-05,1.6371582606990462e-08
|
||||
1.9952623149688796e-05,1.641202515119326e-08
|
||||
1.9952623149688796e-05,1.6450935105904177e-08
|
||||
1.9952623149688796e-05,1.6488361225310858e-08
|
||||
1.9952623149688796e-05,1.6524346392188574e-08
|
||||
1.9952623149688796e-05,1.6558928113022246e-08
|
||||
1.9952623149688796e-05,1.6592138938867027e-08
|
||||
1.9952623149688796e-05,1.6624006821997905e-08
|
||||
1.9952623149688796e-05,1.665455541654349e-08
|
||||
1.9952623149688796e-05,1.668380432977811e-08
|
||||
1.9952623149688796e-05,1.6711769329485368e-08
|
||||
1.9952623149688796e-05,1.6738462511750264e-08
|
||||
1.9952623149688796e-05,1.6763892432637406e-08
|
||||
1.9952623149688796e-05,1.6788064206436675e-08
|
||||
1.9952623149688796e-05,1.681097957247311e-08
|
||||
1.9952623149688796e-05,1.6832636931862217e-08
|
||||
1.9952623149688796e-05,1.6853031355021186e-08
|
||||
1.9952623149688796e-05,1.687215456020574e-08
|
||||
1.9952623149688796e-05,1.688999486281053e-08
|
||||
1.9952623149688796e-05,1.690653709463382e-08
|
||||
1.9952623149688796e-05,1.6921762491746848e-08
|
||||
1.9952623149688796e-05,1.6935648549006222e-08
|
||||
1.9952623149688796e-05,1.6948168838584662e-08
|
||||
1.9952623149688796e-05,1.695929278914847e-08
|
||||
1.9952623149688796e-05,1.696898542145055e-08
|
||||
1.9952623149688796e-05,1.6977207035104874e-08
|
||||
1.9952623149688796e-05,1.6983912840119302e-08
|
||||
1.9952623149688796e-05,1.6989052525338295e-08
|
||||
1.9952623149688796e-05,1.699256975421989e-08
|
||||
1.9952623149688796e-05,1.6994401576260005e-08
|
||||
1.9952623149688796e-05,1.6994477739772384e-08
|
||||
1.9952623149688796e-05,1.699271988849318e-08
|
||||
1.9952623149688796e-05,1.6989040620420942e-08
|
||||
1.9952623149688796e-05,1.6983342382173362e-08
|
||||
1.9952623149688796e-05,1.6975516165613388e-08
|
||||
1.9952623149688796e-05,1.6965439965112504e-08
|
||||
1.9952623149688796e-05,1.6952976942961452e-08
|
||||
1.9952623149688796e-05,1.693797323625088e-08
|
||||
1.9952623149688796e-05,1.6920255319826076e-08
|
||||
1.9952623149688796e-05,1.6899626814970685e-08
|
||||
1.9952623149688796e-05,1.6875864599859146e-08
|
||||
1.9952623149688796e-05,1.6848714031984708e-08
|
||||
1.9952623149688796e-05,1.6817883029489423e-08
|
||||
1.9952623149688796e-05,1.6783034669737056e-08
|
||||
1.9952623149688796e-05,1.674377783759437e-08
|
||||
1.9952623149688796e-05,1.669965527407164e-08
|
||||
1.9952623149688796e-05,1.6650128108596616e-08
|
||||
1.9952623149688796e-05,1.6594555557112625e-08
|
||||
1.9952623149688796e-05,1.6532167853144137e-08
|
||||
1.9952623149688796e-05,1.6462029512327026e-08
|
||||
1.9952623149688796e-05,1.6382988469074245e-08
|
||||
1.9952623149688796e-05,1.6293604020234886e-08
|
||||
1.9952623149688796e-05,1.619204201130206e-08
|
||||
1.9952623149688796e-05,1.607591759753518e-08
|
||||
1.9952623149688796e-05,1.5942050594874486e-08
|
||||
1.9952623149688796e-05,1.578606776895102e-08
|
||||
1.9952623149688796e-05,1.5601720601345105e-08
|
||||
1.9952623149688796e-05,1.5379633197361104e-08
|
||||
1.9952623149688796e-05,1.5104793671989548e-08
|
||||
1.9952623149688796e-05,1.4750892345803154e-08
|
||||
1.9952623149688796e-05,1.4265134295425351e-08
|
||||
1.9952623149688796e-05,1.3514359541675816e-08
|
||||
1.9952623149688796e-05,1.194579997186553e-08
|
||||
|
6
tests/data/test_fiber_flex_expected_results.csv
Normal file
6
tests/data/test_fiber_flex_expected_results.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
signal,nli
|
||||
1.9952623149688796e-05,5.183134799604202e-09
|
||||
1.7957360834719913e-05,4.286200408629989e-09
|
||||
2.593841009459543e-05,6.2510001955285065e-09
|
||||
1.5962098519751036e-05,4.082332034495425e-09
|
||||
2.3943147779626556e-05,7.857762167195498e-09
|
||||
|
809
tests/data/test_long_network.json
Normal file
809
tests/data/test_long_network.json
Normal file
@@ -0,0 +1,809 @@
|
||||
{
|
||||
"network_name": "Example Network - long path",
|
||||
"elements": [{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site A",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "booster A",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span2",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa2",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span3",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa3",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span4",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa4",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span5",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa5",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site C",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "booster C",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span6",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa6",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span7",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa7",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span8",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa8",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span9",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa9",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span10",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa10",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site D",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "booster D",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span11",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa11",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span12",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa12",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site E",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "booster E",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span13",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa13",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span14",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa14",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span15",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa15",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site B",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "",
|
||||
"latitude": 3,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
],
|
||||
"connections": [{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "roadm Site A"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site A",
|
||||
"to_node": "booster A"
|
||||
},
|
||||
{
|
||||
"from_node": "booster A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Span2"
|
||||
},
|
||||
{
|
||||
"from_node": "Span2",
|
||||
"to_node": "Edfa2"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa2",
|
||||
"to_node": "Span3"
|
||||
},
|
||||
{
|
||||
"from_node": "Span3",
|
||||
"to_node": "Edfa3"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa3",
|
||||
"to_node": "Span4"
|
||||
},
|
||||
{
|
||||
"from_node": "Span4",
|
||||
"to_node": "Edfa4"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa4",
|
||||
"to_node": "Span5"
|
||||
},
|
||||
{
|
||||
"from_node": "Span5",
|
||||
"to_node": "Edfa5"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa5",
|
||||
"to_node": "roadm Site C"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site C",
|
||||
"to_node": "booster C"
|
||||
},
|
||||
{
|
||||
"from_node": "booster C",
|
||||
"to_node": "Span6"
|
||||
},
|
||||
{
|
||||
"from_node": "Span6",
|
||||
"to_node": "Edfa6"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa6",
|
||||
"to_node": "Span7"
|
||||
},
|
||||
{
|
||||
"from_node": "Span7",
|
||||
"to_node": "Edfa7"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa7",
|
||||
"to_node": "Span8"
|
||||
},
|
||||
{
|
||||
"from_node": "Span8",
|
||||
"to_node": "Edfa8"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa8",
|
||||
"to_node": "Span9"
|
||||
},
|
||||
{
|
||||
"from_node": "Span9",
|
||||
"to_node": "Edfa9"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa9",
|
||||
"to_node": "Span10"
|
||||
},
|
||||
{
|
||||
"from_node": "Span10",
|
||||
"to_node": "Edfa10"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa10",
|
||||
"to_node": "roadm Site D"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site D",
|
||||
"to_node": "booster D"
|
||||
},
|
||||
{
|
||||
"from_node": "booster D",
|
||||
"to_node": "Span11"
|
||||
},
|
||||
{
|
||||
"from_node": "Span11",
|
||||
"to_node": "Edfa11"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa11",
|
||||
"to_node": "Span12"
|
||||
},
|
||||
{
|
||||
"from_node": "Span12",
|
||||
"to_node": "Edfa12"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa12",
|
||||
"to_node": "roadm Site E"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site E",
|
||||
"to_node": "booster E"
|
||||
},
|
||||
{
|
||||
"from_node": "booster E",
|
||||
"to_node": "Span13"
|
||||
},
|
||||
{
|
||||
"from_node": "Span13",
|
||||
"to_node": "Edfa13"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa13",
|
||||
"to_node": "Span14"
|
||||
},
|
||||
{
|
||||
"from_node": "Span14",
|
||||
"to_node": "Edfa14"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa14",
|
||||
"to_node": "Span15"
|
||||
},
|
||||
{
|
||||
"from_node": "Span15",
|
||||
"to_node": "Edfa15"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa15",
|
||||
"to_node": "roadm Site B"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site B",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
]
|
||||
}
|
||||
96
tests/data/test_lumped_losses_fiber_no_pumps.csv
Normal file
96
tests/data/test_lumped_losses_fiber_no_pumps.csv
Normal file
@@ -0,0 +1,96 @@
|
||||
0.001,0.0007537739940510926,0.0005921033539224395,0.000384643453726324,0.00024710943492700773,0.00015765779381207088,0.00010015276356884663,6.345008665672524e-05,4.012925332336102e-05,2.535268958174273e-05
|
||||
0.001,0.0007532443480762404,0.0005915606741358828,0.00038408573214392957,0.00024666764094038643,0.00015734224135307426,9.993879038586218e-05,6.330912140259024e-05,4.003794165686942e-05,2.529414108865862e-05
|
||||
0.001,0.0007527148738848327,0.0005910183036445593,0.0003835286706438232,0.0002462265418760313,0.00015702726304657165,9.972523988324127e-05,6.316844848796591e-05,3.994682503096186e-05,2.5235719950422228e-05
|
||||
0.001,0.0007521855703345118,0.0005904762413907948,0.00038297226807207136,0.0002457861365766504,0.00015671285789580896,9.9512111295817e-05,6.302806736731544e-05,3.985590307420444e-05,2.5177425921282973e-05
|
||||
0.001,0.0007516564362539944,0.0005899344862777934,0.00038241652320864807,0.0002453464238190796,0.00015639902485083639,9.929940381972637e-05,6.288797746852316e-05,3.976517539750482e-05,2.511925874398998e-05
|
||||
0.001,0.0007511274704431355,0.0005893930371697809,0.0003818614347679428,0.0002449074023149522,0.00015608576280913723,9.908711661290977e-05,6.27481781932559e-05,3.967464159435973e-05,2.5061218149955632e-05
|
||||
0.001,0.0007505986716729718,0.0005888518928921378,0.00038130700139925517,0.0002444690707113658,0.00015577307061625246,9.887524879560432e-05,6.260866891731864e-05,3.958430124109855e-05,2.5003303859417958e-05
|
||||
0.001,0.0007500678710880661,0.0005883088511431218,0.000380751009486411,0.0002440296996901373,0.00015545972380501664,9.866297459432463e-05,6.246890748950651e-05,3.949380391318895e-05,2.4945291488462056e-05
|
||||
0.001,0.0007495350705096461,0.0005877639154939723,0.000380193466563788,0.00024358929686534952,0.00015514572847430736,9.8450298405315e-05,6.232889690863924e-05,3.9403151593579556e-05,2.4887182324516918e-05
|
||||
0.001,0.0007490002717484986,0.0005872170894971442,0.00037963438011605534,0.00024314786979147204,0.00015483109067004745,9.823722458416644e-05,6.218864014470764e-05,3.931234624568946e-05,2.4828977642138712e-05
|
||||
0.001,0.0007484634766050366,0.000586668376686434,0.0003790737575785661,0.00024270542596389042,0.0001545158163857142,9.802375744622405e-05,6.204814013916893e-05,3.9221389813611975e-05,2.4770678703146694e-05
|
||||
0.001,0.0007479199274773811,0.0005861128912299699,0.0003785065486556895,0.00024225795000622747,0.0001541970308568484,9.780794472023814e-05,6.190610951865765e-05,3.9129447888412384e-05,2.471175028700643e-05
|
||||
0.001,0.0007473696306726699,0.0005855506450602122,0.0003779327791658341,0.00024180546890527417,0.0001538747562360148,9.758980264023896e-05,6.176255947727244e-05,3.903652792388679e-05,2.4652197254708885e-05
|
||||
0.001,0.0007468125926679213,0.0005849816503235855,0.0003773524752207052,0.00024134800990073543,0.00015354901486124996,9.736934756691086e-05,6.161750129261558e-05,3.8942637427869684e-05,2.459202450185328e-05
|
||||
0.001,0.0007462488201102061,0.0005844059193804029,0.00037676566322402907,0.00024088560048334876,0.0001532198292542639,9.714659598616437e-05,6.147094632476142e-05,3.884778396152801e-05,2.4531236958179027e-05
|
||||
0.001,0.0007456783198168171,0.0005838234648047683,0.00037617236987025305,0.00024041826839299018,0.00015288722211863548,9.692156450770277e-05,6.132290601522212e-05,3.875197513865345e-05,2.4469839587096592e-05
|
||||
0.001,0.0007451010987754332,0.0005832342993844907,0.0003755726221432343,0.0002399460416167659,0.00015255121633799497,9.66942698635831e-05,6.11733918859104e-05,3.8655218624953314e-05,2.4407837385217267e-05
|
||||
0.001,0.0007445173992825126,0.0005826386743528757,0.00037496668540476865,0.00023946913369259697,0.00015221196586566552,9.646481704279825e-05,6.102247334575324e-05,3.85575594785277e-05,2.4345259282747418e-05
|
||||
0.001,0.0007439272282773631,0.0005820366023339485,0.0003743545861363169,0.00023898757201912962,0.00015186949307274757,9.623322238874437e-05,6.0870161643097905e-05,3.845900518061352e-05,2.4282110155051444e-05
|
||||
0.001,0.0007433305928659832,0.0005814280961601982,0.00037373635109929905,0.0002385013842326201,0.0001515238205025659,9.599950236146117e-05,6.071646810276464e-05,3.835956326175255e-05,2.4218394908993806e-05
|
||||
0.001,0.0007427275003211868,0.0005808131688724332,0.0003731120073337174,0.00023801059820498021,0.0001511749708688244,9.576367353617374e-05,6.05614041249978e-05,3.825924130107498e-05,2.4154118482464792e-05
|
||||
0.001,0.0007421180800523362,0.0005801919587229117,0.00037248171070273063,0.0002375153439047009,0.00015082303982525373,9.55258019540184e-05,6.0405013700224733e-05,3.815806798909622e-05,2.4089299350133826e-05
|
||||
0.001,0.0007415023395254894,0.0005795644789202474,0.00037184548827748576,0.0002370156491221818,0.00015046804996987382,9.528590408468248e-05,6.0247308147258e-05,3.8056050847170796e-05,2.4023942410771268e-05
|
||||
0.001,0.0007408802863797739,0.000578930742889133,0.00037120336741830446,0.00023651154189285886,0.00015011002407818366,9.504399651802114e-05,6.008829886368558e-05,3.7953197447440844e-05,2.395805259559495e-05
|
||||
0.001,0.0007402519284274773,0.00057829076427012,0.0003705553757730914,0.00023600305049498863,0.0001497489851010917,9.480009596242987e-05,5.992799732470356e-05,3.784951541204015e-05,2.389163486774317e-05
|
||||
0.001,0.0007396172736541335,0.0005776445569193926,0.0003699015412757306,0.000235490203447419,0.00014938495616282697,9.455421924320194e-05,5.976641508193571e-05,3.774501241228877e-05,2.38246942217421e-05
|
||||
0.001,0.0007389763302186035,0.0005769921349085269,0.00036924189214444916,0.00023497302950733012,0.00014901796055883247,9.4306383300876e-05,5.960356376224896e-05,3.763969616788547e-05,2.37572356829714e-05
|
||||
0.001,0.000738329973009011,0.0005763343882557762,0.00036857732657886674,0.00023445223185895243,0.00014864849677321228,9.40569245366171e-05,5.943966431343476e-05,3.753370952478887e-05,2.3689350732036766e-05
|
||||
0.001,0.0007376782088319843,0.0005756713289449496,0.0003679078688863157,0.00023392783529630037,0.00014827658488585004,9.38058575472753e-05,5.927472675087035e-05,3.7427059131368685e-05,2.362104369630353e-05
|
||||
0.001,0.0007370210446325295,0.0005750029691304239,0.000367233543593211,0.00023339986479263558,0.00014790224510292775,9.355319701349314e-05,5.910876114408311e-05,3.7319751670569666e-05,2.3552318925085614e-05
|
||||
0.001,0.0007363584874940915,0.0005743293211369546,0.0003665543754437431,0.00023286834549865966,0.00014752549775524457,9.329895769838934e-05,5.8941777615809794e-05,3.721179385927125e-05,2.348318078922229e-05
|
||||
0.001,0.0007356906659117175,0.0005736505214206793,0.00036587051603697917,0.00023233340267585003,0.00014714643450378646,9.30432026577021e-05,5.8773818072131705e-05,3.710321298927822e-05,2.3413646846771747e-05
|
||||
0.001,0.0007350175870680764,0.0005729665823498456,0.00036518198995355594,0.00023179506120909636,0.00014676507541963834,9.278594644638945e-05,5.8604892484780656e-05,3.699401567385024e-05,2.3343721399750524e-05
|
||||
0.001,0.000734339258284937,0.0005722775164633901,0.0003644888219905243,0.00023125334615855053,0.0001463814406964208,9.252720370024704e-05,5.8435010877524154e-05,3.688420855938328e-05,2.327340877117354e-05
|
||||
0.001,0.0007336556870231954,0.0005715833364706749,0.00036379103715988533,0.00023070828275766533,0.00014599555064848363,9.226698913450141e-05,5.82641833251609e-05,3.677379832472749e-05,2.320271330460301e-05
|
||||
0.001,0.0007329668808828947,0.0005708840552512191,0.00036308866068712113,0.00023015989641122435,0.00014560742570909416,9.200531754239911e-05,5.8092419952513674e-05,3.666279168050168e-05,2.313163936369656e-05
|
||||
0.001,0.000732272847603227,0.0005701796858544125,0.000362381718009681,0.0002296082126933358,0.00014521708642859763,9.174220379377606e-05,5.791973093340874e-05,3.6551195368400524e-05,2.3060191331749373e-05
|
||||
0.001,0.0007315751779154508,0.0005694718366517781,0.00036167180797618383,0.00022905447155647377,0.00014482540661409508,9.147823538482221e-05,5.774650123146614e-05,3.643925790598459e-05,2.2988528215049473e-05
|
||||
0.001,0.0007308738763564251,0.0005687605159526348,0.00036095894758939165,0.00022849869020493823,0.00014443240010265552,9.121342232553745e-05,5.7572737692798364e-05,3.6326983828340116e-05,2.2916652961499898e-05
|
||||
0.001,0.0007301689475478705,0.0005680457321686527,0.00036024315397386176,0.00022794088593578913,0.00014403808079282816,9.094777466478586e-05,5.739844718775089e-05,3.6214377685641065e-05,2.2844568528419092e-05
|
||||
0.001,0.0007294603961963875,0.0005673274938137002,0.0003595244443750873,0.00022738107613769066,0.00014364246264358423,9.068130248947494e-05,5.72236366103174e-05,3.610144404275241e-05,2.2772277882278848e-05
|
||||
0.001,0.0007287502876018436,0.0005666079096289159,0.00035880496633647314,0.00022682095171468864,0.00014324674865159545,9.041481948469436e-05,5.7048841153261715e-05,3.598852922211342e-05,2.270000293927642e-05
|
||||
0.001,0.0007280386231103084,0.0005658869826353605,0.0003580847262718071,0.00022626051891339797,0.00014285094367250402,9.014832907727154e-05,5.687406312117876e-05,3.587563473352017e-05,2.2627744673782604e-05
|
||||
0.001,0.0007273254041056322,0.0005651647158992671,0.00035736373064750184,0.00022569978402038908,0.00014245505258865028,8.988183471111395e-05,5.669930482943582e-05,3.5762762093538084e-05,2.2555504064421286e-05
|
||||
0.001,0.0007266106320094578,0.0005644411125319691,0.00035664198598218,0.00022513875336164715,0.0001420590803085807,8.961533984682783e-05,5.652456860390248e-05,3.564991282531874e-05,2.2483282093948716e-05
|
||||
0.001,0.000725894308281204,0.0005637161756897977,0.0003559194988462394,0.00022457743330201225,0.00014166303176654256,8.934884796133105e-05,5.634985678067539e-05,3.5537088458413665e-05,2.2411079749130865e-05
|
||||
0.001,0.0007251764344180624,0.0005629899085739927,0.00035519627586142176,0.0002240158302446243,0.00014126691192198565,8.90823625474685e-05,5.6175171705805915e-05,3.542429052859005e-05,2.233889802062196e-05
|
||||
0.001,0.0007244588135748975,0.0005622641246704724,0.00035447409591105305,0.0002234553120905153,0.00014087167955905718,8.881652603390643e-05,5.600093342830372e-05,3.531178983274928e-05,2.2266910019981595e-05
|
||||
0.001,0.000723741443178776,0.000561538821268995,0.0003537529553873339,0.00022289587522719752,0.00014047733166655684,8.855133617099835e-05,5.5827140373801375e-05,3.519958531186087e-05,2.219511505192651e-05
|
||||
0.001,0.0007230243206833482,0.0005608139956950427,0.00035303285074046774,0.00022233751609917817,0.00014008386527925162,8.82867907426191e-05,5.565379099102327e-05,3.508767592227262e-05,2.212351243120618e-05
|
||||
0.001,0.0007223074435688039,0.0005600896453097011,0.0003523137784782074,0.00022178023120736695,0.00013969127747733319,8.802288756574066e-05,5.5480883751481105e-05,3.4976060635503277e-05,2.2052101482465692e-05
|
||||
0.001,0.0007215926247557181,0.0005593676122940626,0.00035159759247597197,0.00022122546934306127,0.00013930059415776796,8.776031848020719e-05,5.5308872854303e-05,3.486503301641155e-05,2.198107017600086e-05
|
||||
0.001,0.0007208798585848073,0.0005586478889723664,0.0003508842795507963,0.0002206732171528304,0.00013891180440309996,8.749907547557891e-05,5.513775276548628e-05,3.475458937431628e-05,2.1910416102241813e-05
|
||||
0.001,0.0007201691394257483,0.000557930467712979,0.00035017382661216696,0.00022012346138632064,0.00013852489738482468,8.723915060881119e-05,5.49675179985075e-05,3.464472605058592e-05,2.184013687270143e-05
|
||||
0.001,0.0007194604616770773,0.00055721534092818,0.00034946622066134466,0.00021957618889536463,0.00013813986236255893,8.698053600359808e-05,5.4798163113848986e-05,3.453543941831367e-05,2.177023011975932e-05
|
||||
0.001,0.0007187538197660722,0.0005565025010739346,0.00034876144879066544,0.00021903138663308575,0.0001377566886832086,8.672322384971475e-05,5.462968271852315e-05,3.442672588199151e-05,2.1700693496445714e-05
|
||||
0.001,0.0007180492081486484,0.0005557919406496801,0.00034805949818288173,0.0002184890416530366,0.00013737536578016266,8.646720640237894e-05,5.446207146561145e-05,3.431858187719449e-05,2.1631524676231647e-05
|
||||
0.001,0.000717348639431565,0.0005550856739198547,0.00034736232071304855,0.00021795064331956514,0.00013699693247692832,8.621317757037385e-05,5.429578217858938e-05,3.421129897003673e-05,2.1562909902755936e-05
|
||||
0.001,0.0007166521035756881,0.0005543836868927082,0.0003466698924934393,0.00021741616794755068,0.00013662136971116798,8.596112351100096e-05,5.413080535731451e-05,3.410487085131832e-05,2.1494845067789903e-05
|
||||
0.001,0.0007159595906065037,0.0005536859656730149,0.00034598218983055497,0.0002168855920630381,0.0001362486585998701,8.571103051605296e-05,5.396713159578493e-05,3.399929127512844e-05,2.142732610463052e-05
|
||||
0.001,0.0007152710906138687,0.0005529924964615861,0.00034529918922366796,0.00021635889240138666,0.0001358787804376394,8.546288501047042e-05,5.380475158117202e-05,3.389455405818364e-05,2.1360348987661796e-05
|
||||
0.001,0.0007145881681833736,0.0005523048607339887,0.0003446224616264519,0.00021583728670966556,0.00013551259312919557,8.521726369129195e-05,5.364404315662281e-05,3.379090310339315e-05,2.129406976339983e-05
|
||||
0.001,0.0007139108109389651,0.0005516230407004492,0.0003439519758859039,0.00021532074399295122,0.00013515007172518374,8.497414844816332e-05,5.3484993898260945e-05,3.368833016244125e-05,2.122848306212633e-05
|
||||
0.001,0.0007132390066148024,0.0005509470187317473,0.00034328770115903844,0.00021480923358720733,0.0001347911915544671,8.473352137819455e-05,5.3327591526929936e-05,3.358682708410006e-05,2.1163583577742056e-05
|
||||
0.001,0.0007125727430549207,0.0005502767773585094,0.000342629606910633,0.00021430272515636744,0.0001344359282214269,8.449536478383494e-05,5.317182390666476e-05,3.348638581318404e-05,2.109936606707349e-05
|
||||
0.001,0.0007119120082129148,0.0005496122992705212,0.0003419776629110174,0.0002138011886894788,0.00013408425760331254,8.425966117078749e-05,5.3017679043188334e-05,3.3386998389521964e-05,2.1035825349191292e-05
|
||||
0.001,0.000711256790151613,0.0005489535673160376,0.0003413318392338714,0.00021330459449785352,0.00013373615584760944,8.40263932459383e-05,5.286514508242194e-05,3.3288656946938245e-05,2.0972956304734848e-05
|
||||
0.001,0.0007106071943639499,0.0005483006816957998,0.00034069221933208274,0.0002128129992904075,0.00013339165932644894,8.379558393280961e-05,5.271423641048183e-05,3.31913705135711e-05,2.091076460544407e-05
|
||||
0.001,0.000709963208882901,0.0005476536252143895,0.0003400587732671483,0.0002123263734210078,0.00013305074425072359,8.356721599784782e-05,5.256494122003263e-05,3.3095131256746724e-05,2.0849245154782437e-05
|
||||
0.001,0.0007093248218486061,0.0005470123808316875,0.00033943147139689077,0.0002118446875576196,0.00013271338709432742,8.334127240311385e-05,5.241724783997488e-05,3.299993143509595e-05,2.0788392916005465e-05
|
||||
0.001,0.0007086920215080653,0.0005463769316622218,0.0003388102843733889,0.00021136791267964032,0.0001323795645916927,8.311773630434548e-05,5.2271144734051514e-05,3.290576339760186e-05,2.07282029115292e-05
|
||||
0.001,0.0007080656480431051,0.0005457481216341828,0.0003381960373995552,0.00021089668206097172,0.0001320497200486003,8.289690449717853e-05,5.2126825862102536e-05,3.2812752146082854e-05,2.0668755034757233e-05
|
||||
0.001,0.0007074456886869565,0.0005451259321489777,0.0003375886977799707,0.0002104309633113142,0.00013172382748945162,8.26787581753205e-05,5.198427834496719e-05,3.2720889139431744e-05,2.061004372929991e-05
|
||||
0.001,0.0007068321308093747,0.0005445103448031184,0.0003369882331820464,0.00020997072442018424,0.00013140186125447996,8.246327876643199e-05,5.18434894660219e-05,3.2630165945308436e-05,2.055206350992823e-05
|
||||
0.001,0.0007062249619162967,0.0005439013413874698,0.00033639461163356655,0.00020951593375373114,0.00013108379599680725,8.225044792981545e-05,5.170444666951808e-05,3.254057423900392e-05,2.0494808961820763e-05
|
||||
0.001,0.00070562416964951,0.0005432989038865089,0.00033580780152024723,0.000209066560051587,0.00013076960667953474,8.204024755412909e-05,5.156713755893784e-05,3.2452105802317056e-05,2.0438274739819433e-05
|
||||
0.001,0.0007050297417863318,0.0005427030144775926,0.0003352277715833316,0.00020862257242375786,0.00013045926857287288,8.183265975513502e-05,5.143154989537623e-05,3.236475252244954e-05,2.038245556769746e-05
|
||||
0.001,0.0007044417829621171,0.000542113771820027,0.0003346546023905152,0.00020818402485557293,0.00013015281596227648,8.162770599537212e-05,5.129769708700084e-05,3.227852278867728e-05,2.032735670561579e-05
|
||||
0.001,0.0007038602809995153,0.0005415311581470623,0.00033408826282687573,0.00020775088664703998,0.00012985022429639665,8.142536853201701e-05,5.116556699709043e-05,3.219340855821242e-05,2.0272972923816322e-05
|
||||
0.001,0.0007032852238493367,0.0005409551558747416,0.0003335287221154158,0.00020732312745044945,0.00012955146931603386,8.122562983828357e-05,5.103514763884953e-05,3.2109401888525124e-05,2.0219299058105656e-05
|
||||
0.001,0.0007027165995902542,0.0005403857476012292,0.00033297594981485264,0.00020690071726752732,0.0001292565270515082,8.102847260135871e-05,5.090642717392409e-05,3.202649493632917e-05,2.0166330009182866e-05
|
||||
0.001,0.0007021546252265139,0.0005398231466905069,0.00033243014325207994,0.00020648380199548492,0.0001289654971719027,8.083396250547584e-05,5.077944809587575e-05,3.194471491165552e-05,2.0114083097018264e-05
|
||||
0.001,0.0007015992888126556,0.0005392673356287205,0.0003318912717105927,0.00020607235137144977,0.0001286783555062261,8.06420820982489e-05,5.065419847368218e-05,3.186405391103787e-05,2.006255318369691e-05
|
||||
0.001,0.0007010505785332368,0.0005387182970867077,0.00033135930481238495,0.00020566633548374424,0.0001283950781739038,8.04528141416734e-05,5.053066652493675e-05,3.1784504130324826e-05,2.001173519622426e-05
|
||||
0.001,0.000700508482702546,0.0005381760139193414,0.00033083421251577956,0.00020526572476908743,0.000128115641582197,8.026614161010359e-05,5.040884061439589e-05,3.170605786368809e-05,1.9961624125869314e-05
|
||||
0.001,0.0006999729897643184,0.0005376404691648787,0.00033031596511327947,0.00020487049000982136,0.00012784002242364822,8.008204768824872e-05,5.028870925253973e-05,3.1628707502639986e-05,1.9912215027513866e-05
|
||||
0.001,0.0006994440882914515,0.0005371116460443127,0.0003298045332294241,0.0002044806023311588,0.0001275681976735486,7.990051576919067e-05,5.0170261094149856e-05,3.155244553506268e-05,1.9863503019009735e-05
|
||||
0.001,0.0006989172535560769,0.0005365850419669894,0.000329295612913881,0.00020409280438264766,0.00012729790663346764,7.972004038787022e-05,5.0052515589855926e-05,3.147664135129994e-05,1.9815085586326718e-05
|
||||
0.001,0.0006983924815322933,0.0005360606511477293,0.0003287891938968759,0.00020370708584067882,0.00012702914094133737,7.954061545150935e-05,4.993546855036179e-05,3.140129216611291e-05,1.9766960914662127e-05
|
||||
0.001,0.0006978697681747856,0.000535538467781285,0.000328285265898271,0.00020332343638453147,0.00012676189224377013,7.936223487646896e-05,4.981911579385119e-05,3.1326395199731696e-05,1.971912719297887e-05
|
||||
0.001,0.0006973491094188342,0.0005350184860423863,0.0003277838186277228,0.0002029418456965422,0.0001264961521961901,7.918489258833681e-05,4.970345314604528e-05,3.125194767789152e-05,1.967158261402843e-05
|
||||
0.001,0.0006968284099289676,0.000534498597351666,0.00032728277956097635,0.00020256071739357045,0.0001262308004979493,7.900783730702533e-05,4.958798911408524e-05,3.1177632631488905e-05,1.9624124503146986e-05
|
||||
0.001,0.0006963076677967887,0.0005339787996978908,0.00032678214616920946,0.00020218004908417888,0.0001259658352285323,7.883106763041168e-05,4.947272273059253e-05,3.110344941552445e-05,1.957675243920473e-05
|
||||
0.001,0.0006957868810888677,0.0005334590910383602,0.00032628191587964447,0.00020179983833834103,0.00012570125443876325,7.865458213663353e-05,4.935765301510161e-05,3.102939737649859e-05,1.9529465995615212e-05
|
||||
0.001,0.0006952660478468047,0.0005329394692990367,0.0003257820860759608,0.00020142008268794192,0.0001254370561512512,7.847837938443003e-05,4.924277897429975e-05,3.0955475852573814e-05,1.94822647404421e-05
|
||||
0.001,0.00069474516608728,0.0005324199323746772,0.00032528265409871067,0.0002010407796272818,0.0001251732383608348,7.830245791348127e-05,4.91280996022673e-05,3.088168417373684e-05,1.943514823650581e-05
|
||||
|
96
tests/data/test_lumped_losses_fiber_no_raman.csv
Normal file
96
tests/data/test_lumped_losses_fiber_no_raman.csv
Normal file
@@ -0,0 +1,96 @@
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
1.000000000000000021e-03,6.456542290346556703e-04,2.238721138568339957e-05
|
||||
|
98
tests/data/test_lumped_losses_raman_fiber.csv
Normal file
98
tests/data/test_lumped_losses_raman_fiber.csv
Normal file
@@ -0,0 +1,98 @@
|
||||
0.001,0.0007651928200015371,0.0006070713937965498,0.00041423535558437785,0.0002897888610631573,0.00021340907299884933,0.00017198131811953097,0.00016127923791982795,0.00019503601408127412,0.00036549739730595273
|
||||
0.001,0.0007645995806173374,0.0006064422887178694,0.00041349144049413134,0.00028906380160320487,0.00021270693331134475,0.0001712438796411692,0.0001603765556252246,0.00019363496213474675,0.00036239423700181427
|
||||
0.001,0.0007640065772643761,0.0006058136176614386,0.00041274866023030733,0.0002883403899406645,0.0002120069527025505,0.00017050944162049183,0.000159478716966613,0.00019224364342300643,0.0003593168093314386
|
||||
0.001,0.0007634138087852742,0.000605185379478,0.0004120070127662441,0.0002876186224176594,0.00021130912485491145,0.00016977799240843955,0.0001585856969223786,0.00019086199210672448,0.0003562649023666937
|
||||
0.001,0.0007628028346998721,0.0006045332187986192,0.0004112166712442958,0.0002868226029691562,0.00021050564591298308,0.0001688917074786142,0.00015743651373617922,0.00018893812235512526,0.0003514029291704815
|
||||
0.001,0.0007621921143131398,0.0006038815297458003,0.00041042762231867933,0.00028602858816935265,0.00020970502628600424,0.00016800982241073787,0.00015629534163924753,0.00018703308452519017,0.00034660591682276115
|
||||
0.001,0.0007615816463554626,0.0006032303109890501,0.0004096398633263614,0.0002852365728026657,0.00020890725596775628,0.00016713231600712825,0.00015516212643578583,0.00018514669874176095,0.00034187301148734186
|
||||
0.001,0.0007609692265548555,0.000602577299493926,0.0004088509941253184,0.00028444450359523985,0.00020811064471691694,0.00016625772561605027,0.00015403541161623416,0.00018327705284413884,0.00033720006213702974
|
||||
0.001,0.0007603548574442921,0.0006019224999904981,0.0004080610253035772,0.00028365239238410656,0.0002073152021201705,0.00016538605339556675,0.00015291517504370476,0.00018142402424673905,0.0003325863766610152
|
||||
0.001,0.0007597350402439383,0.0006012612395706585,0.0004072600935672035,0.0002828447987841907,0.00020649842223713097,0.00016448344741808307,0.00015174362495246272,0.00017946021794659197,0.00032758319657592714
|
||||
0.001,0.0007591132829776185,0.0006005982088110791,0.0004064581175876688,0.00028203726728774387,0.00020568299547110922,0.00016358411213968798,0.00015057934813125987,0.00017751539893581778,0.00032265060787650516
|
||||
0.001,0.000758484736453085,0.0005999283660908604,0.0004056495676510805,0.00028122495212139567,0.00020486486304104927,0.00016268449575399985,0.00014941879820841596,0.00017558496339953558,0.0003177787884410679
|
||||
0.001,0.0007578494094215417,0.0005992517275730322,0.0004048344831924046,0.000280407904430663,0.00020404408117776887,0.0001617846565020927,0.00014826202727426984,0.00017366890284920263,0.0003129672376410902
|
||||
0.001,0.0007572073108060312,0.0005985683096346821,0.0004040129039083478,0.0002795861755026316,0.00020322070604404603,0.00016088465224596546,0.00014710908652278506,0.00017176720707727308,0.00030821545426856767
|
||||
0.001,0.0007565575890478602,0.00059787696153193,0.0004031823074325593,0.00027875567967892653,0.00020238859856737548,0.00015997497741322437,0.00014594324831107206,0.00016984173084389243,0.0003033838449669414
|
||||
0.001,0.0007559011152632264,0.0005971788697390111,0.00040234530612592536,0.0002779206290242912,0.00020155405878687617,0.00015906535701622418,0.0001447815990558725,0.00016793142878541938,0.0002986152551090434
|
||||
0.001,0.000755237898986442,0.000596474051424026,0.00040150194087318277,0.00027708107588917086,0.00020071714346489746,0.00015815584855490808,0.00014362418708307366,0.00016603627832169687,0.00029390910930431773
|
||||
0.001,0.0007545681886825906,0.0005957627683701927,0.00040065250958751827,0.00027623729012494873,0.00019987808563904174,0.00015724665811831285,0.0001424712015659587,0.00016415642490307197,0.0002892651425802985
|
||||
0.001,0.0007538919937536639,0.0005950450374279253,0.0003997970520738093,0.0002753893223189692,0.00019903693960802692,0.00015633783972296886,0.0001413226854400146,0.00016229183664828758,0.0002846827650697017
|
||||
0.001,0.0007532045557665671,0.0005943145247994342,0.0003989223236188871,0.00027451662339635243,0.0001981640806362608,0.00015538551594067732,0.00014010540813129958,0.00016028630721570607,0.00027963581042999
|
||||
0.001,0.0007525106592079478,0.0005935776116184588,0.00039804170193550713,0.0002736399653899091,0.00019728948692008958,0.00015443417816766013,0.00013889388158999866,0.0001582996284854468,0.0002746667454821644
|
||||
0.001,0.0007518104383956622,0.000592834444449282,0.0003971553683797481,0.0002727595219957832,0.00019641331428482412,0.00015348396557824612,0.00013768822268133468,0.000156331819705631,0.00026977480754699626
|
||||
0.001,0.0007511039033537896,0.0005920850408658466,0.0003962633635582371,0.00027187534416274955,0.00019553561634171146,0.00015253492870981108,0.00013648846139846028,0.00015438279270990136,0.0002649590347362105
|
||||
0.001,0.0007503910642803073,0.0005913294186556257,0.0003953657283217157,0.0002709874829437419,0.00019465644657888978,0.0001515871176567501,0.0001352946268320504,0.0001524524582210848,0.0002602184722292356
|
||||
0.001,0.0007496855573046408,0.0005905851062898704,0.00039449552403657745,0.00027014241927282736,0.0001938361803657908,0.0001507194393001951,0.00013421767536698768,0.000150722476765932,0.0002559376038022294
|
||||
0.001,0.0007489737467556278,0.0005898345737440663,0.000393619635985906,0.00026929349394052985,0.00019301404332913125,0.00014985216957655317,0.00013314488789598826,0.00014900672746282064,0.00025171693602497907
|
||||
0.001,0.0007482556429977025,0.0005890778388714725,0.00039273810426086416,0.0002684407562332248,0.0001921900867993824,0.00014898535811302548,0.00013207630234912348,0.00014730517414690737,0.000247555825445753
|
||||
0.001,0.000747532135526673,0.0005883158165865031,0.0003918519024244402,0.00026758503804540166,0.0001913649895279964,0.00014811957577380352,0.00013101244041258906,0.0001456183389249714,0.00024345460151209766
|
||||
0.001,0.0007468032330641541,0.0005875485221384682,0.0003909610648762846,0.00026672638132361175,0.0001905387943939666,0.00014725486211264363,0.00012995332641946747,0.00014394616337354944,0.00023941257691738652
|
||||
0.001,0.0007460689444707028,0.0005867759709451519,0.0003900656262003575,0.00026586482808789615,0.00018971154418348472,0.00014639125636754904,0.00012889898406950181,0.00014228858823944247,0.00023542906884335907
|
||||
0.001,0.0007453292787585437,0.0005859981786120694,0.0003891656212152682,0.00026500042051039684,0.000188883281693472,0.0001455287975953345,0.000127849436626481,0.0001406455538271199,0.00023150340029334736
|
||||
0.001,0.0007445843685250069,0.0005852152884984452,0.0003882612223549495,0.00026413331906842847,0.00018805414639063353,0.00014466760638632992,0.00012680478406473458,0.00013901709088191773,0.00022763506393382832
|
||||
0.001,0.0007438342228409441,0.0005844273161744179,0.0003873524639441998,0.00026326356496406687,0.00018722417962072503,0.0001438077197030893,0.00012576504647438162,0.00013740313489262333,0.00022382338328436597
|
||||
0.001,0.0007430788509165626,0.0005836342773781009,0.0003864393804873395,0.0002623911994661588,0.00018639342263244998,0.00014294917419819004,0.000124730243348245,0.00013580362065026603,0.00022006768669446508
|
||||
0.001,0.000742327254060605,0.0005828476385639736,0.00038554300530339766,0.00026154496076193957,0.00018559797011481673,0.0001421370333657246,0.00012375932796391997,0.00013430279846409174,0.00021649152387618443
|
||||
0.001,0.0007415704350109161,0.0005820559385468977,0.00038464228372291103,0.0002606960153281244,0.00018480150743526303,0.00014132579578003348,0.000122792459010487,0.0001328143978658426,0.0002129659469511457
|
||||
0.001,0.0007408084031449065,0.0005812591931755618,0.00038373724983374976,0.00025984440338310303,0.0001840040745362742,0.0001405154975809745,0.00012182965960439977,0.00013133837476817992,0.00020949038404752677
|
||||
0.001,0.0007400427720784002,0.0005804590496942265,0.00038282961864956994,0.0002589915613698488,0.00018320681873232144,0.00013970708155515462,0.00012087177639736769,0.00012987560432955444,0.00020606578076074432
|
||||
0.001,0.0007392735475065714,0.0005796555183614057,0.00038191941292656456,0.0002581375157328154,0.0001824097650442608,0.00013890056717630873,0.00011991881140841177,0.0001284260094133047,0.00020269149646849757
|
||||
0.001,0.0007385007352097838,0.0005788486095364762,0.00038100665551987393,0.00025728229294257515,0.00018161293842329387,0.00013809597373520515,0.00011897076635433426,0.0001269895128043655,0.00019936689671873207
|
||||
0.001,0.0007377243410529983,0.0005780383336785572,0.0003800913693799712,0.0002564259194903244,0.00018081636374445108,0.00013729332033271256,0.00011802764264291933,0.00012556603720150224,0.00019609135315036536
|
||||
0.001,0.0007369464655998592,0.0005772268587748353,0.0003791758785432219,0.0002555703831979673,0.00018002165393456068,0.00013649394990366146,0.00011709066577140669,0.00012415690240967774,0.0001928666431485617
|
||||
0.001,0.0007361671107233329,0.000576414188654825,0.000378260191109379,0.00025471569177879693,0.0001792288130669198,0.00013569785799734456,0.00011615980704210183,0.00012276198311838844,0.00018969202938803596
|
||||
0.001,0.0007353862783344302,0.000575600327192691,0.00037734431522203,0.00025386185296321013,0.00017843784520433673,0.00013490504014296103,0.00011523503783001357,0.00012138115492992521,0.0001865667844236815
|
||||
0.001,0.0007346027258369329,0.0005747835721418604,0.00037642443290667116,0.0002530026346493095,0.000177639416207763,0.0001341012793025371,0.0001142922256260196,0.00011996295037667013,0.00018332302768968173
|
||||
0.001,0.0007338177018431625,0.0005739656376861859,0.00037550439543261463,0.0002521443237629474,0.00017684294734265143,0.00013330094534015117,0.00011335582519792064,0.00011855974750452474,0.00018013280630154984
|
||||
0.001,0.0007330312083387708,0.0005731465277735759,0.000374584210907019,0.00025128692777751636,0.0001760484420635206,0.00013250403238709868,0.00011242580398299235,0.00011717140625198769,0.000176995286763841
|
||||
0.001,0.0007322450716827681,0.0005723280950701311,0.00037366577307640326,0.00025043200586833656,0.00017525712146802507,0.00013171151729665014,0.00011150300328069361,0.00011579873047427355,0.00017391111613739919
|
||||
0.001,0.0007314592892342591,0.0005715103366354928,0.0003727490765712826,0.00024957954955556494,0.0001744689721973381,0.00013092337604814113,0.00011058736861417956,0.00011444154833756723,0.0001708794064250159
|
||||
0.001,0.0007306738583803173,0.0005706932495677312,0.00037183411609277345,0.00024872955044744495,0.00017368398100343736,0.0001301395848004509,0.00010967884595770732,0.00011309968990727626,0.00016789928423747183
|
||||
0.001,0.0007298887765314699,0.0005698768309963597,0.00037092088639398746,0.0002478820002115871,0.00017290213471209804,0.00012936011984533696,0.0001087773816703527,0.00011177298701463364,0.00016496989019036454
|
||||
0.001,0.0007291058850619836,0.0005690629705872476,0.0003700113801847071,0.0002470385774678141,0.00017212477134492983,0.0001285860674779147,0.00010788392632853856,0.00011046237940908493,0.00016209217355659912
|
||||
0.001,0.0007283251776795193,0.0005682516594285885,0.0003691055790623401,0.0002461992575642169,0.00017135185999287266,0.00012781738439880834,0.00010699840217906239,0.00010916766306641233,0.00015926520709064215
|
||||
0.001,0.000727546648123048,0.000567442888658507,0.0003682034647519281,0.00024536401604150686,0.00017058337001160307,0.00012705402771768452,0.00010612073231230378,0.0001078886367084761,0.00015648808062028533
|
||||
0.001,0.0007267691175258129,0.0005666351120658079,0.00036730194585451363,0.00024452825978826814,0.00016981299319253088,0.00012628722374912656,0.00010523753204397677,0.00010660034638564814,0.00015369233245141463
|
||||
0.001,0.0007259937543683618,0.0005658298620581495,0.00036640409142867466,0.00024369656281803695,0.0001690470312136919,0.00012552576286196436,0.00010436224908854787,0.00010532792661952348,0.00015094700928094292
|
||||
0.001,0.0007252205525006216,0.0005650271299429238,0.0003655098835814395,0.0002428689011484816,0.0001682854538881413,0.00012476960247399048,0.00010349480634605481,0.00010407117393308648,0.00014825118806841486
|
||||
0.001,0.0007244515476870691,0.0005642289688561167,0.00036462138604045246,0.00024204694758546622,0.00016752954803985582,0.00012401974721449815,0.00010263603739686231,0.00010283083470852359,0.0001456053538142381
|
||||
0.001,0.0007236867286572494,0.0005634353625294562,0.0003637385663464586,0.00024123066115747858,0.00016677926586679636,0.00012327613591461942,0.00010178584352378332,0.00010160667618634935,0.0001430085413998934
|
||||
0.001,0.0007229260842094953,0.0005626462948017631,0.0003628613922977866,0.00024042000126051454,0.00016603456004153966,0.00012253870808207087,0.0001009441272602465,0.00010039846917127745,0.000140459805170444
|
||||
0.001,0.0007221696032014468,0.000561861749604344,0.00036198983191176377,0.0002396149275989645,0.00016529538363567852,0.00012180740380654271,0.00010011079225737115,9.920598777483068e-05,0.00013795821792425024
|
||||
0.001,0.0007214188723728384,0.00056108334509554,0.0003611255610840681,0.0002388168283348348,0.00016456282140960994,0.00012108307905286178,9.928655238677393e-05,9.802986918413655e-05,0.0001355041849544529
|
||||
0.001,0.0007206738776295639,0.0005603110603628828,0.0003602685373417506,0.00023802565027806571,0.00016383681258690845,0.00012036565891864721,9.847129356381268e-05,9.686986333449523e-05,0.0001330967445342526
|
||||
0.001,0.0007199346049934109,0.0005595448746691314,0.00035941871861020354,0.00023724134078502595,0.00016311729706930416,0.00011965506942237431,9.7664903298557e-05,9.57257243308077e-05,0.00013073495556510661
|
||||
0.001,0.0007192103057281418,0.0005587965882928195,0.000358597914203722,0.00023649404923234267,0.0001624426539507404,0.00011900000933912548,9.693290327537121e-05,9.469853254875163e-05,0.0001286228242214262
|
||||
0.001,0.0007184916860834766,0.000558054333130965,0.0003577841401235257,0.0002357533416394368,0.00016177407584741055,0.00011835110239617177,9.620855295571759e-05,9.368449216343134e-05,0.0001265476735456528
|
||||
0.001,0.000717778732645577,0.0005573180893469085,0.0003569773567342285,0.0002350191694371068,0.0001611115088719043,0.00011770828481211398,9.549176022876216e-05,9.268341301362701e-05,0.00012450880618841231
|
||||
0.001,0.0007170715507844816,0.0005565879566941514,0.0003561776441627035,0.00023429158098135867,0.00016045497378223205,0.00011707155159443024,9.47824835635146e-05,9.169515755193108e-05,0.00012250560759307665
|
||||
0.001,0.0007163701270344053,0.0005558639152622166,0.0003553849627325309,0.00023357052778616886,0.00015980441694230793,0.00011644083951173604,9.408063218207804e-05,9.071953997714039e-05,0.00012053740486430812
|
||||
0.001,0.0007156744480415676,0.0005551459453084167,0.00035459927313802623,0.00023285596185845654,0.00015915978530381373,0.00011581608608941654,9.338611653058621e-05,8.975637744384618e-05,0.00011860353870291344
|
||||
0.001,0.0007149845005557793,0.0005544340272448129,0.0003538205364097734,0.0002321478356456351,0.0001585210263398076,0.00011519722952770958,9.269884816673769e-05,8.880548985453175e-05,0.00011670336266552508
|
||||
0.001,0.0007143011352806332,0.0005537290222260827,0.0003530496254918224,0.00023144685778402562,0.00015788868071804074,0.00011458468167101622,9.20191492389152e-05,8.786712068874325e-05,0.00011483685132763588
|
||||
0.001,0.0007136243377311475,0.0005530309085687206,0.00035228649684153725,0.0002307529751854999,0.00015726269010384348,0.00011397837465469773,9.134692457668887e-05,8.694108196461404e-05,0.00011300335424584403
|
||||
0.001,0.0007129540935643617,0.0005523396647985742,0.000351531107363628,0.0002300661353432777,0.0001566429968410848,0.00011337824146720777,9.06820803490277e-05,8.602718880727694e-05,0.00011120223452206596
|
||||
0.001,0.0007122949300063586,0.0005516609446370161,0.0003507932546232374,0.0002293990178082647,0.00015604454205901748,0.00011280134646728481,9.004396195380538e-05,8.514641523915274e-05,0.00010944396621311202
|
||||
0.001,0.0007116422850379047,0.0005509890404263221,0.00035006301886912226,0.00022873877079420107,0.00015545216193435095,0.00011223032450910806,8.941277122627028e-05,8.427699754143763e-05,0.00010771649233683978
|
||||
0.001,0.0007109961448775265,0.0005503239315436604,0.00034934035900275196,0.00022808534468017605,0.00015486580256638324,0.00011166511373672321,8.878842266662507e-05,8.341876815036907e-05,0.00010601922394974779
|
||||
0.001,0.0007103566138672342,0.0005496657159311855,0.0003486253516297722,0.00022743878433373037,0.00015428548213839886,0.00011110570832676001,8.81708780194749e-05,8.25716070442755e-05,0.00010435164299643007
|
||||
0.001,0.0007097236782517396,0.0005490143729973408,0.0003479179557857281,0.0002267990403962617,0.0001537111471536449,0.00011055204708289399,8.756005313455197e-05,8.173535064610718e-05,0.0001027131817052566
|
||||
0.001,0.0007090973244087274,0.0005483698823458906,0.00034721813091834777,0.000226166064037726,0.00015314274472297157,0.00011000406955950422,8.695586501935841e-05,8.090983803329783e-05,0.00010110328401062253
|
||||
0.001,0.0007084775388425413,0.0005477322237660661,0.0003465258368613831,0.00022553980691704316,0.00015258022251510344,0.00010946171600087524,8.635823175652435e-05,8.00949107862898e-05,9.952140501322636e-05
|
||||
0.001,0.0007078645400735427,0.0005471016129101978,0.0003458412757255009,0.00022492042013778988,0.00015202368335334558,0.00010892504915290583,8.57671759148139e-05,7.929051589048381e-05,9.796715152670613e-05
|
||||
0.001,0.0007072583145347741,0.0005464780293804963,0.00034516440688163317,0.00022430785483116316,0.0001514730744232032,0.00010839400891826328,8.518261565996433e-05,7.84964968569563e-05,9.643999410136803e-05
|
||||
0.001,0.0007066588487940405,0.000545861452976259,0.0003444951901125997,0.00022370206265319418,0.00015092834351042303,0.00010786853593723236,8.460447028623623e-05,7.771269974698105e-05,9.493941424410264e-05
|
||||
0.001,0.0007060768113835355,0.0005452653567881146,0.00034385780916102886,0.0002231355522451839,0.0001504295746545273,0.00010739737531972382,8.409424224945842e-05,7.702434963545377e-05,9.360618912201228e-05
|
||||
0.001,0.0007055014939207988,0.0005446762036784223,0.00034322791998477503,0.0002225755642266546,0.00014993632274793293,0.00010693123855410087,8.358951092264173e-05,7.634435339541097e-05,9.22944227993744e-05
|
||||
0.001,0.0007049328836329239,0.0005440939744776738,0.0003426054850001757,0.00022202205441602206,0.000149448541485554,0.00010647007505716636,8.309021096715739e-05,7.567259318109089e-05,9.100372969350909e-05
|
||||
0.001,0.0007043664108869901,0.0005435140913972429,0.00034198598587466614,0.00022147141590047654,0.00014896349766232102,0.00010601178096740148,8.259459730216135e-05,7.500736724232048e-05,8.973176442333615e-05
|
||||
0.001,0.0007038020712072354,0.0005429365478183962,0.00034136940918446675,0.0002209236320980648,0.00014848117283038098,0.00010555633431743894,8.210263744821714e-05,7.434860458126827e-05,8.847824135377829e-05
|
||||
0.001,0.0007032398600991381,0.0005423613371043419,0.00034075574151016483,0.0002203786864681782,0.00014800154862415601,0.00010510371328265478,8.161429921011451e-05,7.369623501807121e-05,8.724287943554497e-05
|
||||
0.001,0.0007026797730466592,0.0005417884525961108,0.00034014496942632764,0.0002198365624959981,0.00014752460674093983,0.00010465389615779026,8.112955064604149e-05,7.305018913687007e-05,8.602540201539488e-05
|
||||
0.001,0.0007021196874055633,0.0005412157406692665,0.0003395348927353949,0.00021929545761274023,0.00014704895219343257,0.00010420578859113516,8.064746506639534e-05,7.240953347459202e-05,8.482441661675139e-05
|
||||
0.001,0.0007015596012323657,0.0005406431992153213,0.0003389255082691921,0.00021875536780717296,0.00014657457987728414,0.00010375938295149973,8.016802726693694e-05,7.17742234562459e-05,8.363970356449741e-05
|
||||
0.001,0.0007009995125587165,0.0005400708260946051,0.0003383168128172846,0.00021821628903476192,0.00014610148467187763,0.0001033146716169485,7.969122211456026e-05,7.114421486558773e-05,8.247104609297546e-05
|
||||
0.001,0.000700426120570031,0.0005394817717340144,0.00033767827777106695,0.00021763678242090514,0.00014557802543177205,0.00010280805245363877,7.913535785684264e-05,7.040274681183516e-05,8.111172191387726e-05
|
||||
0.001,0.0006998527383823768,0.0005388929110101418,0.0003370405259007354,0.00021705847496470142,0.00014505616500334602,0.00010230367256069614,7.858312049704058e-05,6.966868896041247e-05,7.977423771714316e-05
|
||||
0.0010496228983614124,0.002020602352332682,0.0024834354692445607,0.004712247621156641,0.00854174709233096,0.015197203876184536,0.027142477151470907,0.049749449744480465,0.09589624880110185,0.2
|
||||
0.004235602571438949,0.007336805952289255,0.008714058005603317,0.015024716476258112,0.025061770718850837,0.04079161627542227,0.0649508755581543,0.10074574737193842,0.14993445055894863,0.206
|
||||
|
36
tests/data/test_lumped_losses_raman_fiber_config.json
Normal file
36
tests/data/test_lumped_losses_raman_fiber_config.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"uid": "Span1",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.0,
|
||||
"lumped_losses": [
|
||||
{
|
||||
"position": 7,
|
||||
"loss": 0.5
|
||||
}
|
||||
],
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 0.0000167,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
"operational": {
|
||||
"temperature": 283,
|
||||
"raman_pumps": [
|
||||
{
|
||||
"power": 0.2,
|
||||
"frequency": 205000000000000,
|
||||
"propagation_direction": "counterprop"
|
||||
},
|
||||
{
|
||||
"power": 0.206,
|
||||
"frequency": 201000000000000,
|
||||
"propagation_direction": "counterprop"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
224
tests/data/test_old_parameters_fiber_config.json
Normal file
224
tests/data/test_old_parameters_fiber_config.json
Normal file
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"uid": "Span1",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.5,
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 0.0000167,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15,
|
||||
"raman_efficiency": {
|
||||
"cr": [
|
||||
0.00000000e+00,
|
||||
1.12351610e-05,
|
||||
3.47838074e-05,
|
||||
5.79356636e-05,
|
||||
8.06921680e-05,
|
||||
9.79845709e-05,
|
||||
1.10454361e-04,
|
||||
1.18735302e-04,
|
||||
1.24736889e-04,
|
||||
1.30110053e-04,
|
||||
1.41001273e-04,
|
||||
1.46383247e-04,
|
||||
1.57011792e-04,
|
||||
1.70765865e-04,
|
||||
1.88408911e-04,
|
||||
2.05914127e-04,
|
||||
2.24074028e-04,
|
||||
2.47508283e-04,
|
||||
2.77729174e-04,
|
||||
3.08044243e-04,
|
||||
3.34764439e-04,
|
||||
3.56481704e-04,
|
||||
3.77127256e-04,
|
||||
3.96269124e-04,
|
||||
4.10955175e-04,
|
||||
4.18718761e-04,
|
||||
4.19511263e-04,
|
||||
4.17025384e-04,
|
||||
4.13565369e-04,
|
||||
4.07726048e-04,
|
||||
3.83671291e-04,
|
||||
4.08564283e-04,
|
||||
3.69571936e-04,
|
||||
3.14442090e-04,
|
||||
2.16074535e-04,
|
||||
1.23097823e-04,
|
||||
8.95457457e-05,
|
||||
7.52470400e-05,
|
||||
7.19806145e-05,
|
||||
8.87961158e-05,
|
||||
9.30812065e-05,
|
||||
9.37058268e-05,
|
||||
8.45719619e-05,
|
||||
6.90585286e-05,
|
||||
4.50407159e-05,
|
||||
3.36521245e-05,
|
||||
3.02292475e-05,
|
||||
2.69376939e-05,
|
||||
2.60020897e-05,
|
||||
2.82958958e-05,
|
||||
3.08667558e-05,
|
||||
3.66024657e-05,
|
||||
5.80610307e-05,
|
||||
6.54797937e-05,
|
||||
6.25022715e-05,
|
||||
5.37806442e-05,
|
||||
3.94996621e-05,
|
||||
2.68120644e-05,
|
||||
2.33038554e-05,
|
||||
1.79140757e-05,
|
||||
1.52472424e-05,
|
||||
1.32707565e-05,
|
||||
1.06541760e-05,
|
||||
9.84649374e-06,
|
||||
9.13999627e-06,
|
||||
9.08971012e-06,
|
||||
1.04227525e-05,
|
||||
1.50419271e-05,
|
||||
1.77838232e-05,
|
||||
2.15810815e-05,
|
||||
2.03744008e-05,
|
||||
1.81939341e-05,
|
||||
1.31862121e-05,
|
||||
9.65352116e-06,
|
||||
8.62698322e-06,
|
||||
9.18688016e-06,
|
||||
1.01737784e-05,
|
||||
1.08017817e-05,
|
||||
1.03903588e-05,
|
||||
9.30040333e-06,
|
||||
8.30809173e-06,
|
||||
6.90650401e-06,
|
||||
5.52238029e-06,
|
||||
3.90648708e-06,
|
||||
2.22908227e-06,
|
||||
1.55796177e-06,
|
||||
9.77218716e-07,
|
||||
3.23477236e-07,
|
||||
1.60602454e-07,
|
||||
7.97306386e-08
|
||||
],
|
||||
"frequency_offset": [
|
||||
0.0e12,
|
||||
0.5e12,
|
||||
1.0e12,
|
||||
1.5e12,
|
||||
2.0e12,
|
||||
2.5e12,
|
||||
3.0e12,
|
||||
3.5e12,
|
||||
4.0e12,
|
||||
4.5e12,
|
||||
5.0e12,
|
||||
5.5e12,
|
||||
6.0e12,
|
||||
6.5e12,
|
||||
7.0e12,
|
||||
7.5e12,
|
||||
8.0e12,
|
||||
8.5e12,
|
||||
9.0e12,
|
||||
9.5e12,
|
||||
10.0e12,
|
||||
10.5e12,
|
||||
11.0e12,
|
||||
11.5e12,
|
||||
12.0e12,
|
||||
12.5e12,
|
||||
12.75e12,
|
||||
13.0e12,
|
||||
13.25e12,
|
||||
13.5e12,
|
||||
14.0e12,
|
||||
14.5e12,
|
||||
14.75e12,
|
||||
15.0e12,
|
||||
15.5e12,
|
||||
16.0e12,
|
||||
16.5e12,
|
||||
17.0e12,
|
||||
17.5e12,
|
||||
18.0e12,
|
||||
18.25e12,
|
||||
18.5e12,
|
||||
18.75e12,
|
||||
19.0e12,
|
||||
19.5e12,
|
||||
20.0e12,
|
||||
20.5e12,
|
||||
21.0e12,
|
||||
21.5e12,
|
||||
22.0e12,
|
||||
22.5e12,
|
||||
23.0e12,
|
||||
23.5e12,
|
||||
24.0e12,
|
||||
24.5e12,
|
||||
25.0e12,
|
||||
25.5e12,
|
||||
26.0e12,
|
||||
26.5e12,
|
||||
27.0e12,
|
||||
27.5e12,
|
||||
28.0e12,
|
||||
28.5e12,
|
||||
29.0e12,
|
||||
29.5e12,
|
||||
30.0e12,
|
||||
30.5e12,
|
||||
31.0e12,
|
||||
31.5e12,
|
||||
32.0e12,
|
||||
32.5e12,
|
||||
33.0e12,
|
||||
33.5e12,
|
||||
34.0e12,
|
||||
34.5e12,
|
||||
35.0e12,
|
||||
35.5e12,
|
||||
36.0e12,
|
||||
36.5e12,
|
||||
37.0e12,
|
||||
37.5e12,
|
||||
38.0e12,
|
||||
38.5e12,
|
||||
39.0e12,
|
||||
39.5e12,
|
||||
40.0e12,
|
||||
40.5e12,
|
||||
41.0e12,
|
||||
41.5e12,
|
||||
42.0e12
|
||||
]
|
||||
}
|
||||
},
|
||||
"operational": {
|
||||
"temperature": 283,
|
||||
"raman_pumps": [
|
||||
{
|
||||
"power": 224.403e-3,
|
||||
"frequency": 205e12,
|
||||
"propagation_direction": "counterprop"
|
||||
},
|
||||
{
|
||||
"power": 231.135e-3,
|
||||
"frequency": 201e12,
|
||||
"propagation_direction": "counterprop"
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 1,
|
||||
"longitude": 0,
|
||||
"city": null,
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
225
tests/data/test_parameters_fiber_config.json
Normal file
225
tests/data/test_parameters_fiber_config.json
Normal file
@@ -0,0 +1,225 @@
|
||||
{
|
||||
"uid": "Span1",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.5,
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 0.0000167,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15,
|
||||
"raman_coefficient": {
|
||||
"g0": [
|
||||
0.00000000e+00,
|
||||
1.12351610e-05,
|
||||
3.47838074e-05,
|
||||
5.79356636e-05,
|
||||
8.06921680e-05,
|
||||
9.79845709e-05,
|
||||
1.10454361e-04,
|
||||
1.18735302e-04,
|
||||
1.24736889e-04,
|
||||
1.30110053e-04,
|
||||
1.41001273e-04,
|
||||
1.46383247e-04,
|
||||
1.57011792e-04,
|
||||
1.70765865e-04,
|
||||
1.88408911e-04,
|
||||
2.05914127e-04,
|
||||
2.24074028e-04,
|
||||
2.47508283e-04,
|
||||
2.77729174e-04,
|
||||
3.08044243e-04,
|
||||
3.34764439e-04,
|
||||
3.56481704e-04,
|
||||
3.77127256e-04,
|
||||
3.96269124e-04,
|
||||
4.10955175e-04,
|
||||
4.18718761e-04,
|
||||
4.19511263e-04,
|
||||
4.17025384e-04,
|
||||
4.13565369e-04,
|
||||
4.07726048e-04,
|
||||
3.83671291e-04,
|
||||
4.08564283e-04,
|
||||
3.69571936e-04,
|
||||
3.14442090e-04,
|
||||
2.16074535e-04,
|
||||
1.23097823e-04,
|
||||
8.95457457e-05,
|
||||
7.52470400e-05,
|
||||
7.19806145e-05,
|
||||
8.87961158e-05,
|
||||
9.30812065e-05,
|
||||
9.37058268e-05,
|
||||
8.45719619e-05,
|
||||
6.90585286e-05,
|
||||
4.50407159e-05,
|
||||
3.36521245e-05,
|
||||
3.02292475e-05,
|
||||
2.69376939e-05,
|
||||
2.60020897e-05,
|
||||
2.82958958e-05,
|
||||
3.08667558e-05,
|
||||
3.66024657e-05,
|
||||
5.80610307e-05,
|
||||
6.54797937e-05,
|
||||
6.25022715e-05,
|
||||
5.37806442e-05,
|
||||
3.94996621e-05,
|
||||
2.68120644e-05,
|
||||
2.33038554e-05,
|
||||
1.79140757e-05,
|
||||
1.52472424e-05,
|
||||
1.32707565e-05,
|
||||
1.06541760e-05,
|
||||
9.84649374e-06,
|
||||
9.13999627e-06,
|
||||
9.08971012e-06,
|
||||
1.04227525e-05,
|
||||
1.50419271e-05,
|
||||
1.77838232e-05,
|
||||
2.15810815e-05,
|
||||
2.03744008e-05,
|
||||
1.81939341e-05,
|
||||
1.31862121e-05,
|
||||
9.65352116e-06,
|
||||
8.62698322e-06,
|
||||
9.18688016e-06,
|
||||
1.01737784e-05,
|
||||
1.08017817e-05,
|
||||
1.03903588e-05,
|
||||
9.30040333e-06,
|
||||
8.30809173e-06,
|
||||
6.90650401e-06,
|
||||
5.52238029e-06,
|
||||
3.90648708e-06,
|
||||
2.22908227e-06,
|
||||
1.55796177e-06,
|
||||
9.77218716e-07,
|
||||
3.23477236e-07,
|
||||
1.60602454e-07,
|
||||
7.97306386e-08
|
||||
],
|
||||
"frequency_offset": [
|
||||
0.0e12,
|
||||
0.5e12,
|
||||
1.0e12,
|
||||
1.5e12,
|
||||
2.0e12,
|
||||
2.5e12,
|
||||
3.0e12,
|
||||
3.5e12,
|
||||
4.0e12,
|
||||
4.5e12,
|
||||
5.0e12,
|
||||
5.5e12,
|
||||
6.0e12,
|
||||
6.5e12,
|
||||
7.0e12,
|
||||
7.5e12,
|
||||
8.0e12,
|
||||
8.5e12,
|
||||
9.0e12,
|
||||
9.5e12,
|
||||
10.0e12,
|
||||
10.5e12,
|
||||
11.0e12,
|
||||
11.5e12,
|
||||
12.0e12,
|
||||
12.5e12,
|
||||
12.75e12,
|
||||
13.0e12,
|
||||
13.25e12,
|
||||
13.5e12,
|
||||
14.0e12,
|
||||
14.5e12,
|
||||
14.75e12,
|
||||
15.0e12,
|
||||
15.5e12,
|
||||
16.0e12,
|
||||
16.5e12,
|
||||
17.0e12,
|
||||
17.5e12,
|
||||
18.0e12,
|
||||
18.25e12,
|
||||
18.5e12,
|
||||
18.75e12,
|
||||
19.0e12,
|
||||
19.5e12,
|
||||
20.0e12,
|
||||
20.5e12,
|
||||
21.0e12,
|
||||
21.5e12,
|
||||
22.0e12,
|
||||
22.5e12,
|
||||
23.0e12,
|
||||
23.5e12,
|
||||
24.0e12,
|
||||
24.5e12,
|
||||
25.0e12,
|
||||
25.5e12,
|
||||
26.0e12,
|
||||
26.5e12,
|
||||
27.0e12,
|
||||
27.5e12,
|
||||
28.0e12,
|
||||
28.5e12,
|
||||
29.0e12,
|
||||
29.5e12,
|
||||
30.0e12,
|
||||
30.5e12,
|
||||
31.0e12,
|
||||
31.5e12,
|
||||
32.0e12,
|
||||
32.5e12,
|
||||
33.0e12,
|
||||
33.5e12,
|
||||
34.0e12,
|
||||
34.5e12,
|
||||
35.0e12,
|
||||
35.5e12,
|
||||
36.0e12,
|
||||
36.5e12,
|
||||
37.0e12,
|
||||
37.5e12,
|
||||
38.0e12,
|
||||
38.5e12,
|
||||
39.0e12,
|
||||
39.5e12,
|
||||
40.0e12,
|
||||
40.5e12,
|
||||
41.0e12,
|
||||
41.5e12,
|
||||
42.0e12
|
||||
],
|
||||
"reference_frequency": 206184634112792
|
||||
}
|
||||
},
|
||||
"operational": {
|
||||
"temperature": 283,
|
||||
"raman_pumps": [
|
||||
{
|
||||
"power": 224.403e-3,
|
||||
"frequency": 205e12,
|
||||
"propagation_direction": "counterprop"
|
||||
},
|
||||
{
|
||||
"power": 231.135e-3,
|
||||
"frequency": 201e12,
|
||||
"propagation_direction": "counterprop"
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 1,
|
||||
"longitude": 0,
|
||||
"city": null,
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
97
tests/data/test_raman_fiber_expected_results.csv
Normal file
97
tests/data/test_raman_fiber_expected_results.csv
Normal file
@@ -0,0 +1,97 @@
|
||||
signal,ase,nli
|
||||
0.000325019416624,3.8827360617812335e-08,2.397604591245591e-07
|
||||
0.0003222815415358,3.8702821151814216e-08,2.4267833614138976e-07
|
||||
0.0003195661748689,3.8578942925493807e-08,2.455296149641726e-07
|
||||
0.000316873132879,3.8455721305309324e-08,2.483151861322029e-07
|
||||
0.0003125687708988,3.815158818797417e-08,2.497308542349044e-07
|
||||
0.0003083216327341,3.784989647314237e-08,2.5106122773764815e-07
|
||||
0.0003041309702107,3.755062053762566e-08,2.523083160653813e-07
|
||||
0.0002999931829076,3.725370771318225e-08,2.534716728592015e-07
|
||||
0.0002959076621852,3.695913382975532e-08,2.545532047834699e-07
|
||||
0.0002914749637887,3.6620413511505286e-08,2.5520557429118934e-07
|
||||
0.0002871045786391,3.62847038107824e-08,2.557776344401253e-07
|
||||
0.0002827879891071,3.5951828869209396e-08,2.5626453052593257e-07
|
||||
0.0002785247470154,3.562176113110911e-08,2.5666832208790035e-07
|
||||
0.0002743144039041,3.5294473123494e-08,2.569910409348857e-07
|
||||
0.000270032675166,3.4954880805048256e-08,2.571167784361306e-07
|
||||
0.0002658067200554,3.4618272391047544e-08,2.571652788509227e-07
|
||||
0.000261636025157,3.428461757057609e-08,2.5713860104931033e-07
|
||||
0.00025752034599,3.395388872366444e-08,2.570390408700655e-07
|
||||
0.000253459157096,3.362605558722993e-08,2.5284986247287787e-07
|
||||
0.000248983782073,3.3242702224575744e-08,2.48252059976888e-07
|
||||
0.0002445773493265,3.286328176612301e-08,2.437277481862015e-07
|
||||
0.0002402391773459,3.2487750441670215e-08,2.392761376865807e-07
|
||||
0.0002359684123723,3.2116061418127753e-08,2.3489626905665574e-07
|
||||
0.0002317642070805,3.174816817069829e-08,2.3058719110264335e-07
|
||||
0.0002279695550926,3.1424928539548144e-08,2.2668986526609113e-07
|
||||
0.0002242281358436,3.1104729317697146e-08,2.228495045304229e-07
|
||||
0.0002205393783222,3.078753835343166e-08,2.190654562751529e-07
|
||||
0.0002169035545525,3.047333197100547e-08,2.1533790605165431e-07
|
||||
0.0002133200561122,3.01620779209974e-08,2.1166616520930645e-07
|
||||
0.0002097882786443,2.9853744125792176e-08,2.080495504306458e-07
|
||||
0.0002063076230434,2.9548298767727423e-08,2.0448738489666716e-07
|
||||
0.0002028776374913,2.9245712991289203e-08,2.009791389793126e-07
|
||||
0.0001994977236946,2.8945955168147914e-08,1.975241389908885e-07
|
||||
0.0001961672877059,2.8648993828553545e-08,1.9412171682473827e-07
|
||||
0.0001929967738963,2.8368195292008612e-08,1.9088102669437356e-07
|
||||
0.0001898709450753,2.8090002575266257e-08,1.8768789971552863e-07
|
||||
0.0001867892958482,2.7814389032455363e-08,1.8454176486632323e-07
|
||||
0.000183752636707,2.754134148447891e-08,1.8115002092564538e-07
|
||||
0.0001807604032471,2.7270832946920812e-08,1.7781492252546064e-07
|
||||
0.0001778120365192,2.7002836607760232e-08,1.745356369687972e-07
|
||||
0.0001749069829579,2.673732582084065e-08,1.7131134159682263e-07
|
||||
0.0001720467771106,2.6474316260529432e-08,1.6814325920632144e-07
|
||||
0.0001692307716138,2.6213779758633963e-08,1.6503047175593728e-07
|
||||
0.0001664583277393,2.5955688359138642e-08,1.619720751255672e-07
|
||||
0.0001635796256227,2.5677295228672648e-08,1.588223280583729e-07
|
||||
0.0001607481963598,2.540169810843596e-08,1.557306487644946e-07
|
||||
0.0001579633073114,2.512886316325068e-08,1.526960267832303e-07
|
||||
0.0001552255108883,2.4858770138402143e-08,1.4971869736122287e-07
|
||||
0.000152534027681,2.4591385101783997e-08,1.467976093017761e-07
|
||||
0.0001498880910245,2.432667443532368e-08,1.439317302908228e-07
|
||||
0.0001472869464661,2.4064604800471338e-08,1.411200462508912e-07
|
||||
0.0001447314108795,2.3805175801260087e-08,1.3836305172259211e-07
|
||||
0.0001422206714078,2.3548353146553164e-08,1.3565967973526553e-07
|
||||
0.0001397539300508,2.3294102880186107e-08,1.3300888438790536e-07
|
||||
0.0001372700286953,2.3032485432340423e-08,1.3035230831596558e-07
|
||||
0.0001348306664569,2.2773547798807564e-08,1.277485195296911e-07
|
||||
0.0001324350333325,2.2517253805739807e-08,1.2505815113074245e-07
|
||||
0.0001300835425363,2.2263580536243144e-08,1.2242454150816991e-07
|
||||
0.0001277753479236,2.2012491805819457e-08,1.1984647647989558e-07
|
||||
0.0001255096202792,2.1763951788812352e-08,1.1732276843747534e-07
|
||||
0.0001232855464269,2.1517924960982367e-08,1.148522552473446e-07
|
||||
0.0001211034718808,2.1274400813402842e-08,1.1243486085670634e-07
|
||||
0.0001189625537742,2.1033343271785093e-08,1.100694052812587e-07
|
||||
0.0001168619671686,2.0794716623616593e-08,1.0775473577456182e-07
|
||||
0.0001149842862687,2.0591381044652174e-08,1.056582342233035e-07
|
||||
0.0001131392424142,2.038998454906055e-08,1.0360354473279054e-07
|
||||
0.0001113262252932,2.0190503422606346e-08,1.0158979943539652e-07
|
||||
0.0001095446965516,1.9992914861970927e-08,9.961620365200192e-08
|
||||
0.0001077940670993,1.9797195630879305e-08,9.768192356581421e-08
|
||||
0.0001060737596438,1.9603322741072024e-08,9.578614349620901e-08
|
||||
0.0001043832080373,1.9411273409584944e-08,9.392806512410292e-08
|
||||
0.0001027223865858,1.922103688152168e-08,9.210738192714242e-08
|
||||
0.0001010907257366,1.9032590330084783e-08,9.032330177845482e-08
|
||||
9.948766769187398e-05,1.8845911172333032e-08,8.857505025129074e-08
|
||||
9.792267601599324e-05,1.8663442661346744e-08,8.687075031773093e-08
|
||||
9.638489299064336e-05,1.848276820506329e-08,8.550652733411691e-08
|
||||
9.48738026587305e-05,1.830386814585904e-08,8.416598440502352e-08
|
||||
9.338895072626004e-05,1.8126723701740663e-08,8.284871850980459e-08
|
||||
9.192983962632808e-05,1.7951315790883015e-08,8.155428823884958e-08
|
||||
9.049598195913348e-05,1.7777625631449783e-08,8.028226120215297e-08
|
||||
8.908690001727453e-05,1.7605634715742614e-08,7.903221360818749e-08
|
||||
8.77022482135352e-05,1.743532764682425e-08,7.780383887402493e-08
|
||||
8.634156228069215e-05,1.7266686393258476e-08,7.659672513140668e-08
|
||||
8.50043874741986e-05,1.7099693224424935e-08,7.541046895998541e-08
|
||||
8.381694660770028e-05,1.6962933489525264e-08,7.43570471865261e-08
|
||||
8.26484651987276e-05,1.682764479561346e-08,7.33204450340972e-08
|
||||
8.149860566615124e-05,1.6693821025332528e-08,7.230036302225977e-08
|
||||
8.036532369463753e-05,1.6561436760581683e-08,7.129498756488483e-08
|
||||
7.924836834130927e-05,1.6430487594212236e-08,7.030409604146297e-08
|
||||
7.814749266035204e-05,1.6300969571299207e-08,6.932746937742372e-08
|
||||
7.706245353522453e-05,1.6172879193985398e-08,6.836489189528336e-08
|
||||
7.599203524832233e-05,1.6046190191322708e-08,6.741528508795074e-08
|
||||
7.493604414299442e-05,1.5920900877281144e-08,6.647847715560108e-08
|
||||
7.389428911314724e-05,1.57970100612018e-08,6.555429856110159e-08
|
||||
7.268136514077581e-05,1.5628904744452727e-08,6.447826980203191e-08
|
||||
7.148784598320314e-05,1.5462487634551132e-08,6.341945575654982e-08
|
||||
|
@@ -1,97 +0,0 @@
|
||||
,signal,ase,nli
|
||||
0,0.0002869472910749756,3.829244288314411e-08,2.1570435023738975e-07
|
||||
1,0.0002844264441819097,3.810807396068084e-08,2.1799950841473497e-07
|
||||
2,0.00028192866252406385,3.792544000755193e-08,2.2023841125047751e-07
|
||||
3,0.0002794537215642667,3.7744517714620316e-08,2.2242189941355056e-07
|
||||
4,0.00027562432957345563,3.739256592350871e-08,2.2343448272115905e-07
|
||||
5,0.0002718482755003939,3.7044482870002475e-08,2.2437826192962336e-07
|
||||
6,0.00026812479793132313,3.670020704375223e-08,2.2525495466693408e-07
|
||||
7,0.000264450700138397,3.635954085714981e-08,2.2606415187873477e-07
|
||||
8,0.0002608253488030976,3.602242835595967e-08,2.2680748521505387e-07
|
||||
9,0.0002569046888856947,3.564392097524325e-08,2.2718285844823122e-07
|
||||
10,0.0002530414048172964,3.52696660940159e-08,2.2749429758474536e-07
|
||||
11,0.0002492279873569917,3.489974200864255e-08,2.277374766527899e-07
|
||||
12,0.00024546394589921574,3.453407358954537e-08,2.2791414400785136e-07
|
||||
13,0.00024174879169001578,3.4172586853993816e-08,2.280260208417818e-07
|
||||
14,0.00023798746912554602,3.3802283179520985e-08,2.2798420759778034e-07
|
||||
15,0.00023427697848580554,3.343627022987542e-08,2.2788101592695744e-07
|
||||
16,0.0002306167836320285,3.307447309241581e-08,2.2771816297650914e-07
|
||||
17,0.00022700656967539738,3.2716831574363364e-08,2.274975560288182e-07
|
||||
18,0.00022344579480967338,3.236327278261661e-08,2.2361822442592406e-07
|
||||
19,0.00021953361935365365,3.195819964288877e-08,2.1939761734541424e-07
|
||||
20,0.000215683131390894,3.155821693631402e-08,2.152494588710531e-07
|
||||
21,0.0002118936126056039,3.116322947665684e-08,2.1117277567387026e-07
|
||||
22,0.00020816423698459974,3.0773146233359933e-08,2.0716649124095414e-07
|
||||
23,0.000204494186708796,3.0387877710694614e-08,2.0322954179937734e-07
|
||||
24,0.0002011608152067422,3.0044038268833097e-08,1.9963693210325328e-07
|
||||
25,0.0001978756946189507,2.9704204306604607e-08,1.9610141536963302e-07
|
||||
26,0.00019463824873067792,2.9368307297032184e-08,1.9262221997374404e-07
|
||||
27,0.00019144860669288407,2.903632861769827e-08,1.8919927457566036e-07
|
||||
28,0.00018830616497929743,2.870820070744311e-08,1.8583178406705711e-07
|
||||
29,0.0001852103256336822,2.838385708911634e-08,1.8251896218718027e-07
|
||||
30,0.0001821604972098109,2.8063232252848876e-08,1.7926003240910756e-07
|
||||
31,0.00017915618670059162,2.774625963676283e-08,1.76054318231953e-07
|
||||
32,0.00017619680881745593,2.7432875871797347e-08,1.729010553429381e-07
|
||||
33,0.0001732817839023698,2.712301856538676e-08,1.6979948820365403e-07
|
||||
34,0.0001704966413678542,2.6828122477482957e-08,1.6683312331765736e-07
|
||||
35,0.00016775189226190024,2.6536528664560742e-08,1.639139770351803e-07
|
||||
36,0.00016504703499518105,2.624818226917535e-08,1.6104139135569604e-07
|
||||
37,0.00016238266779776653,2.5963117448579666e-08,1.5795381794641793e-07
|
||||
38,0.0001597582427278871,2.568127942199337e-08,1.5492098715709327e-07
|
||||
39,0.0001571732182027887,2.5402614261982925e-08,1.5194201541883415e-07
|
||||
40,0.00015462705891567335,2.5127068868391087e-08,1.4901603171959048e-07
|
||||
41,0.00015212101646395513,2.4854550603641668e-08,1.4614388817380648e-07
|
||||
42,0.00014965447757985992,2.4585009902449718e-08,1.4332463586635585e-07
|
||||
43,0.0001472268380950584,2.4318397887399997e-08,1.4055734193945962e-07
|
||||
44,0.0001447164668892332,2.4034551917480693e-08,1.377259000826997e-07
|
||||
45,0.00014224784112376056,2.3753930444781328e-08,1.3494914625940223e-07
|
||||
46,0.000139820283675003,2.3476479506890216e-08,1.3222606385781202e-07
|
||||
47,0.00013743418748444287,2.3202247900619965e-08,1.295566531341862e-07
|
||||
48,0.00013508884015386686,2.2931181973013504e-08,1.2693987096025158e-07
|
||||
49,0.00013278354172498307,2.2663228905058608e-08,1.2437469442130953e-07
|
||||
50,0.00013051760419724657,2.2398336706395863e-08,1.2186012017917007e-07
|
||||
51,0.00012829168984638487,2.2136423459712534e-08,1.1939640981689728e-07
|
||||
52,0.00012610506317956756,2.1877440279108582e-08,1.1698252030563078e-07
|
||||
53,0.00012395700285919374,2.1621338937233993e-08,1.1461743054419825e-07
|
||||
54,0.00012180241033650921,2.136015630373758e-08,1.1225922783040025e-07
|
||||
55,0.0001196865090578088,2.11019103466444e-08,1.0994951537260489e-07
|
||||
56,0.00011760857776205185,2.0846552296319304e-08,1.0757395097863843e-07
|
||||
57,0.00011556891128259512,2.0594154864038522e-08,1.0524972555992818e-07
|
||||
58,0.00011356676177304645,2.0344670536408355e-08,1.0297570549834491e-07
|
||||
59,0.00011160139690545148,2.009805268169949e-08,1.007507830554809e-07
|
||||
60,0.00010967209909252316,1.9854255584746143e-08,9.857387536569294e-08
|
||||
61,0.00010777915187088834,1.961321154131787e-08,9.644480679617587e-08
|
||||
62,0.00010592181397175025,1.9374877782865603e-08,9.43624842461164e-08
|
||||
63,0.00010409936038609485,1.913921236065976e-08,9.232584080120623e-08
|
||||
64,0.00010246447558376296,1.8936229484424864e-08,9.046927135292076e-08
|
||||
65,0.00010085803630103994,1.873544193319646e-08,8.865067925960422e-08
|
||||
66,9.927950010555374e-05,1.8536821682157304e-08,8.686925127148483e-08
|
||||
67,9.772837346090753e-05,1.834034757300294e-08,8.512422533827403e-08
|
||||
68,9.62041343011343e-05,1.8145993316507615e-08,8.341482250640209e-08
|
||||
69,9.470627135912848e-05,1.7953733512786736e-08,8.174028142913557e-08
|
||||
70,9.32342835979764e-05,1.776354374489084e-08,8.009985766376519e-08
|
||||
71,9.178813743816069e-05,1.757538990695628e-08,7.849321446941075e-08
|
||||
72,9.036733009485282e-05,1.7389250225057777e-08,7.691961625609573e-08
|
||||
73,8.897136946428169e-05,1.7205104136353174e-08,7.537834446343352e-08
|
||||
74,8.760740745801088e-05,1.7025340034280735e-08,7.38751341742058e-08
|
||||
75,8.626710469266231e-05,1.6847609082084475e-08,7.274492099364066e-08
|
||||
76,8.495000573672366e-05,1.6671897815367364e-08,7.16342744751107e-08
|
||||
77,8.365569697520734e-05,1.6498202874185357e-08,7.054284583689086e-08
|
||||
78,8.238374036673638e-05,1.6326516066391613e-08,6.94702656996508e-08
|
||||
79,8.11337070649851e-05,1.615683240442047e-08,6.84161724378069e-08
|
||||
80,7.990517700271111e-05,1.5989150837085435e-08,6.738021182875641e-08
|
||||
81,7.869784230919362e-05,1.5823472723367315e-08,6.63621242598539e-08
|
||||
82,7.751129541079501e-05,1.5659808141896922e-08,6.536156604375558e-08
|
||||
83,7.634513730458697e-05,1.5498175122781168e-08,6.437820072038669e-08
|
||||
84,7.530262080974513e-05,1.5364277079429572e-08,6.349909645089698e-08
|
||||
85,7.427675504203511e-05,1.523236493234819e-08,6.263403294276124e-08
|
||||
86,7.326723873728716e-05,1.510251249079146e-08,6.178275615432246e-08
|
||||
87,7.227232864620995e-05,1.4974078108462424e-08,6.094379608687809e-08
|
||||
88,7.1291797553153e-05,1.4847055996011248e-08,6.011696114034367e-08
|
||||
89,7.032542203609039e-05,1.4721440784517874e-08,5.930206291361685e-08
|
||||
90,6.937298231673965e-05,1.4597227547292096e-08,5.849891607818969e-08
|
||||
91,6.843339696762385e-05,1.447443282270653e-08,5.7706608718023645e-08
|
||||
92,6.750649045006057e-05,1.4353051811356354e-08,5.6924992809748396e-08
|
||||
93,6.65920896785063e-05,1.4233080214004659e-08,5.615392239860827e-08
|
||||
94,6.554258932109667e-05,1.407504972937325e-08,5.5268928972034444e-08
|
||||
95,6.450957734109368e-05,1.3918655180382722e-08,5.439783940506079e-08
|
||||
|
38
tests/data/test_science_utils_fiber_config.json
Normal file
38
tests/data/test_science_utils_fiber_config.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"uid": "Span1",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.5,
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 0.0000167,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
"operational": {
|
||||
"temperature": 283,
|
||||
"raman_pumps": [
|
||||
{
|
||||
"power": 224.403e-3,
|
||||
"frequency": 205e12,
|
||||
"propagation_direction": "counterprop"
|
||||
},
|
||||
{
|
||||
"power": 231.135e-3,
|
||||
"frequency": 201e12,
|
||||
"propagation_direction": "counterprop"
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 1,
|
||||
"longitude": 0,
|
||||
"city": null,
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
tests/data/wrong_duplicate_eqpt_ila_reverse.xlsx
Executable file
BIN
tests/data/wrong_duplicate_eqpt_ila_reverse.xlsx
Executable file
Binary file not shown.
BIN
tests/data/wrong_duplicate_link_reverse.xlsx
Executable file
BIN
tests/data/wrong_duplicate_link_reverse.xlsx
Executable file
Binary file not shown.
BIN
tests/data/wrong_node_type.xlsx
Normal file
BIN
tests/data/wrong_node_type.xlsx
Normal file
Binary file not shown.
BIN
tests/data/wrong_service.xlsx
Executable file
BIN
tests/data/wrong_service.xlsx
Executable file
Binary file not shown.
BIN
tests/data/wrong_service_type.xlsx
Normal file
BIN
tests/data/wrong_service_type.xlsx
Normal file
Binary file not shown.
BIN
tests/data/wrong_topo_bad_eqpt.xlsx
Executable file
BIN
tests/data/wrong_topo_bad_eqpt.xlsx
Executable file
Binary file not shown.
BIN
tests/data/wrong_topo_duplicate_eqpt.xlsx
Executable file
BIN
tests/data/wrong_topo_duplicate_eqpt.xlsx
Executable file
Binary file not shown.
BIN
tests/data/wrong_topo_duplicate_node.xlsx
Executable file
BIN
tests/data/wrong_topo_duplicate_node.xlsx
Executable file
Binary file not shown.
BIN
tests/data/wrong_topo_eqpt.xlsx
Executable file
BIN
tests/data/wrong_topo_eqpt.xlsx
Executable file
Binary file not shown.
BIN
tests/data/wrong_topo_link.xlsx
Executable file
BIN
tests/data/wrong_topo_link.xlsx
Executable file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user