Repository: LASY-org/lasy
Pull request #363: Update definition of Flattened Gaussian to include both NF and FF
Author: login: rob-shalloo
Created: 2025-02-20T23:12:43Z | Merged: 2025-03-31T12:06:17Z

Updating Alberto's recent addition of a flattened Gaussian beam to include the case where the beam is defined in the nearfield, compared to only defining in the far field. 

Addresses #354



Diff:
diff --git a/docs/source/api/profiles/transverse/flattened_gaussian.rst b/docs/source/api/profiles/transverse/flattened_gaussian.rst
new file mode 100644
index 000000000..ad37f0f63
--- /dev/null
+++ b/docs/source/api/profiles/transverse/flattened_gaussian.rst
@@ -0,0 +1,10 @@
+Flattened Gaussian Transverse Profile
+=====================================
+
+Implements a flattened transverse Gaussian profile.
+This profile can either be defined close to a focus, in a far-field regime or in a collimated beam in the near field.
+
+------------
+
+.. autoclass:: lasy.profiles.transverse.FlattenedGaussianTransverseProfile
+    :members:
diff --git a/docs/source/api/profiles/transverse/index.rst b/docs/source/api/profiles/transverse/index.rst
index 45767445b..a327b18b2 100644
--- a/docs/source/api/profiles/transverse/index.rst
+++ b/docs/source/api/profiles/transverse/index.rst
@@ -14,3 +14,4 @@ Transverse Laser Profiles
    super_gaussian_profile
    jinc_profile
    transverse_profile_from_data
+   flattened_gaussian
diff --git a/lasy/profiles/transverse/__init__.py b/lasy/profiles/transverse/__init__.py
index af9daa7ac..e0d80190d 100644
--- a/lasy/profiles/transverse/__init__.py
+++ b/lasy/profiles/transverse/__init__.py
@@ -1,3 +1,4 @@
+from .flattened_gaussian_profile import FlattenedGaussianTransverseProfile
 from .gaussian_profile import GaussianTransverseProfile
 from .hermite_gaussian_profile import HermiteGaussianTransverseProfile
 from .jinc_profile import JincTransverseProfile
@@ -20,4 +21,5 @@
     "TransverseProfile",
     "SummedTransverseProfile",
     "ScaledTransverseProfile",
+    "FlattenedGaussianTransverseProfile",
 ]
diff --git a/lasy/profiles/transverse/flattened_gaussian_profile.py b/lasy/profiles/transverse/flattened_gaussian_profile.py
index 6d1b6fffb..ec078caff 100644
--- a/lasy/profiles/transverse/flattened_gaussian_profile.py
+++ b/lasy/profiles/transverse/flattened_gaussian_profile.py
@@ -1,3 +1,5 @@
+import math
+
 import numpy as np
 from scipy.special import binom
 
@@ -9,7 +11,7 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
@@ -17,84 +19,104 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=0`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
-        E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        E(x,y,z=0) \propto
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
+
+    .. math::
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for **the collimated beam** in the near field which produces this focus is
+    given by:
 
     .. math::
 
-        E(x,y,z=\infty) \propto
-        \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
-        \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
+        E(x,y) \propto
+        \exp\left(-\frac{(N+1)r^2}{w^2}\right)
+        \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w^2}\right)^n
+
+    with the relationship between the spot sizes of the beams in the far field and in the near field given by:
+
+    .. math::
 
-        \mathrm{with} \qquad w(z) = \frac{\lambda_0}{\pi w0}|z-z_{foc}|
+        w = \frac{\lambda_0}{\pi w_0}|z_{\mathrm{foc}}|
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_(z)^2}\right)`.
+    where :math:`z_{\mathrm{foc}}` is the distance between the far field and near field planes.
 
-    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto \Theta(w(z)-r)`.
+    - Note that a beam defined using the near field definition would be
+      equivalent to a beam defined with the corresponding parameters far from focus in
+      the far field, but without the parabolic phase arising from being
+      defined far from the focus.
+
+    - For :math:`N=0`, the near field profile is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w^2}\right)`.
+    - For :math:`N\rightarrow\infty`, the near field profile is a flat profile: :math:`E\propto\Theta(w-r)`.
 
     Parameters
     ----------
-    w0 : float (in meter)
-        The waist of the laser pulse,
-        i.e. :math:`w_{0}` in the above formula.
-    N: int
+    field_type : string
+        Options: 'nearfield', when the beam is defined far from focus (e.g., right before the focusing optics), or 'farfield', when the beam is in the vicinity of the focus.
+
+    w : float (in meter)
+        The waist of the laser pulse. If ``field_type == 'farfield'`` then this
+        variable corresponds to :math:`w_{0}` in the above far field formula.
+        If ``field_type == 'nearfield'`` then this variable corresponds to
+        :math:`w` in the above near field formula.
+
+    N : int
         Determines the "flatness" of the transverse profile, far from
         focus (see the above formula).
         Default: ``N=6`` ; somewhat close to an 8th order supergaussian.
+
     wavelength : float (in meter)
         The main laser wavelength :math:`\lambda_0` of the laser.
-    z_foc : float (in meter), optional
-        Position of the focal plane. (The laser pulse is initialized at
-        ``z=0``.)
-
-    Warnings
-    --------
-    In order to initialize the pulse out of focus, you can either:
 
-    - Use a non-zero ``z_foc``
-    - Use ``z_foc=0`` (i.e. initialize the pulse at focus) and then call
-      ``laser.propagate(-z_foc)``
+    z_foc : float (in meter), optional
+        Only required if defining the pulse in the far field. Gives the position
+        of the focal plane. (The laser pulse is initialized at ``z=0``.)
 
-    Both methods are in principle equivalent, but note that the first
-    method uses the paraxial approximation, while the second method does
-    not make this approximation.
     """
 
-    def __init__(self, w0, N, wavelength, z_foc=0):
+    def __init__(self, field_type, w, N, wavelength, z_foc=0):
         super().__init__()
         # Ensure that N is an integer
-        self.N = int(round(N))
-        # Calculate effective waist of the Laguerre-Gauss modes, at focus
-        self.w_foc = w0 * (self.N + 1) ** 0.5
-        # Calculate Rayleigh Length
-        self.zr = np.pi * self.w_foc**2 / wavelength
-        # Evaluation distance w.r.t focal position
-        self.z_eval = z_foc
-        # Calculate the coefficients for the Laguerre-Gaussian modes
-        self.cn = np.empty(self.N + 1)
-        for n in range(self.N + 1):
-            m_values = np.arange(n, self.N + 1)
-            self.cn[n] = np.sum((1.0 / 2) ** m_values * binom(m_values, n)) / (
-                self.N + 1
-            )
+        assert isinstance(N, int) and N >= 0
+        assert field_type in ["nearfield", "farfield"]
+        self.field_type = field_type
+        self.N = N
+
+        if field_type == "farfield":
+            w0 = w
+            # Calculate effective waist of the Laguerre-Gauss modes, at focus
+            self.w_foc = w0 * (self.N + 1) ** 0.5
+            # Calculate Rayleigh Length
+            self.zr = np.pi * self.w_foc**2 / wavelength
+            # Evaluation distance w.r.t focal position
+            self.z_eval = z_foc
+            # Calculate the coefficients for the Laguerre-Gaussian modes
+            self.cn = np.empty(self.N + 1)
+            for n in range(self.N + 1):
+                m_values = np.arange(n, self.N + 1)
+                self.cn[n] = np.sum((1.0 / 2) ** m_values * binom(m_values, n)) / (
+                    self.N + 1
+                )
+        else:
+            self.w = w
 
     def _evaluate(self, x, y):
         """
@@ -112,34 +134,49 @@ def _evaluate(self, x, y):
             Contains the value of the envelope at the specified points
             This array has the same shape as the arrays x, y
         """
-        # Term for wavefront curvature + Gouy phase
-        diffract_factor = 1.0 - 1j * self.z_eval / self.zr
-        w = self.w_foc * np.abs(diffract_factor)
-        psi = np.angle(diffract_factor)
-        # Argument for the Laguerre polynomials
-        scaled_radius_squared = 2 * (x**2 + y**2) / w**2
-
-        # Sum recursively over the Laguerre polynomials
-        laguerre_sum = np.zeros_like(x, dtype=np.complex128)
-        for n in range(0, self.N + 1):
-            # Recursive calculation of the Laguerre polynomial
-            # - `L` represents $L_n$
-            # - `L1` represents $L_{n-1}$
-            # - `L2` represents $L_{n-2}$
-            if n == 0:
-                L = 1.0
-            elif n == 1:
-                L1 = L
-                L = 1.0 - scaled_radius_squared
-            else:
-                L2 = L1
-                L1 = L
-                L = (((2 * n - 1) - scaled_radius_squared) * L1 - (n - 1) * L2) / n
-            # Add to the sum, including the term for the additional Gouy phase
-            laguerre_sum += self.cn[n] * np.exp(-(2j * n) * psi) * L
-
-        # Final envelope: multiply by n-independent propagation factors
-        exp_argument = -(x**2 + y**2) / (self.w_foc**2 * diffract_factor)
-        envelope = laguerre_sum * np.exp(exp_argument) / diffract_factor
-
-        return envelope
+        if self.field_type == "farfield":
+            # Term for wavefront curvature + Gouy phase
+            diffract_factor = 1.0 - 1j * self.z_eval / self.zr
+            w = self.w_foc * np.abs(diffract_factor)
+            psi = np.angle(diffract_factor)
+            # Argument for the Laguerre polynomials
+            scaled_radius_squared = 2 * (x**2 + y**2) / w**2
+
+            # Sum recursively over the Laguerre polynomials
+            laguerre_sum = np.zeros_like(x, dtype=np.complex128)
+            for n in range(0, self.N + 1):
+                # Recursive calculation of the Laguerre polynomial
+                # - `L` represents $L_n$
+                # - `L1` represents $L_{n-1}$
+                # - `L2` represents $L_{n-2}$
+                if n == 0:
+                    L = 1.0
+                elif n == 1:
+                    L1 = L
+                    L = 1.0 - scaled_radius_squared
+                else:
+                    L2 = L1
+                    L1 = L
+                    L = (((2 * n - 1) - scaled_radius_squared) * L1 - (n - 1) * L2) / n
+                # Add to the sum, including the term for the additional Gouy phase
+                laguerre_sum += self.cn[n] * np.exp(-(2j * n) * psi) * L
+
+            # Final envelope: multiply by n-independent propagation factors
+            exp_argument = -(x**2 + y**2) / (self.w_foc**2 * diffract_factor)
+            envelope = laguerre_sum * np.exp(exp_argument) / diffract_factor
+
+            return envelope
+
+        else:
+            N = self.N
+            w = self.w
+
+            sumseries = 0
+            for n in range(N + 1):
+                sumseries += (
+                    1 / math.factorial(n) * ((N + 1) * (x**2 + y**2) / w**2) ** n
+                )
+
+            envelope = np.exp(-(N + 1) * (x**2 + y**2) / w**2) * sumseries
+
+            return envelope
diff --git a/tests/test_laser_profiles.py b/tests/test_laser_profiles.py
index d328f472a..04ca52829 100644
--- a/tests/test_laser_profiles.py
+++ b/tests/test_laser_profiles.py
@@ -1,11 +1,19 @@
 # -*- coding: utf-8 -*-
 
+import copy
+
 import numpy as np
 import pytest
 from scipy.constants import c
 
 from lasy.laser import Laser
-from lasy.profiles import FromArrayProfile, GaussianProfile, SpeckleProfile
+from lasy.optical_elements.parabolic_mirror import ParabolicMirror
+from lasy.profiles import (
+    CombinedLongitudinalTransverseProfile,
+    FromArrayProfile,
+    GaussianProfile,
+    SpeckleProfile,
+)
 from lasy.profiles.longitudinal import (
     CosineLongitudinalProfile,
     GaussianLongitudinalProfile,
@@ -14,6 +22,7 @@
 )
 from lasy.profiles.profile import Profile, ScaledProfile, SummedProfile
 from lasy.profiles.transverse import (
+    FlattenedGaussianTransverseProfile,
     GaussianTransverseProfile,
     HermiteGaussianTransverseProfile,
     JincTransverseProfile,
@@ -25,6 +34,8 @@
     TransverseProfileFromData,
 )
 from lasy.utils.exp_data_utils import find_center_of_mass
+from lasy.utils.grid import Grid
+from lasy.utils.laser_utils import compute_laser_energy, get_w0
 
 
 class MockProfile(Profile):
@@ -533,3 +544,65 @@ def test_scale_trans_error_if_not_scalar():
         trans_profile_1 * trans_profile_1
     with pytest.raises(AssertionError):
         trans_profile_1 * [1.0, 2.0]
+
+
+def test_flattened_gaussian_profile():
+    w = 20e-3
+    N = 25
+    wl = 800e-9
+    tau = 30e-15
+    pol = (1, 0)
+    energy = 1.0
+    focal_length = 1.0
+
+    w0 = focal_length * wl / np.pi / w
+
+    nf = FlattenedGaussianTransverseProfile(
+        field_type="nearfield", w=w, N=N, wavelength=wl
+    )
+    ff = FlattenedGaussianTransverseProfile(
+        field_type="farfield", w=w0, N=N, wavelength=wl
+    )
+
+    long = GaussianLongitudinalProfile(wl, tau, 0)
+
+    nf_prof = CombinedLongitudinalTransverseProfile(wl, pol, energy, long, nf)
+    ff_prof = CombinedLongitudinalTransverseProfile(wl, pol, energy, long, ff)
+
+    dim = "rt"
+    lo = (0, -100e-15)
+    hi_ff = (500e-6, 100e-15)
+    hi_nf = (40e-3, 100e-15)
+    npoints = (5000, 200)
+
+    las_nf = Laser(dim, lo, hi_nf, npoints, nf_prof)
+    las_ff = Laser(dim, lo, hi_ff, npoints, ff_prof)
+
+    las_nf_cp = copy.deepcopy(las_nf)
+
+    OAP = ParabolicMirror(f=focal_length)
+    las_nf_cp.apply_optics(OAP)
+    las_nf_cp.propagate(
+        focal_length, grid=Grid(dim, lo, hi_ff, npoints, n_azimuthal_modes=1)
+    )
+
+    radlineout_nf_cp = (
+        np.abs(las_nf_cp.grid.get_temporal_field()[0, :, int(npoints[1] / 2)]) ** 2
+    )
+    radlineout_ff = (
+        np.abs(las_ff.grid.get_temporal_field()[0, :, int(npoints[1] / 2)]) ** 2
+    )
+
+    err = np.sum(
+        np.abs(np.abs(radlineout_nf_cp) ** 2 - np.abs(radlineout_ff) ** 2)
+    ) / np.sum(np.abs(radlineout_ff) ** 2)
+
+    assert err < 1e-2
+
+    energy_ff = compute_laser_energy(dim, las_ff.grid)
+    energy_nf_cp = compute_laser_energy(dim, las_nf_cp.grid)
+    assert np.abs(energy_ff - energy_nf_cp) / energy_ff < 1e-4
+
+    w0_ff = get_w0(las_ff.grid, dim)
+    w0_nf_cp = get_w0(las_nf_cp.grid, dim)
+    assert np.abs(w0_nf_cp - w0_ff) / w0_ff < 1e-2


Reviews:
user: login: github-advanced-security[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-02-20T23:14:32Z
user: login: github-advanced-security[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-02-26T12:41:05Z
user: login: MaxThevenet
body: Thanks for this PR! See comments below.
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T21:03:04Z
user: login: rob-shalloo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-26T12:21:33Z
user: login: rob-shalloo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-26T12:39:12Z
user: login: rob-shalloo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-26T12:40:07Z
user: login: rob-shalloo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-26T12:43:05Z
user: login: MaxThevenet
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-31T12:02:43Z
user: login: MaxThevenet
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-31T12:04:26Z

Review comments:
diff_hunk: @@ -533,3 +541,61 @@
         trans_profile_1 * trans_profile_1
     with pytest.raises(AssertionError):
         trans_profile_1 * [1.0, 2.0]
+
+
+def test_flattened_gaussian_profile():
+    w = 20e-3
+    N = 25
+    wl = 800e-9
+    tau = 30e-15
+    pol = (1, 0)
+    energy = 1.0
+    focal_length = 1.0
+
+    w0 = focal_length * wl / np.pi / w
+
+    nf = FlattenedGaussianTransverseProfile(
+        field_type="nearfield", w=w, N=N, wavelength=wl
+    )
+    ff = FlattenedGaussianTransverseProfile(
+        field_type="farfield", w=w0, N=N, wavelength=wl
+    )
+
+    long = GaussianLongitudinalProfile(wl, tau, 0)
+
+    nf_prof = CombinedLongitudinalTransverseProfile(wl, pol, energy, long, nf)
+    ff_prof = CombinedLongitudinalTransverseProfile(wl, pol, energy, long, ff)
+
+    dim = "rt"
+    lo = (0, -100e-15)
+    hi_ff = (1000e-6, 100e-15)
+    hi_nf = (40e-3, 100e-15)
+    npoints = (5000, 200)
+
+    las_nf = Laser(dim, lo, hi_nf, npoints, nf_prof)
+    las_ff = Laser(dim, lo, hi_ff, npoints, ff_prof)
+
+    las_nf_cp = copy.deepcopy(las_nf)
+
+    OAP = ParabolicMirror(f=focal_length)
+    las_nf_cp.apply_optics(OAP)
+    las_nf_cp.propagate(
+        focal_length, grid=Grid(dim, lo, hi_ff, npoints, n_azimuthal_modes=1)
+    )
+
+    radlineout_nf = (
path: tests/test_laser_profiles.py
user: login: github-advanced-security[bot]
body: ## Unused local variable

Variable radlineout_nf is not used.

[Show more details](https://github.com/LASY-org/lasy/security/code-scanning/237)
created_at: 2025-02-20T23:14:32Z
author_association: NONE
diff_hunk: @@ -533,3 +541,61 @@
         trans_profile_1 * trans_profile_1
     with pytest.raises(AssertionError):
         trans_profile_1 * [1.0, 2.0]
+
+
+def test_flattened_gaussian_profile():
+    w = 20e-3
+    N = 25
+    wl = 800e-9
+    tau = 30e-15
+    pol = (1, 0)
+    energy = 1.0
+    focal_length = 1.0
+
+    w0 = focal_length * wl / np.pi / w
+
+    nf = FlattenedGaussianTransverseProfile(
+        field_type="nearfield", w=w, N=N, wavelength=wl
+    )
+    ff = FlattenedGaussianTransverseProfile(
+        field_type="farfield", w=w0, N=N, wavelength=wl
+    )
+
+    long = GaussianLongitudinalProfile(wl, tau, 0)
+
+    nf_prof = CombinedLongitudinalTransverseProfile(wl, pol, energy, long, nf)
+    ff_prof = CombinedLongitudinalTransverseProfile(wl, pol, energy, long, ff)
+
+    dim = "rt"
+    lo = (0, -100e-15)
+    hi_ff = (1000e-6, 100e-15)
+    hi_nf = (40e-3, 100e-15)
+    npoints = (5000, 200)
+
+    las_nf = Laser(dim, lo, hi_nf, npoints, nf_prof)
+    las_ff = Laser(dim, lo, hi_ff, npoints, ff_prof)
+
+    las_nf_cp = copy.deepcopy(las_nf)
+
+    OAP = ParabolicMirror(f=focal_length)
+    las_nf_cp.apply_optics(OAP)
+    las_nf_cp.propagate(
+        focal_length, grid=Grid(dim, lo, hi_ff, npoints, n_azimuthal_modes=1)
+    )
+
+    radlineout_nf = (
+        np.abs(las_nf_cp.grid.get_temporal_field()[0, :, int(npoints[1] / 2)]) ** 2
+    )
+    radlineout_ff = (
path: tests/test_laser_profiles.py
user: login: github-advanced-security[bot]
body: ## Unused local variable

Variable radlineout_ff is not used.

[Show more details](https://github.com/LASY-org/lasy/security/code-scanning/238)
created_at: 2025-02-20T23:14:32Z
author_association: NONE
diff_hunk: @@ -62,12 +62,18 @@
         rr = np.sqrt(x**2 + y**2)
         phase = np.zeros_like(rr)
 
-        _, _, nw = x.shape
+        nw = x.shape[-1]
path: lasy/optical_elements/zernike_aberrations.py
user: login: github-advanced-security[bot]
body: ## Unused local variable

Variable nw is not used.

[Show more details](https://github.com/LASY-org/lasy/security/code-scanning/239)
created_at: 2025-02-26T12:41:05Z
author_association: NONE
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
 
-        \mathrm{with} \qquad w(z) = \frac{\lambda_0}{\pi w0}|z-z_{foc}|
+    with
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_(z)^2}\right)`.
+    .. math::
 
-    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto \Theta(w(z)-r)`.
+        w(z) = \frac{\lambda_0}{\pi w_0}|z-z_{foc}|
+
+    - Note that a beam defined using the near field definition would be
+      equivalent to a beam defined with the corresponding parameters in
+      the far field, but without the parabolic phase arising from being
+      defined far from the focus.
+
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w(z)^2}\right)`.
+    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto\Theta(w(z)-r)`.
 
     Parameters
     ----------
-    w0 : float (in meter)
-        The waist of the laser pulse,
-        i.e. :math:`w_{0}` in the above formula.
-    N: int
+    field_type : string
+        Options: 'nearfield', when the beam is defined far from focus and
+        has been collimated, or 'farfield', when the beam is in the vicinity
+        of or has been directly propagated from the focus. In this case there
+        can be a large defocus in the spatial phase.
+
+    w : float (in meter)
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: MaxThevenet
body: Is there a reason to change the name `w0`?
created_at: 2025-03-19T20:49:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
 
-        \mathrm{with} \qquad w(z) = \frac{\lambda_0}{\pi w0}|z-z_{foc}|
+    with
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_(z)^2}\right)`.
+    .. math::
 
-    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto \Theta(w(z)-r)`.
+        w(z) = \frac{\lambda_0}{\pi w_0}|z-z_{foc}|
+
+    - Note that a beam defined using the near field definition would be
+      equivalent to a beam defined with the corresponding parameters in
+      the far field, but without the parabolic phase arising from being
+      defined far from the focus.
+
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w(z)^2}\right)`.
+    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto\Theta(w(z)-r)`.
 
     Parameters
     ----------
-    w0 : float (in meter)
-        The waist of the laser pulse,
-        i.e. :math:`w_{0}` in the above formula.
-    N: int
+    field_type : string
+        Options: 'nearfield', when the beam is defined far from focus and
+        has been collimated, or 'farfield', when the beam is in the vicinity
+        of or has been directly propagated from the focus. In this case there
+        can be a large defocus in the spatial phase.
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: MaxThevenet
body: I find this slightly misleading, just tried to help clarify, let me know what you think.
```suggestion
        Options: 'nearfield', when the beam is defined far from focus (e.g., right before the focusing optics), or 'farfield', when the beam is in the vicinity of the focus.
```
created_at: 2025-03-19T20:50:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
 
-        \mathrm{with} \qquad w(z) = \frac{\lambda_0}{\pi w0}|z-z_{foc}|
+    with
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_(z)^2}\right)`.
+    .. math::
 
-    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto \Theta(w(z)-r)`.
+        w(z) = \frac{\lambda_0}{\pi w_0}|z-z_{foc}|
+
+    - Note that a beam defined using the near field definition would be
+      equivalent to a beam defined with the corresponding parameters in
+      the far field, but without the parabolic phase arising from being
+      defined far from the focus.
+
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w(z)^2}\right)`.
+    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto\Theta(w(z)-r)`.
 
     Parameters
     ----------
-    w0 : float (in meter)
-        The waist of the laser pulse,
-        i.e. :math:`w_{0}` in the above formula.
-    N: int
+    field_type : string
+        Options: 'nearfield', when the beam is defined far from focus and
+        has been collimated, or 'farfield', when the beam is in the vicinity
+        of or has been directly propagated from the focus. In this case there
+        can be a large defocus in the spatial phase.
+
+    w : float (in meter)
+        The waist of the laser pulse. If ``field_type == 'farfield'`` then this
+        variable corresponds to :math:`w_{0}` in the above far field formula.
+        If ``field_type == 'nearfield'`` then this variable corresponds to
+        :math:`w(z)` in the above near field formula.
+
+    N : int
         Determines the "flatness" of the transverse profile, far from
         focus (see the above formula).
         Default: ``N=6`` ; somewhat close to an 8th order supergaussian.
+
     wavelength : float (in meter)
         The main laser wavelength :math:`\lambda_0` of the laser.
+
     z_foc : float (in meter), optional
-        Position of the focal plane. (The laser pulse is initialized at
-        ``z=0``.)
+        Only required if defining the pulse in the far field. Gives the position
+        of the focal plane. (The laser pulse is initialized at ``z=0``.)
 
     Warnings
     --------
-    In order to initialize the pulse out of focus, you can either:
 
-    - Use a non-zero ``z_foc``
-    - Use ``z_foc=0`` (i.e. initialize the pulse at focus) and then call
-      ``laser.propagate(-z_foc)``
+    In order to initialize the pulse in the far field but out of focus, you
+    must select ``field_type == 'farfield'`` and then you can either:
+
+    - Use a non-zero ``z_foc``.
+    - Use ``z_foc=0`` (i.e., initialize the pulse at focus) and then call
+      ``laser.propagate(-z_foc)``.
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: MaxThevenet
body: This profile is independent of the propagator, I think this whole warning should be dropped. It says something true, but not required here. I understand this was not introduced in this PR.
created_at: 2025-03-19T20:57:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: MaxThevenet
body: I find this expression with `w(z)` confusing, as we're talking about a collimated beam. I would call it `R` or `W` or something, and drop the (z) as well as the definition of `w(z)` below, as I do not think it is used when defined in the near field. This would require more changes in the inputs description below.
created_at: 2025-03-19T20:59:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
 
-        \mathrm{with} \qquad w(z) = \frac{\lambda_0}{\pi w0}|z-z_{foc}|
+    with
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_(z)^2}\right)`.
+    .. math::
 
-    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto \Theta(w(z)-r)`.
+        w(z) = \frac{\lambda_0}{\pi w_0}|z-z_{foc}|
+
+    - Note that a beam defined using the near field definition would be
+      equivalent to a beam defined with the corresponding parameters in
+      the far field, but without the parabolic phase arising from being
+      defined far from the focus.
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: MaxThevenet
body: Good to have this note here indeed!
created_at: 2025-03-19T21:00:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
 
-        \mathrm{with} \qquad w(z) = \frac{\lambda_0}{\pi w0}|z-z_{foc}|
+    with
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_(z)^2}\right)`.
+    .. math::
 
-    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto \Theta(w(z)-r)`.
+        w(z) = \frac{\lambda_0}{\pi w_0}|z-z_{foc}|
+
+    - Note that a beam defined using the near field definition would be
+      equivalent to a beam defined with the corresponding parameters in
+      the far field, but without the parabolic phase arising from being
+      defined far from the focus.
+
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w(z)^2}\right)`.
+    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto\Theta(w(z)-r)`.
 
     Parameters
     ----------
-    w0 : float (in meter)
-        The waist of the laser pulse,
-        i.e. :math:`w_{0}` in the above formula.
-    N: int
+    field_type : string
+        Options: 'nearfield', when the beam is defined far from focus and
+        has been collimated, or 'farfield', when the beam is in the vicinity
+        of or has been directly propagated from the focus. In this case there
+        can be a large defocus in the spatial phase.
+
+    w : float (in meter)
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: rob-shalloo
body: yes, I think having $w_0$ and $w(z)$ in the above formular ensures clarity. It then makes sense to carry this into the definitions below. 
`w0` is used when we're discussing far field and `w` when we're discussing near field
created_at: 2025-03-26T12:21:33Z
author_association: MEMBER
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
 
-        \mathrm{with} \qquad w(z) = \frac{\lambda_0}{\pi w0}|z-z_{foc}|
+    with
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_(z)^2}\right)`.
+    .. math::
 
-    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto \Theta(w(z)-r)`.
+        w(z) = \frac{\lambda_0}{\pi w_0}|z-z_{foc}|
+
+    - Note that a beam defined using the near field definition would be
+      equivalent to a beam defined with the corresponding parameters in
+      the far field, but without the parabolic phase arising from being
+      defined far from the focus.
+
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w(z)^2}\right)`.
+    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto\Theta(w(z)-r)`.
 
     Parameters
     ----------
-    w0 : float (in meter)
-        The waist of the laser pulse,
-        i.e. :math:`w_{0}` in the above formula.
-    N: int
+    field_type : string
+        Options: 'nearfield', when the beam is defined far from focus and
+        has been collimated, or 'farfield', when the beam is in the vicinity
+        of or has been directly propagated from the focus. In this case there
+        can be a large defocus in the spatial phase.
+
+    w : float (in meter)
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: rob-shalloo
body: I have now removed the w(z) as per comments below, but I still believe `w` and `w0` then are correct
created_at: 2025-03-26T12:39:12Z
author_association: MEMBER
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: rob-shalloo
body: I agree, I have now modified these to remove the w(z) and to be more consistent with the use of z throughout the docstring
created_at: 2025-03-26T12:40:06Z
author_association: MEMBER
diff_hunk: @@ -9,92 +11,126 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
     Class for the analytic profile of a Flattened-Gaussian laser pulse.
 
     Define a complex transverse profile with a flattened Gaussian intensity
-    distribution **far from focus** that transform into a distribution
+    distribution **far from focus** that transforms into a distribution
     with rings **in the focal plane**. (See `Santarsiero et al., J.
     Modern Optics, 1997 <http://doi.org/10.1080/09500349708232927>`_)
 
     Increasing the parameter ``N`` increases the
     flatness of the transverse profile **far from focus**,
     and increases the number of rings **in the focal plane**.
 
-    The implementation of this class is directly copied from that in `FBPIC`
+    The implementation of this class is based on that from `FBPIC`
     <https://github.com/fbpic/fbpic/blob/dev/fbpic/lpa_utils/laser/transverse_laser_profiles.py>.
 
-    **In the focal plane** (:math:`z=z_f`), the profile translates to a
+    **In the focal plane** (:math:`z=z_f`), or in the far field, the profile translates to a
     laser with a transverse electric field:
 
     .. math::
 
         E(x,y,z=zf) \propto
-        \exp\left(-\frac{r^2}{(N+1)w0^2}\right)
-        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w0^2}\right)
+        \exp\left(-\frac{r^2}{(N+1)w_0^2}\right)
+        \sum_{n=0}^N c'_n L^0_n\left(\frac{2\,r^2}{(N+1)w_0^2}\right)
+
+
+    with Laguerre polynomials :math:`L^0_n` and
 
-        \mathrm{with} Laguerre polynomials :math:`L^0_n` and
-        \qquad c'_n = \sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
+    .. math::
+
+        \qquad c'_n=\sum_{m=n}^{N}\frac{1}{2^m}\binom{m}{n}
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w0^2}\right)`.
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_0^2}\right)`.
 
-    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto \frac{J_1(r/w0)}{r/w0}`.
+    - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression **far from focus** is
+    The equivalent expression for the collimated beam in the near field which produces this focus is
+    given by:
 
     .. math::
 
         E(x,y,z=\infty) \propto
         \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
         \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
 
-        \mathrm{with} \qquad w(z) = \frac{\lambda_0}{\pi w0}|z-z_{foc}|
+    with
 
-    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w_(z)^2}\right)`.
+    .. math::
 
-    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto \Theta(w(z)-r)`.
+        w(z) = \frac{\lambda_0}{\pi w_0}|z-z_{foc}|
+
+    - Note that a beam defined using the near field definition would be
+      equivalent to a beam defined with the corresponding parameters in
+      the far field, but without the parabolic phase arising from being
+      defined far from the focus.
+
+    - For :math:`N=0`, this is a Gaussian profile: :math:`E\propto\exp\left(-\frac{r^2}{w(z)^2}\right)`.
+    - For :math:`N\rightarrow\infty`, this is a flat profile: :math:`E\propto\Theta(w(z)-r)`.
 
     Parameters
     ----------
-    w0 : float (in meter)
-        The waist of the laser pulse,
-        i.e. :math:`w_{0}` in the above formula.
-    N: int
+    field_type : string
+        Options: 'nearfield', when the beam is defined far from focus and
+        has been collimated, or 'farfield', when the beam is in the vicinity
+        of or has been directly propagated from the focus. In this case there
+        can be a large defocus in the spatial phase.
+
+    w : float (in meter)
+        The waist of the laser pulse. If ``field_type == 'farfield'`` then this
+        variable corresponds to :math:`w_{0}` in the above far field formula.
+        If ``field_type == 'nearfield'`` then this variable corresponds to
+        :math:`w(z)` in the above near field formula.
+
+    N : int
         Determines the "flatness" of the transverse profile, far from
         focus (see the above formula).
         Default: ``N=6`` ; somewhat close to an 8th order supergaussian.
+
     wavelength : float (in meter)
         The main laser wavelength :math:`\lambda_0` of the laser.
+
     z_foc : float (in meter), optional
-        Position of the focal plane. (The laser pulse is initialized at
-        ``z=0``.)
+        Only required if defining the pulse in the far field. Gives the position
+        of the focal plane. (The laser pulse is initialized at ``z=0``.)
 
     Warnings
     --------
-    In order to initialize the pulse out of focus, you can either:
 
-    - Use a non-zero ``z_foc``
-    - Use ``z_foc=0`` (i.e. initialize the pulse at focus) and then call
-      ``laser.propagate(-z_foc)``
+    In order to initialize the pulse in the far field but out of focus, you
+    must select ``field_type == 'farfield'`` and then you can either:
+
+    - Use a non-zero ``z_foc``.
+    - Use ``z_foc=0`` (i.e., initialize the pulse at focus) and then call
+      ``laser.propagate(-z_foc)``.
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: rob-shalloo
body: Agreed, this has been removed
created_at: 2025-03-26T12:43:05Z
author_association: MEMBER
diff_hunk: @@ -42,42 +42,41 @@ class FlattenedGaussianTransverseProfile(TransverseProfile):
 
     - For :math:`N\rightarrow\infty`, this is a Jinc profile: :math:`E\propto\frac{J_1(r/w_0)}{r/w_0}`.
 
-    The equivalent expression for the collimated beam in the near field which produces this focus is
+    The equivalent expression for **the collimated beam** in the near field which produces this focus is
     given by:
 
     .. math::
 
-        E(x,y,z=\infty) \propto
-        \exp\left(-\frac{(N+1)r^2}{w(z)^2}\right)
-        \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w(z)^2}\right)^n
+        E(x,y) \propto
+        \exp\left(-\frac{(N+1)r^2}{w^2}\right)
+        \sum_{n=0}^N \frac{1}{n!}\left(\frac{(N+1)\,r^2}{w^2}\right)^n
 
-    with
+    with the relationship between the spot sizes of the beams in the far field and in the near field given by;
path: lasy/profiles/transverse/flattened_gaussian_profile.py
user: login: MaxThevenet
body: ```suggestion
    with the relationship between the spot sizes of the beams in the far field and in the near field given by:
```
created_at: 2025-03-31T12:02:14Z
author_association: CONTRIBUTOR

PR comments:
user: login: rob-shalloo
created_at: 2025-03-26T12:50:42Z
body: Requested changes implemented
author_association: MEMBER
user: login: rob-shalloo
created_at: 2025-03-26T13:17:51Z
body: Ready for further review / merge

author_association: MEMBER