Skip to content

Conversation

@adophobr
Copy link
Contributor

No description provided.

@edsonportosilva
Copy link
Owner

@adophobr

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a comprehensive semiconductor Distributed Feedback (DFB) laser simulation model to the optic package. The implementation provides rate equation solvers and intensity modulation response calculations for laser dynamics analysis.

Key Changes:

  • Added complete DFB laser model with rate equations solver
  • Implemented intensity modulation (IM) frequency response calculations
  • Added noise modeling capabilities for laser simulations

Reviewed changes

Copilot reviewed 2 out of 6 changed files in this pull request and generated 12 comments.

File Description
requirements.txt Formatting fix: added missing line number to sphinx-rtd-theme entry
optic/models/laser.py New module implementing DFB laser model with rate equations, noise sources, IM response calculations, and plotting utilities
docs/source/models.rst Added documentation reference for the new laser module

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +487 to +488
print('Invalid type of IM response.')
return -1
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using print() for error handling is not a best practice. Consider raising an exception (e.g., ValueError or TypeError) instead so that the caller can properly handle the error condition. The current implementation returns -1 which could lead to silent failures in downstream code.

Suggested change
print('Invalid type of IM response.')
return -1
raise ValueError(f"Invalid type of IM response: {type!r}. Expected 'exact' or 'approx.'.")

Copilot uses AI. Check for mistakes.
float
The electrical current at the specified time.
"""
return np.real(current.signal[np.argwhere(t >= current.t)[-1]])
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The get_current function may fail with an IndexError if t is less than all values in current.t. The expression np.argwhere(t >= current.t)[-1] will raise an IndexError on an empty array. Consider adding boundary checking or handling this edge case.

Suggested change
return np.real(current.signal[np.argwhere(t >= current.t)[-1]])
idxs = np.argwhere(t >= current.t)
if idxs.size == 0:
# If t is earlier than all sampled times, use the earliest available current.
idx = 0
else:
idx = idxs[-1]
return np.real(current.signal[idx])

Copilot uses AI. Check for mistakes.
Comment on lines +335 to +336
current = get_current(current, t)
return current/(e*param.v)-y[0]/param.tau_n-param.vg*param.a0*y[1]*(y[0]-param.n_t)/(1+param.epsilon*y[1])
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable shadowing in this function is problematic. The function parameter current is reassigned on line 335, which shadows the original parameter and makes the code harder to understand. Consider using a different variable name for the extracted current value, such as i_current or current_value.

Suggested change
current = get_current(current, t)
return current/(e*param.v)-y[0]/param.tau_n-param.vg*param.a0*y[1]*(y[0]-param.n_t)/(1+param.epsilon*y[1])
current_value = get_current(current, t)
return current_value/(e*param.v)-y[0]/param.tau_n-param.vg*param.a0*y[1]*(y[0]-param.n_t)/(1+param.epsilon*y[1])

Copilot uses AI. Check for mistakes.
Comment on lines +234 to +235
#rtol = 1e-4,
#atol = 1e-6,
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented-out tolerance parameters (rtol and atol) should either be removed if they're not needed, or uncommented with appropriate values if they're intended to be used. Leaving them commented without explanation reduces code clarity and maintainability.

Suggested change
#rtol = 1e-4,
#atol = 1e-6,

Copilot uses AI. Check for mistakes.
import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft
from scipy.integrate import solve_ivp,odeint
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing comma in import statement. The imports on line 17 should have a space after the comma separating solve_ivp and odeint for consistency with PEP 8 style guidelines.

Suggested change
from scipy.integrate import solve_ivp,odeint
from scipy.integrate import solve_ivp, odeint

Copilot uses AI. Check for mistakes.
Comment on lines +634 to +648
_extracted_from_plot_4(t, ax, 0, 0, 'Optical Power [mW]')
ax[1,0].plot(1e9*t, 1e-9*np.real(y.chirp))
_extracted_from_plot_4(t, ax, 1, 0, 'Chirp [GHz]')
ax[0,1].plot(1e9*t, np.real(y.N))
_extracted_from_plot_4(t, ax, 0, 1, r'Carrier density $N(t)$ [cm$^{-3}$]')
ax[1,1].plot(1e9*t, np.real(y.S))
_extracted_from_plot_4(t, ax, 1, 1, r'Photon Density $S(t)$ [cm$^{-3}$]')
plt.tight_layout()
return ax

def _extracted_from_plot_4(t, ax, arg1, arg2, arg3):
ax[arg1, arg2].set_xlabel('Time [ns]')
ax[arg1, arg2].set_ylabel(arg3)
ax[arg1, arg2].set_xlim(1e9*np.array([t.min(),t.max()]))
ax[arg1, arg2].grid(True) No newline at end of file
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name _extracted_from_plot_4 is not descriptive and appears to be an auto-generated refactoring artifact. Consider using a more meaningful name like _set_subplot_properties or _configure_subplot_axes to better describe what this helper function does.

Suggested change
_extracted_from_plot_4(t, ax, 0, 0, 'Optical Power [mW]')
ax[1,0].plot(1e9*t, 1e-9*np.real(y.chirp))
_extracted_from_plot_4(t, ax, 1, 0, 'Chirp [GHz]')
ax[0,1].plot(1e9*t, np.real(y.N))
_extracted_from_plot_4(t, ax, 0, 1, r'Carrier density $N(t)$ [cm$^{-3}$]')
ax[1,1].plot(1e9*t, np.real(y.S))
_extracted_from_plot_4(t, ax, 1, 1, r'Photon Density $S(t)$ [cm$^{-3}$]')
plt.tight_layout()
return ax
def _extracted_from_plot_4(t, ax, arg1, arg2, arg3):
ax[arg1, arg2].set_xlabel('Time [ns]')
ax[arg1, arg2].set_ylabel(arg3)
ax[arg1, arg2].set_xlim(1e9*np.array([t.min(),t.max()]))
ax[arg1, arg2].grid(True)
_set_subplot_properties(t, ax, 0, 0, 'Optical Power [mW]')
ax[1,0].plot(1e9*t, 1e-9*np.real(y.chirp))
_set_subplot_properties(t, ax, 1, 0, 'Chirp [GHz]')
ax[0,1].plot(1e9*t, np.real(y.N))
_set_subplot_properties(t, ax, 0, 1, r'Carrier density $N(t)$ [cm$^{-3}$]')
ax[1,1].plot(1e9*t, np.real(y.S))
_set_subplot_properties(t, ax, 1, 1, r'Photon Density $S(t)$ [cm$^{-3}$]')
plt.tight_layout()
return ax
def _set_subplot_properties(t, ax, row, col, ylabel):
ax[row, col].set_xlabel('Time [ns]')
ax[row, col].set_ylabel(ylabel)
ax[row, col].set_xlim(1e9*np.array([t.min(),t.max()]))
ax[row, col].grid(True)

Copilot uses AI. Check for mistakes.
out = parameters()
# get physical parameters
out.N = y[0,:]
out.S = y[1,: ]
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an extra space in the array indexing y[1,: ]. For consistency with the rest of the code (see line 177), this should be y[1,:] without the space before the closing bracket.

Suggested change
out.S = y[1,: ]
out.S = y[1,:]

Copilot uses AI. Check for mistakes.
"""
# diffusion coefficient - see ref. [2]
dss = (param.beta*y[0]*y[1]/param.tau_n)
#dnn = (y[0]/self.tau_n)*(1+self.beta*y[1])
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented-out line #dnn = (y[0]/self.tau_n)*(1+self.beta*y[1]) references self which doesn't exist in this function context. This appears to be leftover code from a class-based implementation. Either remove this comment if it's not needed, or update it to reflect the current function-based implementation if it's meant to be informative.

Suggested change
#dnn = (y[0]/self.tau_n)*(1+self.beta*y[1])
# dnn = (y[0] / param.tau_n) * (1 + param.beta * y[1])

Copilot uses AI. Check for mistakes.
"""Basic physical models for DFB laser."""
import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import fft from scipy.fft is unused. Consider removing unused imports to keep the code clean and reduce dependencies.

Suggested change
from scipy.fft import fft

Copilot uses AI. Check for mistakes.
dy = np.zeros(3)
# Carrier density
dy[0] = carrier_density(t,y,param,current)
# Foton density
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment "Foton density" contains a spelling error. The correct spelling is "Photon density".

Suggested change
# Foton density
# Photon density

Copilot uses AI. Check for mistakes.
@edsonportosilva
Copy link
Owner

@copilot open a new pull request to apply changes based on the comments in this thread

Additionally, refactor the functions names and documentation to make them compatible with the standard followed in the remaining of the repository.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 6 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"""
# diffusion coefficient - see ref. [2]
dss = (param.beta*y[0]*y[1]/param.tau_n)
#dnn = (y[0]/self.tau_n)*(1+self.beta*y[1])
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out code found in commented line referencing 'self.tau_n' and 'self.beta'. This appears to be leftover code from a class-based implementation. Consider removing commented-out code or adding a comment explaining why it's preserved.

Suggested change
#dnn = (y[0]/self.tau_n)*(1+self.beta*y[1])

Copilot uses AI. Check for mistakes.
Comment on lines +644 to +648
def _extracted_from_plot_4(t, ax, arg1, arg2, arg3):
ax[arg1, arg2].set_xlabel('Time [ns]')
ax[arg1, arg2].set_ylabel(arg3)
ax[arg1, arg2].set_xlim(1e9*np.array([t.min(),t.max()]))
ax[arg1, arg2].grid(True) No newline at end of file
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name '_extracted_from_plot_4' appears to be auto-generated by a refactoring tool. Consider renaming this to a more descriptive name like '_set_plot_properties' or '_configure_subplot_axis' to improve code readability.

Copilot uses AI. Check for mistakes.
Comment on lines +44 to +48
Mode confinement factor (default: 0.4).
- tau_p : float, optional
Photon lifetime (default: 3.0e-12).
- beta : float, optional
Fraction of spontaneous emission coupling (default: 3.0e-5).
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent indentation in docstring parameter descriptions. Line 44 has only one space for indentation while line 43 correctly has three spaces. The same issue appears on line 48.

Suggested change
Mode confinement factor (default: 0.4).
- tau_p : float, optional
Photon lifetime (default: 3.0e-12).
- beta : float, optional
Fraction of spontaneous emission coupling (default: 3.0e-5).
Mode confinement factor (default: 0.4).
- tau_p : float, optional
Photon lifetime (default: 3.0e-12).
- beta : float, optional
Fraction of spontaneous emission coupling (default: 3.0e-5).

Copilot uses AI. Check for mistakes.
dy = np.zeros(3)
# Carrier density
dy[0] = carrier_density(t,y,param,current)
# Foton density
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a spelling error in the comment. "Foton" should be "Photon".

Suggested change
# Foton density
# Photon density

Copilot uses AI. Check for mistakes.
param.tau_p = getattr(param, "tau_p", 3.0e-12)
param.beta = getattr(param, "beta", 3.0e-5)
param.alpha = getattr(param, "alpha", 5)
param.sigma = getattr(param, "sigma", 2e-20)
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter 'sigma' is set but never used anywhere in the code. Consider removing this unused parameter or documenting why it's reserved for future use.

Copilot uses AI. Check for mistakes.
Comment on lines +96 to +99
param.i_bias = getattr(param, 'i_bias', 0.078)
param.i_max = getattr(param, 'i_max', 0.188)
param.eta_0 = getattr(param, 'eta_0', 0.4)
param.lmbd = getattr(param, 'lmbd', 1300e-9)
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent quote style for string keys. Line 96 uses single quotes for 'i_bias', 'i_max', and 'eta_0' (lines 96-98), while line 99 uses 'lmbd'. This is inconsistent with the double quotes used in earlier lines (e.g., lines 84-95). Consider standardizing on either single or double quotes throughout the function.

Suggested change
param.i_bias = getattr(param, 'i_bias', 0.078)
param.i_max = getattr(param, 'i_max', 0.188)
param.eta_0 = getattr(param, 'eta_0', 0.4)
param.lmbd = getattr(param, 'lmbd', 1300e-9)
param.i_bias = getattr(param, "i_bias", 0.078)
param.i_max = getattr(param, "i_max", 0.188)
param.eta_0 = getattr(param, "eta_0", 0.4)
param.lmbd = getattr(param, "lmbd", 1300e-9)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants