This example demonstrates the feasibility of integrating Lumerical INTERCONNECT with Python. This interoperability is made possible using Application Programming Interface (API). In this example, a Monte Carlo analysis in INTERCONNECT will be generated using Python script based on the circuit defined in the file run_monte_carlo.icp and some of the results such as the histogram and probability density function (pdf) will be plotted using Python plot functions.
This example is similar to the Monte Carlo scripting commands example in the Parameter sweeps, Optimization and Monte Carlo analysis section.
Requirements: Lumerical products 2018a R4 or newer
Note:
|
During the Lumerical product installation process, a lumapi.py file should be automatically installed in this location.
Linux |
/opt/lumerical/interconnect/api/python/ |
Windows |
C:\Program Files\Lumerical\<version>\interconnect\api\python |
This module is the key to enable Lumerical-Python API connection. Once the lumapi module is imported to Python, the integration should be ready. See this page for instructions for setting up Python API.
Importing modules
The following script lines imports the modules ( imp and matplotlib ) and the Lumerical Python API that will be used in the later script.
import importlib.util
#The default paths for windows, linux and mac
spec_win = importlib.util.spec_from_file_location('lumapi', 'C:\\Program Files\\Lumerical\\2020a\\api\\python\\lumapi.py')
spec_lin = importlib.util.spec_from_file_location('lumapi', "/opt/lumerical/2020a/api/python/lumapi.py")
spec_mac = importlib.util.spec_from_file_location('luampi', "/Applications/Lumerical/FDTD Solutions/FDTD Solutions.app/Contents/API/Python/lumapi.py")
#Functions that perform the actual loading
lumapi = importlib.util.module_from_spec(spec_win) #
spec.loader.exec_module(lumapi)
from matplotlib import pyplot as pyplot
User can also use the method mentioned in the Session management - Python API
Creating the Monte Carlo analysis
The following line loads and opens the INTERCONNECT project file run_monte_carlo.icp . An INTERCONNECT instance will be opened up by this.
ic = lumapi.INTERCONNECT("run_monte_carlo.icp")
The following commands generate and superficially define a new Monte Carlo analysis named "MC_script". The use of dictionary data type in Python separates the setup data from the function calls to setsweep , and makes the code cleaner to manage.
ic.addsweep(2)
MC_name = "MC_script"
ic.setsweep("Monte Carlo analysis", "name", MC_name)
setup = {
"number of trials": 200.0,
"enable seed": 1.0,
"seed": 1.0,
"Variation": "Both",
"type": "Parameters",
}
for k, v in setup.items():
ic.setsweep(MC_name, k, v)
After the Monte Carlo analysis object is superficially generated, the parameters can then be defined and added to it. Each of the parameters is defined as a Python dictionary (they are structs inside Lumerical script), and we use an array to store these parameter dictionaries to later loop over to add to the Monte Carlo analysis object.
sweep_parameters = [
{
"Name": "cpl_2",
"Parameter": "::Root Element::WC2::coupling coefficient 1",
"Value": ic.getnamed("WC2", "coupling coefficient 1"),
"Distribution": {
"type": "gaussian",
"variation": 0.02
}
},
{
"Name": "cpl_3",
"Parameter": "::Root Element::WC3::coupling coefficient 1",
"Value": ic.getnamed("WC3", "coupling coefficient 1"),
"Distribution": {
"type": "uniform",
"variation": 0.04
}
},
{
"Name": "wgd_model",
"Model": "WGD::group index 1",
"Value": ic.getnamed("SW1", "group index 1"),
"Process": {
"type": "uniform",
"variation": 1.02
},
"Mismatch": {
"type": "gaussian",
"variation": 0.1
}
},
{
"Name": "wgd_corr",
"Parameters": "SW1_group_index_1,SW2_group_index_1,SW3_group_index_1",
"Value": 0.95
}
]
for parameter in sweep_parameters:
ic.addsweepparameter(MC_name, parameter)
The next step is to add the results (free spectral range, bandwidth and gain) to this Monte Carlo analysis. The commands below add the results to the Monte Carlo analysis object and the results are defined in the array sweep_results . Again, each of the results is defined as a Python dictionary.
sweep_results = [
{ "Name": "fsr",
"Result": "::Root Element::Optical Network Analyzer::input 2/mode 1/peak/free spectral range",
"Estimation": True,
"Min": 1.0e11,
"Max": 2.0e11
},
{ "Name": "bd",
"Result": "::Root Element::Optical Network Analyzer::input 1/mode 1/peak/bandwidth",
"Estimation": False
},
{ "Name": "gain",
"Result": "::Root Element::Optical Network Analyzer::input 1/mode 1/peak/gain",
"Estimation": False
}
]
for result in sweep_results:
ic.addsweepresult(MC_name, result)
The Monte Carlo analysis tab will look like below after the definition of the parameters and results:
Running the Monte Carlo analysis
The following command runs the Monte Carlo analysis that defined in the previous step. The Monte Carlo analysis runs 60 trials in batches of 10 or less and automatically updates the analysis status window after each batch of trials.
ic.runsweep(MC_name)
Plotting the results
One of the advantages of using the Lumerical Python API is that we can take advantage of the advanced Python modules. In this example, we use pyplot in the matplotlib module to plot the Monte Carlo analysis results.
The following commands plot the FSR histogram and the estimation of its pdf in the same figure and this cannot be achieved by using Lumerical script commands.
fsr = ic.getsweepresult(MC_name, "analysis/results/histogram/fsr")
fsrCount = fsr["count"][0][0]
fsr = fsr["fsr"][0][0]
pdf = ic.getsweepresult(MC_name, "analysis/results/pdf/fsr")
pdfCount = pdf["count"][0][0]
pdfFsr = pdf["fsr"][0][0]
pyplot.bar(fsr/1e9, fsrCount)
pyplot.plot(pdfFsr/1e9, pdfCount)
pyplot.xlabel("fsr (GHz)")
pyplot.ylabel("count")
pyplot.show()
The plot is shown below: