Пример #1
0
def matchOmegas(xyo_det,
                hkls_idx,
                chi,
                rMat_c,
                bMat,
                wavelength,
                vInv=vInv_ref,
                beamVec=bVec_ref,
                etaVec=eta_ref,
                omePeriod=None):
    """
    For a given list of (x, y, ome) points, outputs the index into the results
    from oscillAnglesOfHKLs, including the calculated omega values.
    """
    # get omegas for rMat_s calculation
    if omePeriod is not None:
        meas_omes = xfcapi.mapAngle(xyo_det[:, 2], omePeriod)
    else:
        meas_omes = xyo_det[:, 2]

    oangs0, oangs1 = xfcapi.oscillAnglesOfHKLs(hkls_idx.T,
                                               chi,
                                               rMat_c,
                                               bMat,
                                               wavelength,
                                               vInv=vInv,
                                               beamVec=beamVec,
                                               etaVec=etaVec)
    if np.any(np.isnan(oangs0)):
        # debugging
        # TODO: remove this
        import pdb
        pdb.set_trace()
        nanIdx = np.where(np.isnan(oangs0[:, 0]))[0]
        errorString = "Infeasible parameters for hkls:\n"
        for i in range(len(nanIdx)):
            errorString += "%d  %d  %d\n" % tuple(hkls_idx[:, nanIdx[i]])
        raise RuntimeError(errorString)
    else:
        # CAPI version gives vstacked angles... must be (2, nhkls)
        calc_omes = np.vstack([oangs0[:, 2], oangs1[:, 2]])
    if omePeriod is not None:
        calc_omes = np.vstack([
            xfcapi.mapAngle(oangs0[:, 2], omePeriod),
            xfcapi.mapAngle(oangs1[:, 2], omePeriod)
        ])
    # do angular difference
    diff_omes = xfcapi.angularDifference(np.tile(meas_omes, (2, 1)), calc_omes)
    match_omes = np.argsort(diff_omes, axis=0) == 0
    calc_omes = calc_omes.T.flatten()[match_omes.T.flatten()]

    return match_omes, calc_omes
Пример #2
0
 def cart_to_angles(xys, panel, iviewer):
     ang_crds, _ = panel.cart_to_angles(xys, tvec_c=iviewer.instr.tvec)
     ang_crds = np.degrees(ang_crds)
     ang_crds[:, 1] = mapAngle(ang_crds[:, 1],
                               HexrdConfig().polar_res_eta_period,
                               units='degrees')
     return ang_crds
Пример #3
0
def simulate_diffractions(grain_params, experiment, controller):
    """actual forward simulation of the diffraction"""

    # use a packed array for the image_stack
    array_dims = (experiment.nframes, experiment.ncols,
                  ((experiment.nrows - 1) // 8) + 1)
    image_stack = np.zeros(array_dims, dtype=np.uint8)

    count = len(grain_params)
    subprocess = 'simulate diffractions'

    _project = xrdutil._project_on_detector_plane
    rD = experiment.rMat_d
    chi = experiment.chi
    tD = experiment.tVec_d
    tS = experiment.tVec_s
    distortion = experiment.distortion

    eta_range = [
        (-np.pi, np.pi),
    ]
    ome_range = experiment.ome_range
    ome_period = (-np.pi, np.pi)

    full_hkls = xrdutil._fetch_hkls_from_planedata(experiment.plane_data)
    bMat = experiment.plane_data.latVecOps['B']
    wlen = experiment.plane_data.wavelength

    controller.start(subprocess, count)
    for i in range(count):
        rC = xfcapi.makeRotMatOfExpMap(grain_params[i][0:3])
        tC = np.ascontiguousarray(grain_params[i][3:6])
        vInv_s = np.ascontiguousarray(grain_params[i][6:12])
        ang_list = np.vstack(
            xfcapi.oscillAnglesOfHKLs(full_hkls[:, 1:],
                                      chi,
                                      rC,
                                      bMat,
                                      wlen,
                                      vInv=vInv_s))
        # hkls not needed here
        all_angs, _ = xrdutil._filter_hkls_eta_ome(full_hkls, ang_list,
                                                   eta_range, ome_range)
        all_angs[:, 2] = xfcapi.mapAngle(all_angs[:, 2], ome_period)

        proj_pts = _project(all_angs, rD, rC, chi, tD, tC, tS, distortion)
        det_xy = proj_pts[0]
        _write_pixels(det_xy, all_angs[:, 2], image_stack, experiment.base,
                      experiment.inv_deltas, experiment.clip_vals)

        controller.update(i + 1)

    controller.finish(subprocess)
    return image_stack
Пример #4
0
    def _normalize_angs_hkls(angs_0, angs_1, omePeriod, symHKLs_ix):
        # Interleave the two produced oang solutions to simplify later
        # processing
        oangs = np.empty((len(angs_0) * 2, 3), dtype=angs_0.dtype)
        oangs[0::2] = angs_0
        oangs[1::2] = angs_1

        # Map all of the angles at once
        oangs[:, 1] = xfcapi.mapAngle(oangs[:, 1])
        oangs[:, 2] = xfcapi.mapAngle(oangs[:, 2], omePeriod)

        # generate array of symHKLs indices
        symHKLs_ix = symHKLs_ix * 2
        hkl_idx = np.empty((symHKLs_ix[-1], ), dtype=int)
        start = symHKLs_ix[0]
        idx = 0
        for end in symHKLs_ix[1:]:
            hkl_idx[start:end] = idx
            start = end
            idx += 1

        return oangs, hkl_idx
Пример #5
0
    def generate_ring_points(self, tths, etas, panel, display_mode):
        delta_eta_nom = np.degrees(np.median(np.diff(etas)))
        ring_pts = []
        skipped_tth = []
        for i, tth in enumerate(tths):
            # construct ideal angular coords
            ang_crds = np.vstack([np.tile(tth, len(etas)), etas]).T

            # !!! must apply offset
            xys_full = panel.angles_to_cart(ang_crds, tvec_c=self.tvec)

            # skip if ring not on panel
            if len(xys_full) == 0:
                skipped_tth.append(i)
                continue

            # clip to detector panel
            xys, on_panel = panel.clip_to_panel(xys_full, buffer_edges=False)

            if display_mode == ViewType.polar:
                # !!! apply offset correction
                ang_crds, _ = panel.cart_to_angles(xys,
                                                   tvec_c=self.instrument.tvec)

                if len(ang_crds) == 0:
                    skipped_tth.append(i)
                    continue

                # Swap columns, convert to degrees
                ang_crds[:, [0, 1]] = np.degrees(ang_crds[:, [1, 0]])

                # fix eta period
                ang_crds[:, 0] = xfcapi.mapAngle(ang_crds[:, 0],
                                                 self.eta_period,
                                                 units='degrees')

                # sort points for monotonic eta
                eidx = np.argsort(ang_crds[:, 0])
                ang_crds = ang_crds[eidx, :]

                # branch cut
                delta_eta_est = np.median(np.diff(ang_crds[:, 0]))
                cut_on_panel = bool(
                    xfcapi.angularDifference(np.min(ang_crds[:, 0]),
                                             np.max(ang_crds[:, 0]),
                                             units='degrees') < 2 *
                    delta_eta_est)
                if cut_on_panel and len(ang_crds) > 2:
                    split_idx = np.argmax(
                        np.abs(np.diff(ang_crds[:, 0]) - delta_eta_est)) + 1

                    ang_crds = np.vstack([
                        ang_crds[:split_idx, :], nans_row,
                        ang_crds[split_idx:, :]
                    ])

                # append to list with nan padding
                ring_pts.append(np.vstack([ang_crds, nans_row]))

            elif display_mode in [ViewType.raw, ViewType.cartesian]:

                if display_mode == ViewType.raw:
                    # !!! distortion
                    if panel.distortion is not None:
                        xys = panel.distortion.apply_inverse(xys)

                    # Convert to pixel coordinates
                    # ??? keep in pixels?
                    xys = panel.cartToPixel(xys)

                diff_tol = np.radians(self.delta_eta) + 1e-4
                ring_breaks = np.where(
                    np.abs(np.diff(etas[on_panel])) > diff_tol)[0] + 1
                n_segments = len(ring_breaks) + 1

                if n_segments == 1:
                    ring_pts.append(np.vstack([xys, nans_row]))
                else:
                    src_len = sum(on_panel)
                    dst_len = src_len + len(ring_breaks)
                    nxys = np.nan * np.ones((dst_len, 2))
                    ii = 0
                    for i in range(n_segments - 1):
                        jj = ring_breaks[i]
                        nxys[ii + i:jj + i, :] = xys[ii:jj, :]
                        ii = jj
                    i = n_segments - 1
                    nxys[ii + i:, :] = xys[ii:, :]
                    ring_pts.append(np.vstack([nxys, nans_row]))

        return ring_pts, skipped_tth
Пример #6
0
    def overlay(self, display_mode=ViewType.raw):
        sim_data = self.instrument.simulate_laue_pattern(
            self.plane_data,
            minEnergy=self.min_energy,
            maxEnergy=self.max_energy,
            rmat_s=self.sample_rmat,
            grain_params=[
                self.crystal_params,
            ])

        point_groups = {}
        keys = ['spots', 'ranges', 'hkls']
        for det_key, psim in sim_data.items():
            point_groups[det_key] = {key: [] for key in keys}

            # grab panel and split out simulation results
            # !!! note that the sim results are lists over number of grains
            #     and here we explicitly have one.
            panel = self.instrument.detectors[det_key]
            xy_det, hkls_in, angles, dspacing, energy = psim

            # find valid points
            idx = ~np.isnan(energy[0])  # there is only one grain here

            # filter (tth, eta) results
            xy_data = xy_det[0][idx, :]
            angles = angles[0][idx, :]  # these are in radians
            point_groups[det_key]['hkls'] = hkls_in[0][:, idx].T
            angles[:, 1] = xfcapi.mapAngle(angles[:, 1],
                                           np.radians(self.eta_period),
                                           units='radians')

            # !!! apply offset corrections to angles
            # convert to angles in LAB ref
            angles_corr, _ = xfcapi.detectorXYToGvec(
                xy_data,
                panel.rmat,
                self.sample_rmat,
                panel.tvec,
                self.instrument.tvec,
                constants.zeros_3,
                beamVec=self.instrument.beam_vector,
                etaVec=self.instrument.eta_vector)
            # FIXME modify output to be array
            angles_corr = np.vstack(angles_corr).T
            angles_corr[:, 1] = xfcapi.mapAngle(angles_corr[:, 1],
                                                np.radians(self.eta_period),
                                                units='radians')

            if display_mode == ViewType.polar:
                range_corners = self.range_corners(angles_corr)
                # Save the Laue spots as a list instead of a numpy array,
                # so that we can predictably get the id() of spots inside.
                # Numpy arrays do fancy optimizations that break this.
                spots = np.degrees(angles_corr).tolist()
                point_groups[det_key]['spots'] = spots
                point_groups[det_key]['ranges'] = np.degrees(range_corners)
            elif display_mode in [ViewType.raw, ViewType.cartesian]:
                # !!! verify this
                range_corners = self.range_corners(angles)
                panel = self.instrument.detectors[det_key]
                data = xy_data
                if display_mode == ViewType.raw:
                    # Convert to pixel coordinates
                    data = panel.cartToPixel(data)
                    # Swap x and y, they are flipped
                    data[:, [0, 1]] = data[:, [1, 0]]

                point_groups[det_key]['spots'] = data
                point_groups[det_key]['ranges'] = self.range_data(
                    range_corners, display_mode, panel)

        return point_groups
Пример #7
0
    def detector_borders(self, det):
        panel = self.detectors[det]

        row_vec, col_vec = panel.row_pixel_vec, panel.col_pixel_vec
        x_start, x_stop = col_vec[0], col_vec[-1]
        y_start, y_stop = row_vec[0], row_vec[-1]

        # Create the borders in Cartesian
        borders = [[[x, y_start] for x in col_vec],
                   [[x, y_stop] for x in col_vec],
                   [[x_start, y] for y in row_vec],
                   [[x_stop, y] for y in row_vec]]

        # Convert each border to angles
        for i, border in enumerate(borders):
            angles, _ = detectorXYToGvec(border,
                                         panel.rmat,
                                         ct.identity_3x3,
                                         panel.tvec,
                                         ct.zeros_3,
                                         ct.zeros_3,
                                         beamVec=panel.bvec,
                                         etaVec=panel.evec)
            angles = np.array(angles)
            angles[1:, :] = mapAngle(angles[1:, :],
                                     np.radians(self.eta_period),
                                     units='radians')
            # Convert to degrees, and keep them as lists for
            # easier modification later
            borders[i] = np.degrees(angles).tolist()

        # Here, we are going to remove points that are out-of-bounds,
        # and we are going to insert None in between points that are far
        # apart (in the y component), so that they are not connected in the
        # plot. This happens for detectors that are wrapped in the image.
        x_range = np.degrees((self.tth_min, self.tth_max))
        y_range = np.degrees((self.eta_min, self.eta_max))

        # "Far apart" is currently defined as half of the y range
        max_y_distance = abs(y_range[1] - y_range[0]) / 2.0
        for j in range(4):
            border_x, border_y = borders[j][0], borders[j][1]
            i = 0
            # These should be the same length, but just in case...
            while i < len(border_x) and i < len(border_y):
                x, y = border_x[i], border_y[i]
                if (not x_range[0] <= x <= x_range[1]
                        or not y_range[0] <= y <= y_range[1]):
                    # The point is out of bounds, remove it
                    del border_x[i], border_y[i]
                    continue

                if i != 0 and abs(y - border_y[i - 1]) > max_y_distance:
                    # Points are too far apart. Insert a None
                    border_x.insert(i, None)
                    border_y.insert(i, None)
                    i += 1

                i += 1

        return borders
Пример #8
0
    def generate_ring_points(self, tths, etas, panel, display_mode):
        ring_pts = []
        for tth in tths:
            ang_crds = np.vstack([np.tile(tth, len(etas)), etas]).T
            if display_mode == ViewType.polar:
                # !!! apply offset correction
                ang_crds = _convert_angles(
                    ang_crds, panel,
                    identity_3x3, self.tvec,
                    beam_vector=self.instrument.beam_vector,
                    eta_vector=self.instrument.eta_vector
                )
                # Swap columns, convert to degrees
                ang_crds[:, [0, 1]] = np.degrees(ang_crds[:, [1, 0]])

                # fix eta period
                ang_crds[:, 0] = xfcapi.mapAngle(
                    ang_crds[:, 0], self.eta_period, units='degrees'
                )

                # sort points for monotonic eta
                eidx = np.argsort(ang_crds[:, 0])
                ang_crds = ang_crds[eidx, :]

                # append to list with nan padding
                ring_pts.append(np.vstack([ang_crds, nans_row]))
            elif display_mode in [ViewType.raw, ViewType.cartesian]:
                # !!! must apply offset
                xys_full = panel.angles_to_cart(ang_crds, tvec_c=self.tvec)

                # !!! distortion
                if panel.distortion is not None:
                    xys_full = panel.distortion.apply_inverse(xys_full)

                # clip to detector panel
                xys, on_panel = panel.clip_to_panel(
                    xys_full, buffer_edges=False
                )

                if display_mode == ViewType.raw:
                    # Convert to pixel coordinates
                    # ??? keep in pixels?
                    xys = panel.cartToPixel(xys)

                diff_tol = np.radians(self.delta_eta) + 1e-4
                ring_breaks = np.where(
                    np.abs(np.diff(etas[on_panel])) > diff_tol
                )[0] + 1
                n_segments = len(ring_breaks) + 1

                if n_segments == 1:
                    ring_pts.append(np.vstack([xys, nans_row]))
                else:
                    src_len = sum(on_panel)
                    dst_len = src_len + len(ring_breaks)
                    nxys = np.nan*np.ones((dst_len, 2))
                    ii = 0
                    for i in range(n_segments - 1):
                        jj = ring_breaks[i]
                        nxys[ii + i:jj + i, :] = xys[ii:jj, :]
                        ii = jj
                    i = n_segments - 1
                    nxys[ii + i:, :] = xys[ii:, :]
                    ring_pts.append(np.vstack([nxys, nans_row]))

        return ring_pts
Пример #9
0
        return np.hstack(resd)  # resd


# %%

det_key = 'ge2'

fig, ax = plt.subplots()

rid = 0
ii = 0
for ring_data in powder_lines[det_key][rid]:
    tth_edges = ring_data[0][0]
    tth_centers = 0.5 * np.sum(np.vstack([tth_edges[:-1], tth_edges[1:]]),
                               axis=0)
    eta = np.degrees(mapAngle(ring_data[0][1], (0, 2 * np.pi)))
    intensities = np.sum(np.array(ring_data[1]).squeeze(), axis=0)
    if ii < 1:
        iprev = 0
    else:
        iprev = 0.25 * np.max(
            np.sum(powder_lines[det_key][rid][ii - 1][1], axis=0))
    ax.plot(tth_centers, intensities + iprev)
    ii += 1

p0 = fitpeak.estimate_pk_parms_1d(tth_centers, intensities, pktype)

p = fitpeak.fit_pk_parms_1d(p0, tth_centers, intensities, pktype)

if pktype == 'pvoigt':
    fp0 = fitpeak.pkfuncs.pvoigt1d(p0, tth_centers)