def illumination_data(shape, wavelengths, pixelsize=1., beta=0., phi=0., intensity=1., n=1., focus=0., window=None, backdir=False, jones=None, diffraction=True, betamax=BETAMAX): """Constructs forward (or backward) propagating input illumination field data. Parameters ---------- shape : (int,int) Shape of the illumination wavelengths : array_like A list of wavelengths. pixelsize : float, optional Size of the pixel in nm. beta : float or array_like of floats, optional Beta parameter(s) of the illumination. (Default 0. - normal incidence) phi : float or array_like of floats, optional Azimuthal angle(s) of the illumination. n : float, optional Refractive index of the media that this illumination field is assumed to be propagating in (default 1.) focus : float, optional Focal plane of the field. By default it is set at z=0. window : array or None, optional If None, no window function is applied. This window function is multiplied with the constructed plane waves to define field diafragm of the input light. See :func:`.window.aperture`. backdir : bool, optional Whether field is bacward propagating, instead of being forward propagating (default) jones : jones vector or None, optional If specified it has to be a valid jones vector that defines polarization of the light. If not given (default), the resulting field will have two polarization components. See documentation for details and examples. diffraction : bool, optional Specifies whether field is diffraction limited or not. By default, the field is filtered so that it has only propagating waves. You can disable this by specifying diffraction = False. betamax : float, optional The betamax parameter of the propagating field. """ verbose_level = DTMMConfig.verbose if verbose_level > 0: print("Building illumination data.") wavelengths = np.asarray(wavelengths) wavenumbers = 2 * np.pi / wavelengths * pixelsize if wavenumbers.ndim not in (1, ): raise ValueError("Wavelengths should be 1D array") if jones is None: intensity = intensity / 2. waves = illumination_waves(shape, wavenumbers, beta=beta, phi=phi, window=window) #intensity = ((np.abs(waves)**2).sum((-2,-1)))* np.asarray(intensity)[...,None]#sum over pixels #intensity = intensity * intensity mode = -1 if backdir else +1 _beta = np.asarray(beta, FDTYPE) _phi = np.asarray(phi, FDTYPE) _intensity = np.asarray(intensity, FDTYPE) nrays = len(_beta) if _beta.ndim > 0 else 1 beta = _beta[..., None, None, None] phi = _phi[..., None, None, None] intensity = _intensity[..., None, None, None, None] epsa = np.asarray((0., 0., 0.), FDTYPE) alpha, fmat = alphaf(beta, phi, refind2eps([n] * 3), epsa) field = waves2field2(waves, fmat, jones=jones, phi=phi, mode=mode) intensity1 = field2intensity(field) norm = np.ones_like(intensity1) norm[:, ...] = (intensity / nrays)**0.5 if diffraction == True: diffracted_field(field, wavenumbers, d=-focus, n=n, mode=mode, betamax=betamax, out=field) intensity2 = field2intensity(field) ratio = (intensity1.sum((-2, -1)) / intensity2.sum((-2, -1)))**0.5 norm[...] = norm * ratio[..., None, None] np.multiply(norm[..., None, :, :], field, field) return (field, wavelengths, pixelsize)
def waves2field(waves, k0, beta=0., phi=0., n=1., focus=0., jones=None, intensity=None, mode="t", diffraction=True, betamax=BETAMAX): """Converts scalar waves to vector field data.""" beta = np.asarray(beta) phi = np.asarray(phi) k0 = np.asarray(k0) nrays = 1 if jones is None: nrays = 2 if beta.ndim == 1: nrays = len(beta) * nrays waves = waves / (nrays**0.5) if jones is None: fieldv = np.zeros(beta.shape + (2, ) + k0.shape + (4, ) + waves.shape[-2:], dtype=CDTYPE) else: c, s = jones fieldv = np.zeros(beta.shape + k0.shape + (4, ) + waves.shape[-2:], dtype=CDTYPE) if beta.ndim == 1: for i, data in enumerate(fieldv): if jones is None: data[0, ..., 0, :, :] = waves[i] data[0, ..., 1, :, :] = waves[i] data[1, ..., 2, :, :] = waves[i] data[1, ..., 3, :, :] = -waves[i] else: data[..., 0, :, :] = waves[i] * c data[..., 1, :, :] = waves[i] * c data[..., 2, :, :] = waves[i] * s data[..., 3, :, :] = -waves[i] * s else: if jones is None: fieldv[0, ..., 0, :, :] = waves fieldv[0, ..., 1, :, :] = waves fieldv[1, ..., 2, :, :] = waves fieldv[1, ..., 3, :, :] = -waves else: fieldv[..., 0, :, :] = waves * c fieldv[..., 1, :, :] = waves * c fieldv[..., 2, :, :] = waves * s fieldv[..., 3, :, :] = -waves * s if diffraction == True: diffracted_field(fieldv, k0, d=-focus, n=n, mode=mode, betamax=betamax, out=fieldv) #normalize field to these intensities if intensity is not None: intensity = intensity / nrays if jones is None: #-2 element must be polarization. make it broadcastable to field intensity intensity = intensity[..., None, :] norm = (intensity / (field2intensity(fieldv).sum((-2, -1))))**0.5 np.multiply(fieldv, norm[..., None, None, None], fieldv) return fieldv