Variability analysis of Mach-Zehnder lattice design

In this sample we explore the effect of phase errors in the waveguides, on the performance of a MZI lattice filter.

This example is created as a set of files. The directional coupler, lattice PCell and waveguide are defined in separate files and part of this example.


To run this file, you will also need to download mzi_lattice.py, dc.py, waveguide_template.py, params.p

from demolib import technology                          # example technology "demolib" in IPKISS
import ipkiss3.all as i3                                # ipkiss itself
import numpy as np                                      # numpy numerical library
import pylab as plt                                     # matplotlib plotting library
from mzi_lattice import MZIPass                         # use the MZIPass Pcell we've created


wavelengths = np.linspace(1.51, 1.6, 500)


def get_response():                                     # function which gets the spectral response (in frequency domain) of the MZIPass device.
    cell = MZIPass(fsr=0.05,                            # we tune the phase error:
                   phase_error_width_deviation=0.001,   # standard deviation (amplitude) of the sidewall roughness;
                   phase_error_correlation_length=0.5   # correlation length (in um) of the sidewall roughness.
                   )
    lv = cell.Layout()
    lv.write_gdsii("lattice.gds")
    cm = cell.CircuitModel()
    S = cm.get_smatrix(wavelengths=wavelengths)

    return S['in1', 'out1'], S['in1', 'out2']           # returns s-parameter of in1-out1 and in1-out2


s13, s14 = get_response()

fig1 = plt.figure()                                     # plot the calculated transmission spectrum
plt.plot(wavelengths, np.abs(s13)**2)
plt.plot(wavelengths, np.abs(s14)**2)
plt.show()


def get_xtalk_dB(spectrum, wl_range=[1.555, 1.575]):    # function that extracts the maximum cross-talk value on the first band (1.539 - 1.541 um)
    """Calculate the crosstalk in a certain band."""
    idx_min = np.argmin(np.abs(wavelengths - wl_range[0]))
    idx_max = np.argmin(np.abs(wavelengths - wl_range[1]))
    max_value = np.max(np.abs(spectrum[idx_min:idx_max]))
    return 20 * np.log10(np.abs(max_value))             # return the max cross-talk value in dB


def get_crosstalk(get_response_fn=get_response, num_samples=10, plot=False):    # function that sweep over a number of samples for spectral responses (with plot) and extract maximum cross-talk values.
    xt = np.zeros((num_samples,))

    for x in xrange(num_samples):
        t11, t12 = get_response_fn()

        xt[x] = get_xtalk_dB(t11)
        if plot:
            plt.plot(wavelengths, 20 * np.log10(np.abs(t11)), 'r', alpha=0.2)
            plt.plot(wavelengths, 20 * np.log10(np.abs(t12)), 'r', alpha=0.2)
            plt.hlines(xt[x], wavelengths[0], wavelengths[-1], 'g', alpha=0.5)
            plt.ylabel("Transmission (dB)")
            plt.xlabel("Wavelength ($\mu$ m)")
            plt.ylim([-40, 0])

    return xt                                           # return list of max cross-talk values

num_samples = 20

fig2 = plt.figure()
xt = get_crosstalk(num_samples=num_samples, plot=True)
plt.show()
  • ../../_images/sphx_glr_plot_mzi_variab_analysis_001.png
  • ../../_images/sphx_glr_plot_mzi_variab_analysis_002.png

Now let’s plot a cumulative distribution function (cdf) to display how much of the samples are within a certain crosstalk level. You can adjust the phase error in the model to check how this function changes. Note that you may need to increase the number of samples (> 100) to get a representative result.

num_bins = 8
n, bins, patches = plt.hist(xt, num_bins, normed=1, histtype='stepfilled',
                            cumulative=True, facecolor='b', alpha=0.5)
plt.title('Cumulative distribution function of maximum crosstalk values')
plt.xlabel("Maximum crosstalk (dB)")
plt.ylabel("Occurrence")
plt.show()
../../_images/sphx_glr_plot_mzi_variab_analysis_003.png

Out:

/bbotworker/IPKISSDOC/build/_blddoc/lib/python2.7/site-packages/matplotlib/axes/_axes.py:6571: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.
  warnings.warn("The 'normed' kwarg is deprecated, and has been "

To run this file, you will also need to download mzi_lattice.py, dc.py, waveguide_template.py, params.p.