diff --git a/pyproject.toml b/pyproject.toml index d01e833..86fedb3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "scgenerator" -version = "0.3.24" +version = "0.3.25" description = "Simulate nonlinear pulse propagation in optical fibers" readme = "README.md" authors = [{ name = "Benoit Sierro", email = "benoit.sierro@iap.unibe.ch" }] diff --git a/src/scgenerator/noise.py b/src/scgenerator/noise.py index b18e284..ec0cd8b 100644 --- a/src/scgenerator/noise.py +++ b/src/scgenerator/noise.py @@ -217,6 +217,8 @@ class NoiseMeasurement: spec[1:-1] *= 0.5 if phase is None: phase = 2 * np.pi * self.rng.random(len(freq) - 2) + elif phase.shape[-1] != len(freq) - 2: + phase = np.interp(freq, self.freq, phase)[1:-1] time, dt = math.irfftfreq(freq, True) amp = np.asarray(np.sqrt(spec), dtype=complex) diff --git a/src/scgenerator/physics/pulse.py b/src/scgenerator/physics/pulse.py index 4ac72ed..6856462 100644 --- a/src/scgenerator/physics/pulse.py +++ b/src/scgenerator/physics/pulse.py @@ -545,11 +545,11 @@ def shot_noise(w: np.ndarray, dt: float): dw = w[1] - w[0] rand_phase = np.random.rand(len(w)) * 2 * pi - oppm_phase = np.exp(-1j * rand_phase) + shot_noise_phase = np.exp(-1j * rand_phase) - oppm_amp = np.sqrt(0.5 * units.hbar * np.abs(w) / dw) + shot_noise_amplitude = np.sqrt(0.5 * units.hbar * np.abs(w) / dw) - return ifft(oppm_amp * oppm_phase / dt * np.sqrt(2 * pi)) + return ifft(shot_noise_amplitude * shot_noise_phase / dt * np.sqrt(2 * pi)) def finalize_pulse( @@ -614,7 +614,29 @@ def compress_pulse(spectra: np.ndarray): else: return fftshift(ifft(flatten_phase(spectra)), axes=1) +def shot_noise(w: np.ndarray, dt: float): + """ + Parameters + ---------- + w : array, shape (n,) + angular frequencies + dt : float + resolution of time grid + + Returns + ------- + np.ndarray, shape (n,) + noise field to be added on top of initial field in time domain + """ + dw = w[1] - w[0] + + rand_phase = np.random.rand(len(w)) * 2 * pi + shot_noise_phase = np.exp(-1j * rand_phase) + + shot_noise_amplitude = np.sqrt(0.5 * units.hbar * np.abs(w) / dw) + + return ifft(shot_noise_amplitude * shot_noise_phase / dt * np.sqrt(2 * pi)) def ideal_compressed_pulse(spectra: np.ndarray): """ returns the ideal compressed pulse assuming flat phase diff --git a/src/scgenerator/physics/units.py b/src/scgenerator/physics/units.py index cbf093b..959e1a3 100644 --- a/src/scgenerator/physics/units.py +++ b/src/scgenerator/physics/units.py @@ -375,14 +375,26 @@ def nm_rads(nm: _T) -> _T: return 2e9 * np.pi * c / nm +def nm_hz(nm: _T) -> _T: + return 1e9 * c / nm + + def um_rads(um: _T) -> _T: return 2e6 * np.pi * c / um +def um_hz(um: _T) -> _T: + return 1e6 * c / um + + def m_rads(m: _T) -> _T: return 2 * np.pi * c / m +def m_hz(m: _T) -> _T: + return c / m + + def get_unit(unit: Union[str, Callable]) -> Callable[[float], float]: if isinstance(unit, str): return units_map[unit]