Source code for lasy.profiles.transverse.transverse_profile_from_data

import numpy as np
from scipy.interpolate import RegularGridInterpolator

from lasy.utils.exp_data_utils import find_center_of_mass

from .transverse_profile import TransverseProfile


[docs] class TransverseProfileFromData(TransverseProfile): """ Class for transverse laser profile. Created using data from an experimental measurement or from the output of another code. Uses user supplied data to define the transverse profile of the laser pulse. The data must be supplied as a 2D numpy array of intensity values (for example an imported camera image from an experimental measurement). In the case of experimental measurements, this data should already have some undergone some preprocessing such as background subtraction and noise removal. The beam will be imported and automatically centered unless otherwise specified. Parameters ---------- intensity_data : 2Darray of floats The 2D transverse intensity profile of the laser pulse. lo, hi : list of scalars (in meters) Lower and higher end of the physical domain of the data. One element per direction (in this case 2) center_data : bool, optional If true, the intensity data will be rolled to put the center of mass at the center of the image. It will also shift the x and y data axes such that (x,y) = (0,0) is also located at the center of the image. Default is True """ def __init__(self, intensity_data, lo, hi, center_data=True): super().__init__() intensity_data = intensity_data.astype("float64") n_y, n_x = np.shape(intensity_data) dx = (hi[0] - lo[0]) / n_x dy = (hi[1] - lo[1]) / n_y if center_data: x_range = np.abs(hi[0] - lo[0]) y_range = np.abs(hi[1] - lo[1]) x_data = np.linspace(-x_range / 2, x_range / 2, n_x) y_data = np.linspace(-y_range / 2, y_range / 2, n_y) n_x0, n_y0 = find_center_of_mass(intensity_data) intensity_data = np.roll( np.roll(intensity_data, -int(n_x0 - n_x / 2), axis=1), -int(n_y0 - n_y / 2), axis=0, ) else: x_data = np.linspace(lo[0], hi[0], n_x) y_data = np.linspace(lo[1], hi[1], n_y) # Normalise the profile such that its squared integeral == 1 intensity_data /= np.sum(intensity_data) * dx * dy # Note here we use the square root of intensity to get the 'field' self.field_interp = RegularGridInterpolator( (y_data, x_data), np.sqrt(intensity_data), bounds_error=False, fill_value=0.0, ) def _evaluate(self, x, y): """ Return the transverse envelope. Parameters ---------- x, y : ndarrays of floats Define points on which to evaluate the envelope These arrays need to all have the same shape. Returns ------- envelope : ndarray of floats Contains the value of the envelope at the specified points This array has the same shape as the arrays x, y """ envelope = self.field_interp((y, x)) return envelope