Example #1
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
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
Example #3
0
    distortion = (xf.dFunc_ref, dparams)
except (KeyError):
    distortion = None

# for defining patches
delta_eta = 0.5
neta = int(360 / float(delta_eta))

eta = np.radians(delta_eta * np.linspace(0, neta - 1, num=neta))

angs = [
    np.vstack([i * np.ones(neta), eta, np.zeros(neta)]) for i in pd.getTTh()
]

# need xy coords and pixel sizes
gVec_ring_l = xf.anglesToGVec(angs[0].T, xf.bVec_ref, xf.eta_ref)
xydet_ring = xfcapi.gvecToDetectorXY(gVec_ring_l.T, rMat_d, rMat_s, rMat_c,
                                     tVec_d, tVec_s, tVec_c)

if distortion is not None:
    det_xy = distortion[0](xydet_ring, distortion[1], invert=True)
ang_ps = angularPixelSize(det_xy,
                          pixel_pitch,
                          rMat_d,
                          rMat_s,
                          tVec_d,
                          tVec_s,
                          tVec_c,
                          distortion=distortion)

    # dfunc = instr_cfg['detector']['distortion']['function_name']
    dparams = instr_cfg["detector"]["distortion"]["parameters"]
    distortion = (xf.dFunc_ref, dparams)
except (KeyError):
    distortion = None

# for defining patches
delta_eta = 0.5
neta = int(360 / float(delta_eta))

eta = np.radians(delta_eta * np.linspace(0, neta - 1, num=neta))

angs = [np.vstack([i * np.ones(neta), eta, np.zeros(neta)]) for i in pd.getTTh()]

# need xy coords and pixel sizes
gVec_ring_l = xf.anglesToGVec(angs[0].T, xf.bVec_ref, xf.eta_ref)
xydet_ring = xfcapi.gvecToDetectorXY(gVec_ring_l.T, rMat_d, rMat_s, rMat_c, tVec_d, tVec_s, tVec_c)

if distortion is not None:
    det_xy = distortion[0](xydet_ring, distortion[1], invert=True)
ang_ps = angularPixelSize(det_xy, pixel_pitch, rMat_d, rMat_s, tVec_d, tVec_s, tVec_c, distortion=distortion)


def compute_areas(xy_eval_vtx, conn):
    areas = np.zeros(len(conn))
    for i in range(len(conn)):
        polygon = [[xy_eval_vtx[conn[i, j], 0], xy_eval_vtx[conn[i, j], 1]] for j in range(4)]
        areas[i] = gutil.computeArea(polygon)
    return areas