Laser Pulse with user-defined longitudinal profile#

In this example we show how to define a custom longitudinal profile based on an analytical expression (in this case a “flat-top” profile that rises smoothly from zero to one as a squared cosine, stays constant for some time, and then goes smoothly to zero as a squared cosine).

Define a derived class of LongitudinalProfile: MyOwnLongitudinalProfile#

First, we define a new class MyOwnLongitudinalProfile, inheriting the LongitudinalProfile class. We need to implement the __init__ method to record the parameters of the custom profile, and the evaluate method that should return the envelope as a function of the time.

[1]:
from lasy.profiles.longitudinal import LongitudinalProfile


# User-defined profile
class MyOwnLongitudinalProfile(LongitudinalProfile):
    r"""
    Derived class for the analytic longitudinal flat-top profile of a laser pulse.

    i.e., a longitudinal profile that rises smoothly from zero to one (as a squared cosine),
    stays constant for some time and then goes down smoothly to zero (as a squared cosine).

    Parameters
    ----------
    wavelength : float (in meter)
        The main laser wavelength :math:`\lambda_0` of the laser.
    t_start : float (in seconds)
        The starting time of the pulse,
    t_rise : float (in seconds)
        The rise time of the pulse envelope,
    t_flat : float (in seconds)
        The duration of the flat part of the pulse envelope,
    t_down : float (in seconds)
        The duration of the decreasing part of the pulse envelope,
    cep_phase : float (in radian), optional
        The Carrier Enveloppe Phase (CEP)

    """

    def __init__(self, wavelength, t_start, t_rise, t_flat, t_down, cep_phase):
        super().__init__(wavelength)
        self.t_start = t_start
        self.t_rise = t_rise
        self.t_flat = t_flat
        self.t_down = t_down
        self.cep_phase = cep_phase

    def evaluate(self, t):
        """
        Return the longitudinal envelope.

        Parameters
        ----------
        t : ndarrays of floats
            Define points on which to evaluate the envelope

        Returns
        -------
        envelope : ndarray of complex numbers
            Contains the value of the longitudinal envelope at the
            specified points. This array has the same shape as the array t.
        """
        t1 = self.t_start
        t2 = t1 + self.t_rise
        t3 = t2 + self.t_flat
        t4 = t3 + self.t_down
        tcep = 0.5 * (t3 + t2)

        envelope = (
            (t >= t1) * (t < t2) * np.cos(0.5 * np.pi * (t - t2) / (t2 - t1)) ** 2
            + (t >= t2) * (t < t3)
            + (t >= t3) * (t < t4) * np.cos(0.5 * np.pi * (t - t3) / (t3 - t4)) ** 2
        ) * np.exp(+1.0j * (self.cep_phase + self.omega0 * tcep))

        return envelope
LASY: using backend NP

Use MyOwnLongitudinalProfile as a regular longitudinal profile#

The new class MyOwnLongitudinalProfile can be used just like any other longitudinal profile

[2]:
wavelength = 800e-6
t_start = 0
t_rise = 20e-15
t_flat = 20e-15
t_down = 10e-15
cep_phase = 0
longitudinal_profile = MyOwnLongitudinalProfile(
    wavelength, t_start, t_rise, t_flat, t_down, cep_phase
)
[3]:
# test the custom longitudinal profile
import matplotlib.pyplot as plt
import numpy as np

times = np.linspace(0.0, 55e-15, 300)
plt.plot(times, np.abs(longitudinal_profile.evaluate(times)))
[3]:
[<matplotlib.lines.Line2D at 0x7350c54daf50>]
../_images/tutorials_user_defined_longitudinal_profile_5_1.png
[ ]: