mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-11-02 11:07:57 +00:00
Formating Excel_userguide.rst and adding a section for the optional Eqpt sheet
Typos correction Explanations added on how to fill in the excel Eqpt sheet Removing verbose printing for debug of create_eqpt_sheet.py Bug correction : blank removed when copying city names with creat_eqpt_sheet.py Typos correction on README and Excel_userguide adding some line for the export PYTHONPATH in the readme typos corrections Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
This commit is contained in:
@@ -2,108 +2,174 @@
|
||||
How to prepare the Excel input file
|
||||
-----------------------------------
|
||||
|
||||
`examples/transmission_main_example.py`_ gives the possibility to use an excel input file instead of a json file. The program then will generate the corresponding json file for you.
|
||||
`examples/transmission_main_example.py <examples/transmission_main_example.py>`_ gives the possibility to use an excel input file instead of a json file. The program then will generate the corresponding json file for you.
|
||||
|
||||
The file named 'meshTopologyExampleV2.xls' is an example.
|
||||
|
||||
In order to work the excel file MUST contain at least 2 sheets
|
||||
In order to work the excel file MUST contain at least 2 sheets:
|
||||
|
||||
- Nodes
|
||||
- Links
|
||||
|
||||
(In progress) The File MAY contain an additional sheet:
|
||||
|
||||
- Eqt
|
||||
|
||||
Nodes sheet
|
||||
-----------
|
||||
|
||||
Nodes sheet contains seven columns
|
||||
each line represents a 'node' (ROADM site or an in line amplifier site ILA)
|
||||
- City (Mandatory)
|
||||
- State
|
||||
- Country
|
||||
- Region
|
||||
- Latitude
|
||||
- Longitude
|
||||
- Type
|
||||
Nodes sheet contains seven columns.
|
||||
Each line represents a 'node' (ROADM site or an in line amplifier site ILA)::
|
||||
|
||||
"City" is used for the name of a node of the digraph. It accepts letters, numbers,commas,underscore,dash, blank... (not exhaustive).
|
||||
City (Mandatory) ; State ; Country ; Region ; Latitude ; Longitude ; Type
|
||||
|
||||
It Must be unique.
|
||||
- **City** is used for the name of a node of the digraph. It accepts letters, numbers,commas,underscore,dash, blank... (not exhaustive).
|
||||
|
||||
"Type" is not mandatory.
|
||||
- If not filled, it will be interpreted as an 'ILA' site if node degree is 2 and as a ROADM otherwise.
|
||||
- If filled, it can take "ROADM" or "ILA" values. if another string is used, it will be considered as not filled.
|
||||
**City name MUST be unique**
|
||||
|
||||
"State", "Country", "Region" are not mandatory.
|
||||
- **Type** is not mandatory.
|
||||
|
||||
"Longitude", "Latitude" are not mandatory. They should contain numbers.
|
||||
- If not filled, it will be interpreted as an 'ILA' site if node degree is 2 and as a ROADM otherwise.
|
||||
- If filled, it can take "ROADM", "FUSED" or "ILA" values. If another string is used, it will be considered as not filled. FUSED means that spans ingress and egress spans will be fuesed together.
|
||||
|
||||
there must not be empty line(s) between two nodes lines
|
||||
- *State*, *Country*, *Region* are not mandatory.
|
||||
"Region" is a holdover from the CORONET topology reference file `CORONET_Global_Topology.xls <examples/CORONET_Global_Topology.xls>`_. CORONET separates its network into geographical regions (Europe, Asia, Continental US.) This information is not used by gnpy.
|
||||
|
||||
- *Longitude*, *Latitude* are not mandatory. If filled they should contain numbers.
|
||||
|
||||
**There MUST NOT be empty line(s) between two nodes lines**
|
||||
|
||||
|
||||
Links sheet
|
||||
-----------
|
||||
|
||||
Links sheet must contain sixteen columns::
|
||||
|
||||
<-- east cable from a to z --> <-- west from z to -->
|
||||
NodeA ; NodeZ ; Distance km ; Fiber type ; Lineic att ; Con_in ; Con_out ; PMD ; Cable Id ; Distance km ; Fiber type ; Lineic att ; Con_in ; Con_out ; PMD ; Cable Id
|
||||
|
||||
|
||||
Links sheets MUST contain all links between nodes defined in Nodes sheet.
|
||||
each line represents a 'bidir link' between two nodes. The wo direction are represented on a single line with "east cable from a to z" fields and "west from z to a" fields
|
||||
Each line represents a 'bidir link' between two nodes. The two direction are represented on a single line with "east cable from a to z" fields and "west from z to a" fields. Values for 'a to z' may be different from values from 'z to a'.
|
||||
'z to a' direction MUST NOT be repeated in a different line.
|
||||
|
||||
- "NodeA" and "NodeZ" are Mandatory. They are the two endpoints of the link. They MUST contain a node name from the "City" names listed in Nodes sheet.
|
||||
|
||||
parameters for "east cable from a to z" and "west from z to a" are detailed in 2x7 columns. If not filled, "west from z to a" is copied from "east cable from a to z".
|
||||
Parameters for "east cable from a to z" and "west from z to a" are detailed in 2x7 columns. If not filled, "west from z to a" is copied from "east cable from a to z".
|
||||
|
||||
- "Distance km" : is not Mandatory.
|
||||
If filled it MUST contain numbers. If empty it is replaced by a default "80" km value.
|
||||
If values are over 150 km the program will automatically suppose that intermediate span description are required and will generate spans in the json output.
|
||||
For example, a line filled with::
|
||||
|
||||
- "Fiber type" is not mandatory.
|
||||
if filled it must contain types listed in eqpt_config.json in "Fiber" list "type_variety".
|
||||
if not filled it takes "SSMF" as default value.
|
||||
node6 ; node3 ; 80 ; SSMF ; 0.2 ; 0.5 ; 0.5 ; 0.1 ; cableB ; ; ; 0.21 ; 0.2 ; ; ;
|
||||
|
||||
- "Lineic att" is not mandatory. It is the lineic attenuation expressed in dB/km.
|
||||
if filled it must contain positive numbers.
|
||||
if not filled it takes "0.2" dB/km value
|
||||
will generate a unidir fiber span from node6 to node3 with::
|
||||
|
||||
[node6 node3 80 SSMF 0.2 0.5 0.5 0.1 cableB]
|
||||
|
||||
- "Con_in", "Con_out" are not mandatory and are not used yet. They are the connector loss in dB at ingress and egress of the fiber spans.
|
||||
if filled it must contain positive numbers.
|
||||
if not filled it takes "0.5" dB default value.
|
||||
and a fiber span from node3 to node6::
|
||||
|
||||
- "PMD" is not mandatory and and is not used yet. It is the PMD value of the link in ps.
|
||||
If filled they must contain positive numbers.
|
||||
if not filled it takes "0.1" ps value.
|
||||
[node6 node3 80 SSMF 0.21 0.2 0.5 0.1 cableB] attributes.
|
||||
|
||||
- **NodeA** and **NodeZ** are Mandatory.
|
||||
They are the two endpoints of the link. They MUST contain a node name from the **City** names listed in Nodes sheet.
|
||||
|
||||
- **Distance km** is not mandatory.
|
||||
It is the link length.
|
||||
|
||||
- If filled it MUST contain numbers. If empty it is replaced by a default "80" km value.
|
||||
- If value is below 150 km, it is considered as a single (bidirectional) fiber span.
|
||||
- If value is over 150 km the `transmission_main_example.py <examples/transmission_main_example.py>`_ program will automatically suppose that intermediate span description are required and will generate fiber spans elements with "_1","_2", ... trailing strings which are not visible in the json output.
|
||||
|
||||
- **Fiber type** is not mandatory.
|
||||
|
||||
If filled it must contain types listed in `eqpt_config.json <examples/eqpt_config.json>`_ in "Fiber" list "type_variety".
|
||||
If not filled it takes "SSMF" as default value.
|
||||
|
||||
- **Lineic att** is not mandatory.
|
||||
|
||||
It is the lineic attenuation expressed in dB/km.
|
||||
If filled it must contain positive numbers.
|
||||
If not filled it takes "0.2" dB/km value
|
||||
|
||||
- *Con_in*, *Con_out* are not mandatory and are not used yet.
|
||||
|
||||
They are the connector loss in dB at ingress and egress of the fiber spans.
|
||||
If filled they must contain positive numbers.
|
||||
If not filled they take "0.5" dB default value.
|
||||
|
||||
- *PMD* is not mandatory and and is not used yet.
|
||||
|
||||
It is the PMD value of the link in ps.
|
||||
If filled they must contain positive numbers.
|
||||
If not filled, it takes "0.1" ps value.
|
||||
|
||||
- *Cable Id* is not mandatory.
|
||||
If filled they must contain strings with the same constraint as "City" names.
|
||||
|
||||
- "Cable Id" is not Mandatory. if filled they must contain strings with the same constraint as "City" names.
|
||||
|
||||
|
||||
|
||||
(in progress)
|
||||
|
||||
Eqpt sheet
|
||||
----------
|
||||
Eqt sheet is optional. It lists the amplifiers types and characteristics on each degree.
|
||||
|
||||
Eqt sheet is optional. It lists the amplifiers types and characteristics on each degree of the *Node A* line.
|
||||
Links sheet must contain sixteen columns::
|
||||
|
||||
<-- east cable from a to z --> <-- west from z to -->
|
||||
Node A ; Node Z ; amp type ; att_in ; amp gain ; tilt ; att_out ; amp type ; att_in ; amp gain ; tilt ; att_out
|
||||
|
||||
If the sheet is present, it MUST have as many lines as egress directions of ROADMs defined in Links Sheet.
|
||||
|
||||
For example, consider the following list of links (A,B and C being a ROADM)
|
||||
A - amp1
|
||||
amp1 - amp2
|
||||
Amp2 - B
|
||||
A - amp3
|
||||
amp3 - C
|
||||
For example, consider the following list of links (A,B and C being a ROADM and amp# ILAs)
|
||||
|
||||
::
|
||||
|
||||
A - amp1
|
||||
amp1 - amp2
|
||||
Amp2 - B
|
||||
A - amp3
|
||||
amp3 - C
|
||||
|
||||
then Eqpt sheet should contain:
|
||||
A - amp1
|
||||
amp1 - amp2
|
||||
Amp2 - B
|
||||
A - amp3
|
||||
amp3 - C
|
||||
B - amp2
|
||||
C - amp3
|
||||
|
||||
`examples/create_eqpt_sheet.py`_ helps you to create a template for the mandatory entries of the list.
|
||||
::
|
||||
|
||||
A - amp1
|
||||
amp1 - amp2
|
||||
Amp2 - B
|
||||
A - amp3
|
||||
amp3 - C
|
||||
B - amp2
|
||||
C - amp3
|
||||
|
||||
|
||||
`create_eqpt_sheet.py <examples/create_eqpt_sheet.py>`_ helps you to create a template for the mandatory entries of the list.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ cd examples
|
||||
$ python create_eqpt_sheet.py meshTopologyExampleV2.xls
|
||||
|
||||
|
||||
- **Node A** is mandatory. It is the name of the node (as listed in Nodes sheet).
|
||||
If Node A is a 'ROADM' (Type attribute in sheet Node), its number of occurence must be equal to its degree.
|
||||
If Node A is an 'ILA' it should appear only once.
|
||||
|
||||
- **Node Z** is mandatory. It is the egress direction from the *Node A* site. Multiple Links between the same Node A and NodeZ is not supported.
|
||||
|
||||
- **amp type** is not mandatory.
|
||||
If filled it must contain types listed in `eqpt_config.json <examples/eqpt_config.json>`_ in "Edfa" list "type_variety".
|
||||
If not filled it takes "std_medium_gain" as default value.
|
||||
|
||||
- **amp_gain** is not mandatory. It is the value to be set on the amplifier (in dB).
|
||||
If not filled, it will be determined with design rules in the convert.py file.
|
||||
If filled, it must contain positive numbers.
|
||||
|
||||
- *att_in* and *att_out* are not mandatory and are not used yet. They are the value of the attenautor at input and output of amplifier (in dB).
|
||||
If filled they must contain positive numbers.
|
||||
|
||||
- *tilt* --TODO--
|
||||
|
||||
# to be completed #
|
||||
|
||||
|
||||
|
||||
12
README.rst
12
README.rst
@@ -71,6 +71,14 @@ fully-functional programs.
|
||||
|
||||
By default, this script operates on a single span network defined in `examples/edfa/edfa_example_network.json <examples/edfa/edfa_example_network.json>`_
|
||||
|
||||
(you may need to set PYTHONPATH variable. For example on Ubuntu, add your workspace path to PYTHONPATH in your .bashrc file :
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
export PYTHONPATH=$PYTHONPATH:~/<workspace path>/gnpy/
|
||||
|
||||
)
|
||||
|
||||
You can specify a different network at the command line as follows. For
|
||||
example, to use the CORONET Continental US (CONUS) network defined in `examples/coronet_conus_example.json <examples/coronet_conus_example.json>`_:
|
||||
|
||||
@@ -100,12 +108,12 @@ dBm/channel. These are not yet parametrized but can be modified directly in the
|
||||
script (via the SpectralInformation tuple) to accomodate any baud rate,
|
||||
spacing, power or channel count demand.
|
||||
|
||||
The amplifier's gain is set to exactly compsenate for the loss in each network
|
||||
The amplifier's gain is set to exactly compensate for the loss in each network
|
||||
element. The amplifier is currently defined with gain range of 15 dB to 25 dB
|
||||
and 21 dBm max output power. Ripple and NF models are defined in
|
||||
`examples/edfa_config.json <examples/edfa_config.json>`_
|
||||
|
||||
It is possible to use an excell file input. this will generate the json topology entry. How to prepare the Excel input file is explined `here <Escel_userguide.rst>`_.
|
||||
It is possible to use an excell file input. this will generate the json topology entry. How to prepare the Excel input file is explained `here <Excel_userguide.rst>`_.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
@@ -43,6 +43,7 @@ all_rows = lambda sh, start=0: (sh.row(x) for x in range(start, sh.nrows))
|
||||
|
||||
def read_excel(input_filename):
|
||||
with open_workbook(input_filename) as wb:
|
||||
# reading Links sheet
|
||||
links_sheet = wb.sheet_by_name('Links')
|
||||
links = []
|
||||
nodeoccuranceinlinks = []
|
||||
@@ -52,21 +53,21 @@ def read_excel(input_filename):
|
||||
links.append(Shortlink(row[0].value,row[1].value))
|
||||
links_by_src[row[0].value].append(Shortnode(row[1].value,''))
|
||||
links_by_dest[row[1].value].append(Shortnode(row[0].value,''))
|
||||
# print(f'source {links[len(links)-1].src} dest {links[len(links)-1].dest}')
|
||||
#print(f'source {links[len(links)-1].src} dest {links[len(links)-1].dest}')
|
||||
nodeoccuranceinlinks.append(row[0].value)
|
||||
nodeoccuranceinlinks.append(row[1].value)
|
||||
|
||||
# reading Nodes sheet
|
||||
nodes_sheet = wb.sheet_by_name('Nodes')
|
||||
nodes = []
|
||||
# eqt = []
|
||||
node_degree = []
|
||||
for row in all_rows(nodes_sheet, start=5) :
|
||||
|
||||
temp_eqt = row[6].value
|
||||
# verify if node degree to confirm eqt type
|
||||
# verify node degree to confirm eqt type
|
||||
node_degree.append(nodeoccuranceinlinks.count(row[0].value))
|
||||
if temp_eqt.lower() == 'ila' and nodeoccuranceinlinks.count(row[0].value) !=2 :
|
||||
print(f'inconsistance node {nodes[len(nodes)-1]} has degree \
|
||||
print(f'Inconsistancy: node {nodes[len(nodes)-1]} has degree \
|
||||
{node_degree[len(nodes)-1]} and can not be an ILA ... replaced by ROADM')
|
||||
temp_eqt = 'ROADM'
|
||||
if temp_eqt == '' and nodeoccuranceinlinks.count(row[0].value) == 2 :
|
||||
@@ -74,19 +75,16 @@ def read_excel(input_filename):
|
||||
if temp_eqt == '' and nodeoccuranceinlinks.count(row[0].value) != 2 :
|
||||
temp_eqt = 'ROADM'
|
||||
# print(f'node {nodes[len(nodes)-1]} eqt {temp_eqt}')
|
||||
# eqt.append(temp_eqt)
|
||||
nodes.append(Shortnode(row[0].value,temp_eqt))
|
||||
print(len(nodes)-1)
|
||||
print(f'node {nodes[len(nodes)-1].nodename} eqt {temp_eqt}')
|
||||
|
||||
|
||||
# print(links_by_src)
|
||||
# print(len(nodes)-1)
|
||||
print(f'reading: node {nodes[len(nodes)-1].nodename} eqt {temp_eqt}')
|
||||
return links,nodes, links_by_src , links_by_dest
|
||||
|
||||
def create_eqt_template(links,nodes, links_by_src , links_by_dest, input_filename):
|
||||
with open(f'{input_filename[:-4]}_eqt_sheet.txt','w') as my_file :
|
||||
output_filename = f'{input_filename[:-4]}_eqt_sheet.txt'
|
||||
with open(output_filename,'w') as my_file :
|
||||
# print header similar to excel
|
||||
my_file.write('OPTIONAL\n\n\
|
||||
my_file.write('OPTIONAL\n\n\n\
|
||||
\t\tNode a egress amp (from a to z)\t\t\t\t\tNode a ingress amp (from z to a) \
|
||||
\nNode A \tNode Z \tamp type \tatt_in \tamp gain \ttilt \tatt_out\
|
||||
amp type \tatt_in \tamp gain \ttilt \tatt_out\n')
|
||||
@@ -97,18 +95,18 @@ def create_eqt_template(links,nodes, links_by_src , links_by_dest, input_filenam
|
||||
for lk in links:
|
||||
temp = [lk.src , lk.dest]
|
||||
tab.append(temp)
|
||||
print(temp)
|
||||
my_file.write(f'{temp[0]} \t {temp[1]}\n')
|
||||
# print(temp)
|
||||
my_file.write(f'{temp[0]}\t{temp[1]}\n')
|
||||
for n in nodes :
|
||||
if n.eqt.lower() == 'roadm' :
|
||||
for src in links_by_dest[n.nodename] :
|
||||
temp = [n.nodename , src.nodename]
|
||||
tab.append(temp)
|
||||
print(temp)
|
||||
my_file.write(f'{temp[0]} \t {temp[1]}\n')
|
||||
# print(temp)
|
||||
my_file.write(f'{temp[0]}\t{temp[1]}\n')
|
||||
i = i + 1
|
||||
print(len(tab))
|
||||
|
||||
print(f'File {output_filename} successfully created with Node A - Node Z ' +
|
||||
' entries for Eqpt sheet in excel file.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parser.parse_args()
|
||||
@@ -116,3 +114,4 @@ if __name__ == '__main__':
|
||||
links,nodes,links_by_src, links_by_dest = read_excel(input_filename)
|
||||
create_eqt_template(links,nodes, links_by_src , links_by_dest , input_filename)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user