Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added tests for LongitudinalProfileFromData and fix for issue #185 #304

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5045667
Added tests for LongitudinalProfileFromData
Oct 8, 2024
c325c05
Monotonically decreasing spectral data in LongitudinalProfileFromData
Oct 8, 2024
60a6fc6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 8, 2024
d67b2a2
Updated tests
Oct 8, 2024
8dfae34
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 8, 2024
b38e4a4
Minor correction
Oct 8, 2024
7434295
em-archer
Oct 8, 2024
36f7e57
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 8, 2024
ff58c8b
Minor correction
Oct 8, 2024
c4dc18d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 8, 2024
fd0dda1
Syntax
Oct 8, 2024
8667d78
Syntax conflict
Oct 9, 2024
aef6bef
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 9, 2024
293fba0
em-archer
Oct 9, 2024
bb23517
em-archer
Oct 9, 2024
a366342
Should now include phase
Oct 9, 2024
bc0112b
Final commit
Oct 9, 2024
6951008
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 9, 2024
dfbb025
Fixing flipping of arrays
Oct 9, 2024
63854d3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 9, 2024
7e231f1
em-archer
Oct 9, 2024
e2ed172
Assertions also checked with separate notebook
Oct 9, 2024
d05893f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 9, 2024
5186fdd
Increase time resolution
Oct 9, 2024
4b2b40a
Modified to also allow spectral data to be specified with respect to …
Oct 10, 2024
804f5bf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 10, 2024
5e7a93f
Merge branch 'LASY-org:development' into development
em-archer Oct 14, 2024
fb5aabc
Added requirement for user to specify axis type
Oct 14, 2024
39e81a1
Merge branch 'LASY-org:development' into development
em-archer Oct 14, 2024
16e70ee
Merge branch 'development' of https://github.com/em-archer/lasy into …
Oct 14, 2024
07ada48
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 14, 2024
51d67b2
Merge branch 'LASY-org:development' into development
em-archer Oct 15, 2024
e6dab5d
Update lasy/profiles/longitudinal/longitudinal_profile_from_data.py
em-archer Oct 16, 2024
1c6f7a3
Update lasy/profiles/longitudinal/longitudinal_profile_from_data.py
em-archer Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions lasy/profiles/longitudinal/longitudinal_profile_from_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ class LongitudinalProfileFromData(LongitudinalProfile):

datatype : string
The domain in which the data has been passed. Options
are 'spectral' and 'temporal'
are 'spectral' and 'temporal'. Spectral data may either be,
a) Wavelength dependent (lambda): data["axis_is_wavelength"] = True or
b) Angular freuqency dependent (omega): data["axis_is_wavelength"] = False
em-archer marked this conversation as resolved.
Show resolved Hide resolved

em-archer marked this conversation as resolved.
Show resolved Hide resolved
axis : ndarrays of floats
The horizontal axis of the pulse duration measurement.
The array must be monotonously increasing.
When datatype is 'spectral' axis is wavelength in meters.
The array must be monotonically increasing or decreasing.
When datatype is 'spectral' axis is wavelength in meters OR
angular frequency in 1/seconds.
em-archer marked this conversation as resolved.
Show resolved Hide resolved
When datatype is 'temporal' axis is time in seconds.

intensity : ndarrays of floats
Expand Down Expand Up @@ -60,16 +63,27 @@ class LongitudinalProfileFromData(LongitudinalProfile):

def __init__(self, data, lo, hi):
if data["datatype"] == "spectral":
# First find central frequency
wavelength = data["axis"]
assert np.all(
np.diff(wavelength) > 0
), 'data["axis"] must be in monotonously increasing order.'
spectral_intensity = data["intensity"]
if "axis_is_wavelength" not in data: # Set to wavelength data by default
data["axis_is_wavelength"] = True
em-archer marked this conversation as resolved.
Show resolved Hide resolved
if data["axis_is_wavelength"]:
wavelength = data["axis"] # Accept as wavelength
spectral_intensity = data["intensity"]
else:
wavelength = 2.0 * np.pi * c / data["axis"] # Convert to wavelength
spectral_intensity = (
data["intensity"] * 2.0 * np.pi * c / wavelength**2
) # Convert spectral data
assert np.all(np.diff(wavelength) > 0) or np.all(
np.diff(wavelength) < 0
), 'data["axis"] must be in monotonically increasing or decreasing order.'
if data.get("phase") is None:
spectral_phase = np.zeros_like(wavelength)
else:
spectral_phase = data["phase"]
if np.all(np.diff(wavelength) < 0): # Flip arrays
wavelength = wavelength[::-1]
spectral_intensity = spectral_intensity[::-1]
spectral_phase = spectral_phase[::-1]
dt = data["dt"]
cwl = np.sum(spectral_intensity * wavelength) / np.sum(spectral_intensity)
cfreq = c / cwl
Expand Down
89 changes: 89 additions & 0 deletions tests/test_laser_profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from lasy.profiles.longitudinal import (
CosineLongitudinalProfile,
GaussianLongitudinalProfile,
LongitudinalProfileFromData,
SuperGaussianLongitudinalProfile,
)
from lasy.profiles.profile import Profile, ScaledProfile, SummedProfile
Expand Down Expand Up @@ -153,11 +154,14 @@ def test_longitudinal_profiles():

wavelength = 800e-9
tau_fwhm = 30.0e-15
omega_fwhm = 4 * np.log(2) / tau_fwhm # Assumes fully-compressed
t_peak = 1.0 * tau_fwhm
cep_phase = 0.5 * np.pi
omega_0 = 2.0 * np.pi * c / wavelength

t = np.linspace(t_peak - 4 * tau_fwhm, t_peak + 4 * tau_fwhm, npoints)
omega = np.linspace(omega_0 - 4 * omega_fwhm, omega_0 + 4 * omega_fwhm, npoints)
wavelength_axis = 2.0 * np.pi * c / omega # Note: monotonically decreasing

# GaussianLongitudinalProfile
print("GaussianLongitudinalProfile")
Expand Down Expand Up @@ -234,6 +238,91 @@ def test_longitudinal_profiles():
print("cep_phase = ", cep_phase_cos)
assert np.abs(cep_phase_cos - cep_phase) / cep_phase < 0.02

# LongitudinalProfileFromData
print("LongitudinalProfileFromData")
data = {} # Generate spectral data assuming analytic Fourier transform of GaussianLongitudinalProfile
data["datatype"] = "spectral"
data["dt"] = 1e-16
profile = np.exp(
Fixed Show fixed Hide fixed
-(tau**2) * ((omega - omega_0) ** 2) / 4.0 + 1.0j * (cep_phase + omega * t_peak)
)
spectral_intensity = np.abs(profile) ** 2 / np.max(np.abs(profile) ** 2)
spectral_phase = np.unwrap(np.angle(profile))

print("Case 1: monotonically decreasing data on wavelength axis")
data["axis"] = wavelength_axis
data["intensity"] = spectral_intensity
data["phase"] = spectral_phase
profile_data = LongitudinalProfileFromData(data, np.min(t), np.max(t))
field_data = profile_data.evaluate(t)

std_gauss_data = np.sqrt(np.average((t - t_peak) ** 2, weights=np.abs(field_data)))
std_gauss_th = tau / np.sqrt(2.0)
print("std_th = ", std_gauss_th)
print("std = ", std_gauss_data)
assert np.abs(std_gauss_data - std_gauss_th) / std_gauss_th < 0.01

t_peak_gaussian_data = t[np.argmax(np.abs(field_data))]
print("t_peak_th = ", t_peak)
print("t_peak = ", t_peak_gaussian_data)
assert np.abs(t_peak_gaussian_data - t_peak) / t_peak < 0.01

print("Case 2: monotonically increasing data on wavelength axis")
data["axis"] = wavelength_axis[::-1]
data["intensity"] = spectral_intensity[::-1]
data["phase"] = spectral_phase[::-1]
profile_data = LongitudinalProfileFromData(data, np.min(t), np.max(t))
field_data = profile_data.evaluate(t)

std_gauss_data = np.sqrt(np.average((t - t_peak) ** 2, weights=np.abs(field_data)))
std_gauss_th = tau / np.sqrt(2.0)
print("std_th = ", std_gauss_th)
print("std = ", std_gauss_data)
assert np.abs(std_gauss_data - std_gauss_th) / std_gauss_th < 0.01

t_peak_gaussian_data = t[np.argmax(np.abs(field_data))]
print("t_peak_th = ", t_peak)
print("t_peak = ", t_peak_gaussian_data)
assert np.abs(t_peak_gaussian_data - t_peak) / t_peak < 0.01

print("Case 3: monotonically increasing data on angular frequency axis")
data["axis"] = omega
data["intensity"] = spectral_intensity
data["phase"] = spectral_phase
data["axis_is_wavelength"] = False
profile_data = LongitudinalProfileFromData(data, np.min(t), np.max(t))
field_data = profile_data.evaluate(t)

std_gauss_data = np.sqrt(np.average((t - t_peak) ** 2, weights=np.abs(field_data)))
std_gauss_th = tau / np.sqrt(2.0)
print("std_th = ", std_gauss_th)
print("std = ", std_gauss_data)
assert np.abs(std_gauss_data - std_gauss_th) / std_gauss_th < 0.01

t_peak_gaussian_data = t[np.argmax(np.abs(field_data))]
print("t_peak_th = ", t_peak)
print("t_peak = ", t_peak_gaussian_data)
assert np.abs(t_peak_gaussian_data - t_peak) / t_peak < 0.01

print("Case 4: monotonically decreasing data on angular frequency axis")
data["axis"] = omega[::-1]
data["intensity"] = spectral_intensity[::-1]
data["phase"] = spectral_phase[::-1]
data["axis_is_wavelength"] = False
profile_data = LongitudinalProfileFromData(data, np.min(t), np.max(t))
field_data = profile_data.evaluate(t)

std_gauss_data = np.sqrt(np.average((t - t_peak) ** 2, weights=np.abs(field_data)))
std_gauss_th = tau / np.sqrt(2.0)
print("std_th = ", std_gauss_th)
print("std = ", std_gauss_data)
assert np.abs(std_gauss_data - std_gauss_th) / std_gauss_th < 0.01

t_peak_gaussian_data = t[np.argmax(np.abs(field_data))]
print("t_peak_th = ", t_peak)
print("t_peak = ", t_peak_gaussian_data)
assert np.abs(t_peak_gaussian_data - t_peak) / t_peak < 0.01


def test_profile_gaussian_3d_cartesian(gaussian):
# - 3D Cartesian case
Expand Down
Loading