Source code for piel.models.transient.electro_optic.pulsed_laser
import numpy as np
from piel.types import PulsedLaser, TimeSignalData, ns, W
[docs]
def generate_laser_time_data_pulses(
pulsed_laser: PulsedLaser,
time_frame_s: float,
point_amount: int,
data_name: str = "optical_pulse_power",
) -> TimeSignalData:
"""
Converts PulsedLaser metrics into a time-domain signal representation.
Parameters:
- pulsed_laser (PulsedLaser): The pulsed laser object containing metrics.
- time_frame_s (float): Total duration of the time signal in seconds.
- point_amount (int): Number of points in the time and data arrays.
- data_name (str): Name/description of the data signal.
Returns:
- TimeSignalData: The time-domain signal data.
"""
if not pulsed_laser.metrics:
raise ValueError(
"PulsedLaser object must contain at least one PulsedLaserMetrics."
)
# Assuming we use the first set of metrics
metrics = pulsed_laser.metrics[0]
time_frame_ns = time_frame_s * 1e9
# Extract necessary metrics with proper unit conversions
pulse_repetition_rate_Hz = metrics.pulse_repetition_rate_Hz.value # in Hz
pulse_width_ns = metrics.pulse_width_s.min * 1e9 # Convert seconds to nanoseconds
pulse_amplitude_W = metrics.pulse_power_W.max # in Watts
# Calculate pulse interval in nanoseconds
pulse_interval_ns = 1e9 / pulse_repetition_rate_Hz # nanoseconds
# Calculate the number of pulses that fit within the time frame
num_pulses = int(np.floor(time_frame_ns / pulse_interval_ns))
# Generate pulse start and end times in nanoseconds
pulse_start_times_ns = np.arange(num_pulses) * pulse_interval_ns
pulse_end_times_ns = pulse_start_times_ns + pulse_width_ns
# Ensure that pulse_end_times_ns do not exceed the total time frame
pulse_end_times_ns = np.clip(pulse_end_times_ns, None, time_frame_ns)
# Calculate time step in nanoseconds
time_step_ns = time_frame_ns / point_amount
# Check if pulse_width_ns is at least one time step
if pulse_width_ns < time_step_ns:
print(
"Warning: Pulse width is smaller than the time step. Pulses may not be visible."
)
# Generate the time array in nanoseconds
time_array_ns = np.linspace(0, time_frame_ns, point_amount, endpoint=False)
# Initialize data array with zeros
data_array = np.zeros(point_amount)
# Find start and end indices for each pulse using searchsorted
start_indices = np.searchsorted(time_array_ns, pulse_start_times_ns, side="left")
end_indices = np.searchsorted(time_array_ns, pulse_end_times_ns, side="right")
# Ensure that end_indices are within bounds
end_indices = np.clip(end_indices, 0, point_amount)
# Assign pulse amplitudes using vectorized operations
for start, end in zip(start_indices, end_indices):
if start < end:
data_array[start:end] = pulse_amplitude_W
# Create TimeSignalData object
signal_data = TimeSignalData(
time_s=time_array_ns.tolist(), # Time in nanoseconds
data=data_array.tolist(),
data_name=data_name,
time_s_unit=ns, # nanoseconds
data_unit=W, # Watts
)
return signal_data