def q_from_geometry( shape: Tuple[int, int], geometry: Geometry, reflection: bool, alphai: float, ): """ Calculate the q vector for each pixel in an image Parameters: ----------- image: ndarray, detector image geometry: pyFAI Geometry PONI, Pixel Size, Sample Det dist etc alphai: scalar, deg angle of incedence out_range: list, optional [[left, right],[lower, upper]] for the output image res: list, optional resolution of the output image coord_sys: str 'qp_qz', 'qy_qz' or 'theta_alpha' Returns ------- qimage: ndarray remeshed/warped image xcrd: ndarray x-coords of warped image ycrd: ndarray y-coords of warped image """ assert shape == geometry.detector.shape[-2:] x = np.arange(shape[1]) y = np.arange(shape[0]) px_x, px_y = np.meshgrid(x, y) r_z, r_y, r_x = geometry.calc_pos_zyx(d1=px_y, d2=px_x) if reflection: alphas = alpha(r_x, r_y, r_z) - alphai phis = phi(r_x, r_y, r_z) k_i = k_f = 2 * np.pi / geometry.wavelength * 1e-10 q_x = k_f * np.cos(alphas) * np.cos(phis) - k_i * np.cos(alphai) q_y = k_f * np.cos(alphas) * np.sin(phis) q_z = (k_f * np.sin(alphas) + k_i * np.sin(alphai)) q_r = np.sqrt(q_x**2 + q_y**2) * np.sign(q_y) q_h = q_r q_v = q_z else: alphas = alpha(r_x, r_y, r_z) phis = phi(r_x, r_y, r_z) q_x, q_y, q_z = q_from_angles(phis, alphas, geometry.wavelength) * 1e-10 q_v = q_y q_h = q_x return np.dstack((q_h, q_v))
def remesh(image: np.ndarray, geometry: Geometry, reflection: bool, alphai: float, bins: Tuple[int, int] = None, q_h_range: Tuple[float, float] = None, q_v_range: Tuple[float, float] = None, out_range=None, res=None, coord_sys='qp_qz'): """ Redraw the GI Image in (qp, qz) coordinates. Parameters: ----------- image: ndarray, detector image geometry: pyFAI Geometry PONI, Pixel Size, Sample Det dist etc alphai: scalar, deg angle of incedence out_range: list, optional [[left, right],[lower, upper]] for the output image res: list, optional resolution of the output image coord_sys: str 'qp_qz', 'qy_qz' or 'theta_alpha' Returns ------- qimage: ndarray remeshed/warped image xcrd: ndarray x-coords of warped image ycrd: ndarray y-coords of warped image """ geometry = geometry.__deepcopy__() geometry.setFit2D(geometry.getFit2D()["directDist"], geometry.getFit2D()["centerX"], len(image) - geometry.getFit2D()["centerY"]) assert image.shape == geometry.detector.shape x = np.arange(image.shape[1]) y = np.arange(image.shape[0]) px_x, px_y = np.meshgrid(x, y) r_z, r_y, r_x = geometry.calc_pos_zyx(d1=px_y, d2=px_x) if reflection: alphas = alpha(r_x, r_y, r_z) - alphai phis = phi(r_x, r_y, r_z) k_i = k_f = 2 * np.pi / geometry.wavelength * 1e-10 q_x = k_f * np.cos(alphas) * np.cos(phis) - k_i * np.cos(alphai) q_y = k_f * np.cos(alphas) * np.sin(phis) q_z = -(k_f * np.sin(alphas) + k_i * np.sin(alphai)) q_r = np.sqrt(q_x ** 2 + q_y ** 2) * np.sign(q_y) q_h = q_r q_v = -q_z else: alphas = alpha(r_x, r_y, r_z) phis = phi(r_x, r_y, r_z) q_x, q_y, q_z = q_from_angles(phis, alphas, geometry.wavelength) * 1e-10 q_v = -q_y # -q_y q_h = q_x if bins is None: bins = tuple(image.shape) if q_h_range is None: q_h_range = (q_h.min(), q_h.max()) if q_v_range is None: q_v_range = (q_v.min(), q_v.max()) I, q_h, q_v, _, _ = splitBBox.histoBBox2d(weights=image, pos0=q_h, delta_pos0=np.ones_like(image) * (q_h_range[1] - q_h_range[0]) / bins[0], pos1=q_v, delta_pos1=np.ones_like(image) * (q_v_range[1] - q_v_range[0]) / bins[1], bins=bins, pos0Range=q_h_range, pos1Range=q_v_range, dummy=None, delta_dummy=None, allow_pos0_neg=True, # mask=mask, # dark=dark, # flat=flat, # solidangle=solidangle, # polarization=polarization, # normalization_factor=normalization_factor, # chiDiscAtPi=self.chiDiscAtPi, # empty=dummy if dummy is not None else self._empty ) q_h, q_v = np.meshgrid(q_h, q_v) return I, q_h, q_v