Exemplo n.º 1
0
def cake_gisaxs(img,
                q_par,
                q_per,
                bins=None,
                q_range=(0, 10),
                azimuth_range=(-90, 0)):

    if bins is None: bins = tuple(reversed(img.shape))
    if q_range is None: q_range = (0, q_par[-1])
    if azimuth_range is None: azimuth_range = (-180, 180)

    azimuth_range = np.deg2rad(azimuth_range)

    #recalculate the q-range of the input array
    q_h = np.linspace(q_par[0], q_par[-1], bins[0])
    q_v = np.linspace(q_per[0], q_per[-1], bins[1])[::-1]

    q_h_te, q_v_te = np.meshgrid(q_h, q_v)
    tth_array = np.sqrt(q_h_te**2 + q_v_te**2)
    chi_array = -np.arctan2(q_h_te, q_v_te)

    #Mask the remeshed array
    img_mask = np.ma.masked_array(img, mask=img == 0)

    img_mask = np.ma.masked_where(tth_array < q_range[0], img_mask)
    img_mask = np.ma.masked_where(tth_array > q_range[1], img_mask)

    img_mask = np.ma.masked_where(chi_array < np.min(azimuth_range), img_mask)
    img_mask = np.ma.masked_where(chi_array > np.max(azimuth_range), img_mask)

    cake, q, chi, _, _ = splitBBox.histoBBox2d(
        weights=img_mask,
        pos0=tth_array,
        delta_pos0=np.ones_like(img_mask) * (q_par[1] - q_par[0]) / bins[1],
        pos1=chi_array,
        delta_pos1=np.ones_like(img_mask) * (q_per[1] - q_per[0]) / bins[1],
        bins=bins,
        pos0Range=np.array([np.min(q_range), np.max(q_range)]),
        pos1Range=np.array([np.min(azimuth_range),
                            np.max(azimuth_range)]),
        dummy=None,
        delta_dummy=None,
        mask=img_mask.mask)

    return cake, q, np.rad2deg(chi)[::-1]
Exemplo n.º 2
0
def cake_gisaxs(img,
                q_par,
                q_per,
                bins=None,
                radial_range=None,
                azimuth_range=None):
    """
    Unwrap the stitched image from q-space to 2theta-Chi space (Radial-Azimuthal angle)

    Parameters:
    -----------
    :param img: List of 2D images
    :type img: List of ndarray
    :param q_par: minimum and maximum q_par (in A-1) of the input image
    :type q_par: Tuple
    :param q_per: minimum and maximum of q_par in A-1
    :type q_per: Tuple
    :param bins: number of point in both x and y direction of the final cake
    :type bins: Tuple
    :param radial_range: minimum and maximum of the radial range in degree
    :type radial_range: Tuple
    :param azimuth_range: minimum and maximum of the 2th range in degree
    :type azimuth_range: Tuple
    """
    if bins is None:
        bins = tuple(reversed(img.shape))
    if radial_range is None:
        radial_range = (0, q_par[-1])
    if azimuth_range is None:
        azimuth_range = (-180, 180)

    azimuth_range = np.deg2rad(azimuth_range)

    # recalculate the q-range of the input array
    q_h = np.linspace(q_par[0], q_par[-1], bins[0])
    q_v = np.linspace(q_per[0], q_per[-1], bins[1])[::-1]

    q_h_te, q_v_te = np.meshgrid(q_h, q_v)
    tth_array = np.sqrt(q_h_te**2 + q_v_te**2)
    chi_array = -np.arctan2(q_h_te, q_v_te)

    # Mask the remeshed array
    img_mask = np.ma.masked_array(img, mask=img == 0)

    img_mask = np.ma.masked_where(tth_array < radial_range[0], img_mask)
    img_mask = np.ma.masked_where(tth_array > radial_range[1], img_mask)

    img_mask = np.ma.masked_where(chi_array < np.min(azimuth_range), img_mask)
    img_mask = np.ma.masked_where(chi_array > np.max(azimuth_range), img_mask)

    cake, q, chi, _, _ = splitBBox.histoBBox2d(
        weights=img_mask,
        pos0=tth_array,
        delta_pos0=np.ones_like(img_mask) * (q_par[1] - q_par[0]) / bins[1],
        pos1=chi_array,
        delta_pos1=np.ones_like(img_mask) * (q_per[1] - q_per[0]) / bins[1],
        bins=bins,
        pos0Range=np.array([np.min(radial_range),
                            np.max(radial_range)]),
        pos1Range=np.array([np.min(azimuth_range),
                            np.max(azimuth_range)]),
        dummy=None,
        delta_dummy=None,
        mask=img_mask.mask)

    return cake, q, np.rad2deg(chi)[::-1]
Exemplo n.º 3
0
def remesh_transmission(image,
                        ai,
                        bins=None,
                        q_h_range=None,
                        q_v_range=None,
                        out_range=None,
                        coord_sys='qp_qz',
                        mask=None):
    """
    Redraw the Transmission image in (qp, qz) coordinates using pyFAI splitBBox.histoBBox2d method

    Parameters:
    -----------
    :param image: 2D raw Detector image in pixel
    :type image: ndarray
    :param ai: PyFAI AzimuthalIntegrator
    :type ai: PyFAI AzimuthalIntegrator
    :param bins: number of point for the binning
    :type bins: int
    :param q_h_range: Starting and ending point for the q_horizontal range
    :type q_h_range: Tuple(float, float), optional
    :param q_v_range: Starting and ending point for the q_vertical range
    :type q_v_range: Tuple(float, float), optional
    :param out_range: q range of the output image
    :type out_range: [[left, right],[lower, upper]], optional
    :param coord_sys: Output ooordinate system
    :type coord_sys: str, 'qp_qz', 'qy_qz' or 'theta_alpha'
    :param mask: Mask of the 2D raw image
    :type mask: numpy 2D array of boolean
    """

    assert image.shape == ai.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 = ai.calc_pos_zyx(d1=px_y, d2=px_x)

    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, ai.wavelength) * 1e-10
    q_v = q_y
    q_h = q_x

    resc_q = False
    if -q_v.min() > np.pi:
        resc_q = True
        q_v *= 0.1
        q_h *= 0.1

    if bins is None: bins = tuple(reversed(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_y, q_z, _, _ = 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=1,
    )

    return I, q_y, q_z, resc_q
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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
    """
    q = q_from_geometry(image.shape, geometry, reflection, alphai)

    q_h = q[:, :, 0]
    q_v = q[:, :, 1]

    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())

    # Note: dividing q values by 10 so that the q map is within the bounds allowed by histoBBox2d
    I, q_h, q_v, _, _ = splitBBox.histoBBox2d(
        weights=image,
        pos0=q_h / 10,
        delta_pos0=np.ones_like(image) * (q_h_range[1] - q_h_range[0]) /
        bins[0] / 10,
        pos1=q_v / 10,
        delta_pos1=np.ones_like(image) * (q_v_range[1] - q_v_range[0]) /
        bins[1] / 10,
        bins=bins,
        pos0Range=np.asarray(q_h_range) / 10,
        pos1Range=np.asarray(q_v_range) / 10,
        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 * 10, q_v * 10