def test_cellcentroids(in_file):
    count = 0
    with open(in_file, 'rb') as f:
        while True:
            try:
                args = pickle.load(f)
            except EOFError:
                break

            with nvtx.profile_range('original'):
                res_orig = cell_centroids_original(*args)
            with nvtx.profile_range('current in hexrd'):
                res_current = cellCentroids(*args)
            with nvtx.profile_range('numba1'):
                res_numba1 = cell_centroids_opt1(*args)
            with nvtx.profile_range('numba1_bis'):
                res_numba1 = cell_centroids_opt1(*args)
            with nvtx.profile_range('numba'):
                res_numba = cell_centroids_numba(*args)
            with nvtx.profile_range('numba_bis'):
                res_numba = cell_centroids_numba(*args)

            assert np.allclose(res_current, res_orig)
            assert np.allclose(res_current, res_numba1)
            assert np.allclose(res_current, res_numba)
            count += 1
Esempio n. 2
0
def test_cellcentroids(in_file):
    count = 0
    with open(in_file, 'rb') as f:
        while True:
            try:
                args = pickle.load(f)
            except EOFError:
                break

            with nvtx.profile_range('original'):
                res_orig = cell_centroids_original(*args)
            with nvtx.profile_range('current in hexrd'):
                res_current = cellCentroids(*args)
            with nvtx.profile_range('numba1'):
                res_numba1 = cell_centroids_opt1(*args)
            with nvtx.profile_range('numba1_bis'):
                res_numba1 = cell_centroids_opt1(*args)
            with nvtx.profile_range('numba'):
                res_numba = cell_centroids_numba(*args)
            with nvtx.profile_range('numba_bis'):
                res_numba = cell_centroids_numba(*args)

            assert np.allclose(res_current, res_orig)
            assert np.allclose(res_current, res_numba1)
            assert np.allclose(res_current, res_numba)
            count += 1
Esempio n. 3
0
def make_reflection_patches(instr_cfg,
                            tth_eta,
                            ang_pixel_size,
                            omega=None,
                            tth_tol=0.2,
                            eta_tol=1.0,
                            rMat_c=np.eye(3),
                            tVec_c=np.c_[0., 0., 0.].T,
                            distortion=distortion,
                            npdiv=1,
                            quiet=False,
                            compute_areas_func=compute_areas):
    """
    prototype function for making angular patches on a detector

    panel_dims are [(xmin, ymin), (xmax, ymax)] in mm

    pixel_pitch is [row_size, column_size] in mm

    DISTORTION HANDING IS STILL A KLUDGE

    patches are:

                 delta tth
   d  ------------- ... -------------
   e  | x | x | x | ... | x | x | x |
   l  ------------- ... -------------
   t                 .
   a                 .
                     .
   e  ------------- ... -------------
   t  | x | x | x | ... | x | x | x |
   a  ------------- ... -------------

    """
    npts = len(tth_eta)

    # detector frame
    rMat_d = xfcapi.makeDetectorRotMat(
        instr_cfg['detector']['transform']['tilt_angles'])
    tVec_d = np.r_[instr_cfg['detector']['transform']['t_vec_d']]
    pixel_size = instr_cfg['detector']['pixels']['size']

    frame_nrows = instr_cfg['detector']['pixels']['rows']
    frame_ncols = instr_cfg['detector']['pixels']['columns']

    panel_dims = (
        -0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]],
        0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]])
    row_edges = np.arange(frame_nrows +
                          1)[::-1] * pixel_size[1] + panel_dims[0][1]
    col_edges = np.arange(frame_ncols + 1) * pixel_size[0] + panel_dims[0][0]

    # sample frame
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.r_[instr_cfg['oscillation_stage']['t_vec_s']]

    # data to loop
    # ...WOULD IT BE CHEAPER TO CARRY ZEROS OR USE CONDITIONAL?
    if omega is None:
        full_angs = np.hstack([tth_eta, np.zeros((npts, 1))])
    else:
        full_angs = np.hstack([tth_eta, omega.reshape(npts, 1)])
    patches = []
    for angs, pix in zip(full_angs, ang_pixel_size):
        # need to get angular pixel size
        rMat_s = xfcapi.makeOscillRotMat([chi, angs[2]])

        ndiv_tth = npdiv * np.ceil(tth_tol / np.degrees(pix[0]))
        ndiv_eta = npdiv * np.ceil(eta_tol / np.degrees(pix[1]))

        tth_del = np.arange(
            0, ndiv_tth + 1) * tth_tol / float(ndiv_tth) - 0.5 * tth_tol
        eta_del = np.arange(
            0, ndiv_eta + 1) * eta_tol / float(ndiv_eta) - 0.5 * eta_tol

        # store dimensions for convenience
        #   * etas and tths are bin vertices, ome is already centers
        sdims = [len(eta_del) - 1, len(tth_del) - 1]

        # meshgrid args are (cols, rows), a.k.a (fast, slow)
        m_tth, m_eta = np.meshgrid(tth_del, eta_del)
        npts_patch = m_tth.size

        # calculate the patch XY coords from the (tth, eta) angles
        # * will CHEAT and ignore the small perturbation the different
        #   omega angle values causes and simply use the central value
        gVec_angs_vtx = np.tile(angs, (npts_patch, 1)) \
                        + np.radians(
                            np.vstack([m_tth.flatten(),
                                       m_eta.flatten(),
                                       np.zeros(npts_patch)
                                       ]).T
                                     )

        # will need this later
        rMat_s = xfcapi.makeOscillRotMat([chi, angs[2]])

        # FOR ANGULAR MESH
        conn = gutil.cellConnectivity(sdims[0], sdims[1], origin='ll')
        gVec_c = xf.anglesToGVec(gVec_angs_vtx,
                                 xf.bVec_ref,
                                 xf.eta_ref,
                                 rMat_s=rMat_s,
                                 rMat_c=rMat_c)

        xy_eval_vtx = xfcapi.gvecToDetectorXY(gVec_c.T, rMat_d, rMat_s, rMat_c,
                                              tVec_d, tVec_s, tVec_c)
        if distortion is not None and len(distortion) == 2:
            xy_eval_vtx = distortion[0](xy_eval_vtx,
                                        distortion[1],
                                        invert=True)
            pass

        areas = compute_areas_func(xy_eval_vtx, conn)

        # EVALUATION POINTS
        #   * for lack of a better option will use centroids
        tth_eta_cen = gutil.cellCentroids(np.atleast_2d(gVec_angs_vtx[:, :2]),
                                          conn)
        gVec_angs = np.hstack(
            [tth_eta_cen, np.tile(angs[2], (len(tth_eta_cen), 1))])
        gVec_c = xf.anglesToGVec(gVec_angs,
                                 xf.bVec_ref,
                                 xf.eta_ref,
                                 rMat_s=rMat_s,
                                 rMat_c=rMat_c)

        xy_eval = xfcapi.gvecToDetectorXY(gVec_c.T, rMat_d, rMat_s, rMat_c,
                                          tVec_d, tVec_s, tVec_c)
        if distortion is not None and len(distortion) == 2:
            xy_eval = distortion[0](xy_eval, distortion[1], invert=True)
            pass
        row_indices = gutil.cellIndices(row_edges, xy_eval[:, 1])
        col_indices = gutil.cellIndices(col_edges, xy_eval[:, 0])

        patches.append(
            ((gVec_angs_vtx[:, 0].reshape(m_tth.shape),
              gVec_angs_vtx[:, 1].reshape(m_tth.shape)),
             (xy_eval_vtx[:, 0].reshape(m_tth.shape),
              xy_eval_vtx[:, 1].reshape(m_tth.shape)), conn,
             areas.reshape(sdims[0],
                           sdims[1]), (row_indices.reshape(sdims[0], sdims[1]),
                                       col_indices.reshape(sdims[0],
                                                           sdims[1]))))
        pass
    return patches
Esempio n. 4
0
def make_reflection_patches(instr_cfg,
                            tth_eta,
                            ang_pixel_size,
                            omega=None,
                            tth_tol=0.2,
                            eta_tol=1.0,
                            rMat_c=np.eye(3),
                            tVec_c=np.zeros((3, 1)),
                            distortion=None,
                            npdiv=1,
                            quiet=False,
                            compute_areas_func=gutil.compute_areas,
                            beamVec=None):
    """
    prototype function for making angular patches on a detector

    panel_dims are [(xmin, ymin), (xmax, ymax)] in mm

    pixel_pitch is [row_size, column_size] in mm

    FIXME: DISTORTION HANDING IS STILL A KLUDGE!!!

    patches are:

                 delta tth
   d  ------------- ... -------------
   e  | x | x | x | ... | x | x | x |
   l  ------------- ... -------------
   t                 .
   a                 .
                     .
   e  ------------- ... -------------
   t  | x | x | x | ... | x | x | x |
   a  ------------- ... -------------

   outputs are:
       (tth_vtx, eta_vtx),
       (x_vtx, y_vtx),
       connectivity,
       subpixel_areas,
       (x_center, y_center),
       (i_row, j_col)
    """
    npts = len(tth_eta)

    # detector frame
    rMat_d = xfcapi.makeRotMatOfExpMap(
        np.r_[instr_cfg['detector']['transform']['tilt']])
    tVec_d = np.r_[instr_cfg['detector']['transform']['translation']]
    pixel_size = instr_cfg['detector']['pixels']['size']

    frame_nrows = instr_cfg['detector']['pixels']['rows']
    frame_ncols = instr_cfg['detector']['pixels']['columns']

    panel_dims = (
        -0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]],
        0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]])
    row_edges = np.arange(frame_nrows + 1)[::-1]*pixel_size[1] \
        + panel_dims[0][1]
    col_edges = np.arange(frame_ncols + 1)*pixel_size[0] \
        + panel_dims[0][0]

    # sample frame
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.r_[instr_cfg['oscillation_stage']['translation']]

    # beam vector
    if beamVec is None:
        beamVec = xfcapi.bVec_ref

    # data to loop
    # ...WOULD IT BE CHEAPER TO CARRY ZEROS OR USE CONDITIONAL?
    if omega is None:
        full_angs = np.hstack([tth_eta, np.zeros((npts, 1))])
    else:
        full_angs = np.hstack([tth_eta, omega.reshape(npts, 1)])

    patches = []
    for angs, pix in zip(full_angs, ang_pixel_size):
        ndiv_tth = npdiv * np.ceil(tth_tol / np.degrees(pix[0]))
        ndiv_eta = npdiv * np.ceil(eta_tol / np.degrees(pix[1]))

        tth_del = np.arange(0, ndiv_tth + 1)*tth_tol/float(ndiv_tth) \
            - 0.5*tth_tol
        eta_del = np.arange(0, ndiv_eta + 1)*eta_tol/float(ndiv_eta) \
            - 0.5*eta_tol

        # store dimensions for convenience
        #   * etas and tths are bin vertices, ome is already centers
        sdims = [len(eta_del) - 1, len(tth_del) - 1]

        # FOR ANGULAR MESH
        conn = gutil.cellConnectivity(sdims[0], sdims[1], origin='ll')

        # meshgrid args are (cols, rows), a.k.a (fast, slow)
        m_tth, m_eta = np.meshgrid(tth_del, eta_del)
        npts_patch = m_tth.size

        # calculate the patch XY coords from the (tth, eta) angles
        # * will CHEAT and ignore the small perturbation the different
        #   omega angle values causes and simply use the central value
        gVec_angs_vtx = np.tile(angs, (npts_patch, 1)) \
            + np.radians(
                np.vstack(
                    [m_tth.flatten(),
                     m_eta.flatten(),
                     np.zeros(npts_patch)]
                ).T
            )

        xy_eval_vtx, _ = _project_on_detector_plane(gVec_angs_vtx,
                                                    rMat_d,
                                                    rMat_c,
                                                    chi,
                                                    tVec_d,
                                                    tVec_c,
                                                    tVec_s,
                                                    distortion,
                                                    beamVec=beamVec)

        areas = compute_areas_func(xy_eval_vtx, conn)

        # EVALUATION POINTS
        #   * for lack of a better option will use centroids
        tth_eta_cen = gutil.cellCentroids(np.atleast_2d(gVec_angs_vtx[:, :2]),
                                          conn)

        gVec_angs = np.hstack(
            [tth_eta_cen, np.tile(angs[2], (len(tth_eta_cen), 1))])

        xy_eval, _ = _project_on_detector_plane(gVec_angs,
                                                rMat_d,
                                                rMat_c,
                                                chi,
                                                tVec_d,
                                                tVec_c,
                                                tVec_s,
                                                distortion,
                                                beamVec=beamVec)

        row_indices = gutil.cellIndices(row_edges, xy_eval[:, 1])
        col_indices = gutil.cellIndices(col_edges, xy_eval[:, 0])

        # append patch data to list
        patches.append(
            ((gVec_angs_vtx[:, 0].reshape(m_tth.shape),
              gVec_angs_vtx[:, 1].reshape(m_tth.shape)),
             (xy_eval_vtx[:, 0].reshape(m_tth.shape),
              xy_eval_vtx[:, 1].reshape(m_tth.shape)), conn,
             areas.reshape(sdims[0],
                           sdims[1]), (xy_eval[:,
                                               0].reshape(sdims[0], sdims[1]),
                                       xy_eval[:,
                                               1].reshape(sdims[0], sdims[1])),
             (row_indices.reshape(sdims[0], sdims[1]),
              col_indices.reshape(sdims[0], sdims[1]))))
        pass  # close loop over angles
    return patches
def make_reflection_patches(
    instr_cfg,
    tth_eta,
    ang_pixel_size,
    omega=None,
    tth_tol=0.2,
    eta_tol=1.0,
    rMat_c=np.eye(3),
    tVec_c=np.c_[0.0, 0.0, 0.0].T,
    distortion=distortion,
    npdiv=1,
    quiet=False,
    compute_areas_func=compute_areas,
):
    """
    prototype function for making angular patches on a detector

    panel_dims are [(xmin, ymin), (xmax, ymax)] in mm

    pixel_pitch is [row_size, column_size] in mm

    DISTORTION HANDING IS STILL A KLUDGE

    patches are:

                 delta tth
   d  ------------- ... -------------
   e  | x | x | x | ... | x | x | x |
   l  ------------- ... -------------
   t                 .
   a                 .
                     .
   e  ------------- ... -------------
   t  | x | x | x | ... | x | x | x |
   a  ------------- ... -------------

    """
    npts = len(tth_eta)

    # detector frame
    rMat_d = xfcapi.makeDetectorRotMat(instr_cfg["detector"]["transform"]["tilt_angles"])
    tVec_d = np.r_[instr_cfg["detector"]["transform"]["t_vec_d"]]
    pixel_size = instr_cfg["detector"]["pixels"]["size"]

    frame_nrows = instr_cfg["detector"]["pixels"]["rows"]
    frame_ncols = instr_cfg["detector"]["pixels"]["columns"]

    panel_dims = (
        -0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]],
        0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]],
    )
    row_edges = np.arange(frame_nrows + 1)[::-1] * pixel_size[1] + panel_dims[0][1]
    col_edges = np.arange(frame_ncols + 1) * pixel_size[0] + panel_dims[0][0]

    # sample frame
    chi = instr_cfg["oscillation_stage"]["chi"]
    tVec_s = np.r_[instr_cfg["oscillation_stage"]["t_vec_s"]]

    # data to loop
    # ...WOULD IT BE CHEAPER TO CARRY ZEROS OR USE CONDITIONAL?
    if omega is None:
        full_angs = np.hstack([tth_eta, np.zeros((npts, 1))])
    else:
        full_angs = np.hstack([tth_eta, omega.reshape(npts, 1)])
    patches = []
    for angs, pix in zip(full_angs, ang_pixel_size):
        # need to get angular pixel size
        rMat_s = xfcapi.makeOscillRotMat([chi, angs[2]])

        ndiv_tth = npdiv * np.ceil(tth_tol / np.degrees(pix[0]))
        ndiv_eta = npdiv * np.ceil(eta_tol / np.degrees(pix[1]))

        tth_del = np.arange(0, ndiv_tth + 1) * tth_tol / float(ndiv_tth) - 0.5 * tth_tol
        eta_del = np.arange(0, ndiv_eta + 1) * eta_tol / float(ndiv_eta) - 0.5 * eta_tol

        # store dimensions for convenience
        #   * etas and tths are bin vertices, ome is already centers
        sdims = [len(eta_del) - 1, len(tth_del) - 1]

        # meshgrid args are (cols, rows), a.k.a (fast, slow)
        m_tth, m_eta = np.meshgrid(tth_del, eta_del)
        npts_patch = m_tth.size

        # calculate the patch XY coords from the (tth, eta) angles
        # * will CHEAT and ignore the small perturbation the different
        #   omega angle values causes and simply use the central value
        gVec_angs_vtx = np.tile(angs, (npts_patch, 1)) + np.radians(
            np.vstack([m_tth.flatten(), m_eta.flatten(), np.zeros(npts_patch)]).T
        )

        # will need this later
        rMat_s = xfcapi.makeOscillRotMat([chi, angs[2]])

        # FOR ANGULAR MESH
        conn = gutil.cellConnectivity(sdims[0], sdims[1], origin="ll")
        gVec_c = xf.anglesToGVec(gVec_angs_vtx, xf.bVec_ref, xf.eta_ref, rMat_s=rMat_s, rMat_c=rMat_c)

        xy_eval_vtx = xfcapi.gvecToDetectorXY(gVec_c.T, rMat_d, rMat_s, rMat_c, tVec_d, tVec_s, tVec_c)
        if distortion is not None and len(distortion) == 2:
            xy_eval_vtx = distortion[0](xy_eval_vtx, distortion[1], invert=True)
            pass

        areas = compute_areas_func(xy_eval_vtx, conn)

        # EVALUATION POINTS
        #   * for lack of a better option will use centroids
        tth_eta_cen = gutil.cellCentroids(np.atleast_2d(gVec_angs_vtx[:, :2]), conn)
        gVec_angs = np.hstack([tth_eta_cen, np.tile(angs[2], (len(tth_eta_cen), 1))])
        gVec_c = xf.anglesToGVec(gVec_angs, xf.bVec_ref, xf.eta_ref, rMat_s=rMat_s, rMat_c=rMat_c)

        xy_eval = xfcapi.gvecToDetectorXY(gVec_c.T, rMat_d, rMat_s, rMat_c, tVec_d, tVec_s, tVec_c)
        if distortion is not None and len(distortion) == 2:
            xy_eval = distortion[0](xy_eval, distortion[1], invert=True)
            pass
        row_indices = gutil.cellIndices(row_edges, xy_eval[:, 1])
        col_indices = gutil.cellIndices(col_edges, xy_eval[:, 0])

        patches.append(
            (
                (gVec_angs_vtx[:, 0].reshape(m_tth.shape), gVec_angs_vtx[:, 1].reshape(m_tth.shape)),
                (xy_eval_vtx[:, 0].reshape(m_tth.shape), xy_eval_vtx[:, 1].reshape(m_tth.shape)),
                conn,
                areas.reshape(sdims[0], sdims[1]),
                (row_indices.reshape(sdims[0], sdims[1]), col_indices.reshape(sdims[0], sdims[1])),
            )
        )
        pass
    return patches
Esempio n. 6
0
def make_reflection_patches(instr_cfg,
                            tth_eta,
                            ang_pixel_size,
                            omega=None,
                            tth_tol=0.2,
                            eta_tol=1.0,
                            rmat_c=np.eye(3),
                            tvec_c=np.zeros((3, 1)),
                            npdiv=1,
                            quiet=False,
                            compute_areas_func=gutil.compute_areas):
    """
    Make angular patches on a detector.

    panel_dims are [(xmin, ymin), (xmax, ymax)] in mm

    pixel_pitch is [row_size, column_size] in mm

    FIXME: DISTORTION HANDING IS STILL A KLUDGE!!!

    patches are:

                 delta tth
    d  ------------- ... -------------
    e  | x | x | x | ... | x | x | x |
    l  ------------- ... -------------
    t                 .
    a                 .
                     .
    e  ------------- ... -------------
    t  | x | x | x | ... | x | x | x |
    a  ------------- ... -------------

    outputs are:
        (tth_vtx, eta_vtx),
        (x_vtx, y_vtx),
        connectivity,
        subpixel_areas,
        (x_center, y_center),
        (i_row, j_col)
    """
    npts = len(tth_eta)

    # detector quantities
    rmat_d = xfcapi.makeRotMatOfExpMap(
        np.r_[instr_cfg['detector']['transform']['tilt']])
    tvec_d = np.r_[instr_cfg['detector']['transform']['translation']]
    pixel_size = instr_cfg['detector']['pixels']['size']

    frame_nrows = instr_cfg['detector']['pixels']['rows']
    frame_ncols = instr_cfg['detector']['pixels']['columns']

    panel_dims = (
        -0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]],
        0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]])
    row_edges = np.arange(frame_nrows + 1)[::-1]*pixel_size[1] \
        + panel_dims[0][1]
    col_edges = np.arange(frame_ncols + 1)*pixel_size[0] \
        + panel_dims[0][0]

    # handle distortion
    distortion = None
    if distortion_key in instr_cfg['detector']:
        distortion_cfg = instr_cfg['detector'][distortion_key]
        if distortion_cfg is not None:
            try:
                func_name = distortion_cfg['function_name']
                dparams = distortion_cfg['parameters']
                distortion = distortion_pkg.get_mapping(func_name, dparams)
            except (KeyError):
                raise RuntimeError("problem with distortion specification")

    # sample frame
    chi = instr_cfg['oscillation_stage']['chi']
    tvec_s = np.r_[instr_cfg['oscillation_stage']['translation']]

    # beam vector
    bvec = np.r_[instr_cfg['beam']['vector']]

    # data to loop
    # ??? WOULD IT BE CHEAPER TO CARRY ZEROS OR USE CONDITIONAL?
    if omega is None:
        full_angs = np.hstack([tth_eta, np.zeros((npts, 1))])
    else:
        full_angs = np.hstack([tth_eta, omega.reshape(npts, 1)])

    patches = []
    for angs, pix in zip(full_angs, ang_pixel_size):
        # calculate bin edges for patch based on local angular pixel size
        # tth
        ntths, tth_edges = gutil.make_tolerance_grid(bin_width=np.degrees(
            pix[0]),
                                                     window_width=tth_tol,
                                                     num_subdivisions=npdiv)

        # eta
        netas, eta_edges = gutil.make_tolerance_grid(bin_width=np.degrees(
            pix[1]),
                                                     window_width=eta_tol,
                                                     num_subdivisions=npdiv)

        # FOR ANGULAR MESH
        conn = gutil.cellConnectivity(netas, ntths, origin='ll')

        # meshgrid args are (cols, rows), a.k.a (fast, slow)
        m_tth, m_eta = np.meshgrid(tth_edges, eta_edges)
        npts_patch = m_tth.size

        # calculate the patch XY coords from the (tth, eta) angles
        # !!! will CHEAT and ignore the small perturbation the different
        #     omega angle values causes and simply use the central value
        gVec_angs_vtx = np.tile(angs, (npts_patch, 1)) \
            + np.radians(
                np.vstack([m_tth.flatten(),
                            m_eta.flatten(),
                            np.zeros(npts_patch)
                ]).T
            )

        xy_eval_vtx, rmats_s, on_plane = _project_on_detector_plane(
            gVec_angs_vtx,
            rmat_d,
            rmat_c,
            chi,
            tvec_d,
            tvec_c,
            tvec_s,
            distortion,
            beamVec=bvec)

        areas = compute_areas_func(xy_eval_vtx, conn)

        # EVALUATION POINTS
        # !!! for lack of a better option will use centroids
        tth_eta_cen = gutil.cellCentroids(np.atleast_2d(gVec_angs_vtx[:, :2]),
                                          conn)

        gVec_angs = np.hstack(
            [tth_eta_cen, np.tile(angs[2], (len(tth_eta_cen), 1))])

        xy_eval, rmats_s, on_plane = _project_on_detector_plane(gVec_angs,
                                                                rmat_d,
                                                                rmat_c,
                                                                chi,
                                                                tvec_d,
                                                                tvec_c,
                                                                tvec_s,
                                                                distortion,
                                                                beamVec=bvec)

        row_indices = gutil.cellIndices(row_edges, xy_eval[:, 1])
        col_indices = gutil.cellIndices(col_edges, xy_eval[:, 0])

        # append patch data to list
        patches.append(
            ((gVec_angs_vtx[:, 0].reshape(m_tth.shape),
              gVec_angs_vtx[:, 1].reshape(m_tth.shape)),
             (xy_eval_vtx[:, 0].reshape(m_tth.shape),
              xy_eval_vtx[:, 1].reshape(m_tth.shape)), conn,
             areas.reshape(netas, ntths), (xy_eval[:, 0].reshape(netas, ntths),
                                           xy_eval[:, 1].reshape(netas,
                                                                 ntths)),
             (row_indices.reshape(netas,
                                  ntths), col_indices.reshape(netas, ntths))))
        pass  # close loop over angles
    return patches