Example #1
0
    def simulate_laue_pattern(self,
                              crystal_data,
                              minEnergy=5.,
                              maxEnergy=35.,
                              rmat_s=None,
                              tvec_s=None,
                              grain_params=None,
                              beam_vec=None):
        """
        """
        if isinstance(crystal_data, PlaneData):

            plane_data = crystal_data

            # grab the expanded list of hkls from plane_data
            hkls = np.hstack(plane_data.getSymHKLs())

            # and the unit plane normals (G-vectors) in CRYSTAL FRAME
            gvec_c = np.dot(plane_data.latVecOps['B'], hkls)
        elif len(crystal_data) == 2:
            # !!! should clean this up
            hkls = np.array(crystal_data[0])
            bmat = crystal_data[1]
            gvec_c = np.dot(bmat, hkls)
        else:
            raise (RuntimeError, 'argument list not understood')
        nhkls_tot = hkls.shape[1]

        # parse energy ranges
        # TODO: allow for spectrum parsing
        multipleEnergyRanges = False
        if hasattr(maxEnergy, '__len__'):
            assert len(maxEnergy) == len(minEnergy), \
                'energy cutoff ranges must have the same length'
            multipleEnergyRanges = True
            lmin = []
            lmax = []
            for i in range(len(maxEnergy)):
                lmin.append(ct.keVToAngstrom(maxEnergy[i]))
                lmax.append(ct.keVToAngstrom(minEnergy[i]))
        else:
            lmin = ct.keVToAngstrom(maxEnergy)
            lmax = ct.keVToAngstrom(minEnergy)

        # parse grain parameters kwarg
        if grain_params is None:
            grain_params = np.atleast_2d(
                np.hstack([np.zeros(6), ct.identity_6x1]))
        n_grains = len(grain_params)

        # sample rotation
        if rmat_s is None:
            rmat_s = ct.identity_3x3

        # dummy translation vector... make input
        if tvec_s is None:
            tvec_s = ct.zeros_3

        # beam vector
        if beam_vec is None:
            beam_vec = ct.beam_vec

        # =========================================================================
        # LOOP OVER GRAINS
        # =========================================================================

        # pre-allocate output arrays
        xy_det = np.nan * np.ones((n_grains, nhkls_tot, 2))
        hkls_in = np.nan * np.ones((n_grains, 3, nhkls_tot))
        angles = np.nan * np.ones((n_grains, nhkls_tot, 2))
        dspacing = np.nan * np.ones((n_grains, nhkls_tot))
        energy = np.nan * np.ones((n_grains, nhkls_tot))
        for iG, gp in enumerate(grain_params):
            rmat_c = makeRotMatOfExpMap(gp[:3])
            tvec_c = gp[3:6].reshape(3, 1)
            vInv_s = mutil.vecMVToSymm(gp[6:].reshape(6, 1))

            # stretch them: V^(-1) * R * Gc
            gvec_s_str = np.dot(vInv_s, np.dot(rmat_c, gvec_c))
            ghat_c_str = mutil.unitVector(np.dot(rmat_c.T, gvec_s_str))

            # project
            dpts = gvecToDetectorXY(ghat_c_str.T,
                                    self.rmat,
                                    rmat_s,
                                    rmat_c,
                                    self.tvec,
                                    tvec_s,
                                    tvec_c,
                                    beamVec=beam_vec)

            # check intersections with detector plane
            canIntersect = ~np.isnan(dpts[:, 0])
            npts_in = sum(canIntersect)

            if np.any(canIntersect):
                dpts = dpts[canIntersect, :].reshape(npts_in, 2)
                dhkl = hkls[:, canIntersect].reshape(3, npts_in)

                # back to angles
                tth_eta, gvec_l = detectorXYToGvec(dpts,
                                                   self.rmat,
                                                   rmat_s,
                                                   self.tvec,
                                                   tvec_s,
                                                   tvec_c,
                                                   beamVec=beam_vec)
                tth_eta = np.vstack(tth_eta).T

                # warp measured points
                if self.distortion is not None:
                    if len(self.distortion) == 2:
                        dpts = self.distortion[0](dpts,
                                                  self.distortion[1],
                                                  invert=True)
                    else:
                        raise (RuntimeError,
                               "something is wrong with the distortion")

                # plane spacings and energies
                dsp = 1. / rowNorm(gvec_s_str[:, canIntersect].T)
                wlen = 2 * dsp * np.sin(0.5 * tth_eta[:, 0])

                # clip to detector panel
                _, on_panel = self.clip_to_panel(dpts, buffer_edges=True)

                if multipleEnergyRanges:
                    validEnergy = np.zeros(len(wlen), dtype=bool)
                    for i in range(len(lmin)):
                        in_energy_range = np.logical_and(
                            wlen >= lmin[i], wlen <= lmax[i])
                        validEnergy = validEnergy | in_energy_range
                        pass
                else:
                    validEnergy = np.logical_and(wlen >= lmin, wlen <= lmax)
                    pass

                # index for valid reflections
                keepers = np.where(np.logical_and(on_panel, validEnergy))[0]

                # assign output arrays
                xy_det[iG][keepers, :] = dpts[keepers, :]
                hkls_in[iG][:, keepers] = dhkl[:, keepers]
                angles[iG][keepers, :] = tth_eta[keepers, :]
                dspacing[iG, keepers] = dsp[keepers]
                energy[iG, keepers] = ct.keVToAngstrom(wlen[keepers])
                pass  # close conditional on valids
            pass  # close loop on grains
        return xy_det, hkls_in, angles, dspacing, energy
def calibrate_instrument_from_sx(instr,
                                 grain_params,
                                 bmat,
                                 xyo_det,
                                 hkls_idx,
                                 param_flags=None,
                                 dparam_flags=None,
                                 ome_period=None,
                                 xtol=cnst.sqrt_epsf,
                                 ftol=cnst.sqrt_epsf,
                                 factor=10.,
                                 sim_only=False,
                                 use_robust_lsq=False):
    """
    arguments xyo_det, hkls_idx are DICTs over panels

    !!!
        distortion is still hosed...
        Currently a dict of detector keys with
        distortion[key] = [d_func, d_params, d_flags]
    """
    pnames = [
        '{:>24s}'.format('wavelength'),
        '{:>24s}'.format('chi'),
        '{:>24s}'.format('tvec_s[0]'),
        '{:>24s}'.format('tvec_s[1]'),
        '{:>24s}'.format('tvec_s[2]'),
        '{:>24s}'.format('expmap_c[0]'),
        '{:>24s}'.format('expmap_c[0]'),
        '{:>24s}'.format('expmap_c[0]'),
        '{:>24s}'.format('tvec_c[0]'),
        '{:>24s}'.format('tvec_c[1]'),
        '{:>24s}'.format('tvec_c[2]'),
    ]

    for det_key, panel in instr.detectors.iteritems():
        pnames += [
            '{:>24s}'.format('%s tilt[0]' % det_key),
            '{:>24s}'.format('%s tilt[1]' % det_key),
            '{:>24s}'.format('%s tilt[2]' % det_key),
            '{:>24s}'.format('%s tvec[0]' % det_key),
            '{:>24s}'.format('%s tvec[1]' % det_key),
            '{:>24s}'.format('%s tvec[2]' % det_key),
        ]

    # now add distortion if
    for det_key, panel in instr.detectors.iteritems():
        if panel.distortion is not None:
            for j in range(len(panel.distortion[1])):
                pnames.append('{:>24s}'.format('%s dparam[%d]' % (det_key, j)))

    # reset parameter flags for instrument as specified
    if param_flags is None:
        param_flags = instr.param_flags
    else:
        # will throw an AssertionError if wrong length
        instr.param_flags = param_flags

    det_keys = instr.detectors.keys()

    # re-map omegas if need be
    if ome_period is not None:
        for det_key in det_keys:
            xyo_det[det_key][:, 2] = xfcapi.mapAngle(xyo_det[det_key][:, 2],
                                                     ome_period)
    # grain parameters
    expmap_c = grain_params[:3]
    tvec_c = grain_params[3:6]
    vinv_s = grain_params[6:]

    plist_full = instr.calibration_params(expmap_c, tvec_c)

    dfuncs = {}
    ndparams = {}
    dparam_flags = []
    for det_key, panel in instr.detectors.iteritems():
        if panel.distortion is not None:
            dfuncs[det_key] = panel.distortion[0]
            # ititialize to all False...
            ndparams[det_key] = len(panel.distortion[1])
        else:
            dfuncs[det_key] = None
            ndparams[det_key] = 0
        dparam_flags.append(np.zeros(ndparams[det_key], dtype=bool))
    dparam_flags = np.hstack(dparam_flags)
    refine_flags = np.hstack([param_flags, dparam_flags])
    plist_fit = plist_full[refine_flags]
    fit_args = (plist_full, param_flags, dfuncs, dparam_flags, ndparams, instr,
                xyo_det, hkls_idx, bmat, vinv_s, ome_period, instr.beam_vector,
                instr.eta_vector)
    if sim_only:
        return sxcal_obj_func(plist_fit,
                              plist_full,
                              param_flags,
                              dfuncs,
                              dparam_flags,
                              ndparams,
                              instr,
                              xyo_det,
                              hkls_idx,
                              bmat,
                              vinv_s,
                              ome_period,
                              instr.beam_vector,
                              instr.eta_vector,
                              sim_only=True)
    else:
        print("Set up to refine:")
        for i in np.where(refine_flags)[0]:
            print("\t%s = %1.7e" % (pnames[i], plist_full[i]))

        # run optimization
        if use_robust_lsq:
            result = least_squares(sxcal_obj_func,
                                   plist_fit,
                                   args=fit_args,
                                   xtol=xtol,
                                   ftol=ftol,
                                   loss='soft_l1',
                                   method='trf')
            x = result.x
            resd = result.fun
            mesg = result.message
            ierr = result.status
        else:
            # do least squares problem
            x, cov_x, infodict, mesg, ierr = leastsq(sxcal_obj_func,
                                                     plist_fit,
                                                     args=fit_args,
                                                     factor=factor,
                                                     xtol=xtol,
                                                     ftol=ftol,
                                                     full_output=1)
            resd = infodict['fvec']
        if ierr not in [1, 2, 3, 4]:
            raise RuntimeError("solution not found: ierr = %d" % ierr)
        else:
            print("INFO: optimization fininshed successfully with ierr=%d" %
                  ierr)
            print("INFO: %s" % mesg)

        # ??? output message handling?
        fit_params = plist_full
        fit_params[refine_flags] = x

        # run simulation with optimized results
        sim_final = sxcal_obj_func(x,
                                   plist_full,
                                   param_flags,
                                   dfuncs,
                                   dparam_flags,
                                   ndparams,
                                   instr,
                                   xyo_det,
                                   hkls_idx,
                                   bmat,
                                   vinv_s,
                                   ome_period,
                                   instr.beam_vector,
                                   instr.eta_vector,
                                   sim_only=True)

        # ??? reset instrument here?
        instr.beam_energy = cnst.keVToAngstrom(fit_params[0])
        instr.chi = fit_params[1]
        instr.tvec = fit_params[2:5]
        ii = 11
        for det_key, panel in instr.detectors.iteritems():
            panel.tilt = fit_params[ii:ii + 3]
            panel.tvec = fit_params[ii + 3:ii + 6]
            ii += 6
            # !!! use jj to do distortion...
            if panel.distortion is not None:
                pass
            pass

        return fit_params, resd, sim_final
Example #3
0
    def simulate_rotation_series(self,
                                 plane_data,
                                 grain_param_list,
                                 eta_ranges=[
                                     (-np.pi, np.pi),
                                 ],
                                 ome_ranges=[
                                     (-np.pi, np.pi),
                                 ],
                                 ome_period=(-np.pi, np.pi),
                                 chi=0.,
                                 tVec_s=ct.zeros_3,
                                 wavelength=None):
        """
        """

        # grab B-matrix from plane data
        bMat = plane_data.latVecOps['B']

        # reconcile wavelength
        #   * added sanity check on exclusions here; possible to
        #   * make some reflections invalid (NaN)
        if wavelength is None:
            wavelength = plane_data.wavelength
        else:
            if plane_data.wavelength != wavelength:
                plane_data.wavelength = ct.keVToAngstrom(wavelength)
        assert not np.any(np.isnan(plane_data.getTTh())),\
            "plane data exclusions incompatible with wavelength"

        # vstacked G-vector id, h, k, l
        full_hkls = xrdutil._fetch_hkls_from_planedata(plane_data)
        """ LOOP OVER GRAINS """
        valid_ids = []
        valid_hkls = []
        valid_angs = []
        valid_xys = []
        ang_pixel_size = []
        for gparm in grain_param_list:

            # make useful parameters
            rMat_c = makeRotMatOfExpMap(gparm[:3])
            tVec_c = gparm[3:6]
            vInv_s = gparm[6:]

            # All possible bragg conditions as vstacked [tth, eta, ome]
            # for each omega solution
            angList = np.vstack(
                oscillAnglesOfHKLs(
                    full_hkls[:, 1:],
                    chi,
                    rMat_c,
                    bMat,
                    wavelength,
                    vInv=vInv_s,
                ))

            # filter by eta and omega ranges
            # ??? get eta range from detector?
            allAngs, allHKLs = xrdutil._filter_hkls_eta_ome(
                full_hkls, angList, eta_ranges, ome_ranges)
            allAngs[:, 2] = mapAngle(allAngs[:, 2], ome_period)

            # find points that fall on the panel
            det_xy, rMat_s = xrdutil._project_on_detector_plane(
                allAngs, self.rmat, rMat_c, chi, self.tvec, tVec_c, tVec_s,
                self.distortion)
            xys_p, on_panel = self.clip_to_panel(det_xy)
            valid_xys.append(xys_p)

            # grab hkls and gvec ids for this panel
            valid_hkls.append(allHKLs[on_panel, 1:])
            valid_ids.append(allHKLs[on_panel, 0])

            # reflection angles (voxel centers) and pixel size in (tth, eta)
            valid_angs.append(allAngs[on_panel, :])
            ang_pixel_size.append(self.angularPixelSize(xys_p))
        return valid_ids, valid_hkls, valid_angs, valid_xys, ang_pixel_size
Example #4
0
 def wavelength(self):
     return constants.keVToAngstrom(self.energy)
Example #5
0
 def wavelength(self, x):
     """
     in angstrom
     """
     self._energy = constants.keVToAngstrom(x)
Example #6
0
def mockup_experiment():
    # user options
    # each grain is provided in the form of a quaternion.

    # The following array contains the quaternions for the array. Note that the
    # quaternions are in the columns, with the first row (row 0) being the real
    # part w. We assume that we are dealing with unit quaternions

    quats = np.array([[0.91836393, 0.90869942], [0.33952917, 0.18348350],
                      [0.17216207, 0.10095837], [0.10811041, 0.36111851]])

    n_grains = quats.shape[-1]  # last dimension provides the number of grains
    phis = 2. * np.arccos(
        quats[0, :])  # phis are the angles for the quaternion
    # ns contains the rotation axis as an unit vector
    ns = hexrd.matrixutil.unitVector(quats[1:, :])
    exp_maps = np.array([phis[i] * ns[:, i] for i in range(n_grains)])
    rMat_c = rotations.rotMatOfQuat(quats)

    cvec = np.arange(-25, 26)
    X, Y, Z = np.meshgrid(cvec, cvec, cvec)

    crd0 = 1e-3 * np.vstack([X.flatten(), Y.flatten(), Z.flatten()]).T
    crd1 = crd0 + np.r_[0.100, 0.100, 0]
    crds = np.array([crd0, crd1])

    # make grain parameters
    grain_params = []
    for i in range(n_grains):
        for j in range(len(crd0)):
            grain_params.append(
                np.hstack([exp_maps[i, :], crds[i][j, :], vInv_ref]))

    # scan range and period
    ome_period = (0, 2 * np.pi)
    ome_range = [
        ome_period,
    ]
    ome_step = np.radians(1.)
    nframes = 0
    for i in range(len(ome_range)):
        nframes += int((ome_range[i][1] - ome_range[i][0]) / ome_step)

    ome_edges = np.arange(nframes + 1) * ome_step

    # instrument
    with open('./retiga.yml', 'r') as fildes:
        instr = instrument.HEDMInstrument(yaml.safe_load(fildes))
    panel = next(iter(instr.detectors.values()))  # !!! there is only 1

    # tranform paramters
    #   Sample
    chi = instr.chi
    tVec_s = instr.tvec
    #   Detector
    rMat_d = panel.rmat
    tilt_angles_xyzp = np.asarray(rotations.angles_from_rmat_xyz(rMat_d))
    tVec_d = panel.tvec

    # pixels
    row_ps = panel.pixel_size_row
    col_ps = panel.pixel_size_col
    pixel_size = (row_ps, col_ps)
    nrows = panel.rows
    ncols = panel.cols

    # panel dimensions
    panel_dims = [tuple(panel.corner_ll), tuple(panel.corner_ur)]

    x_col_edges = panel.col_edge_vec
    y_row_edges = panel.row_edge_vec
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)

    max_pixel_tth = instrument.max_tth(instr)

    detector_params = np.hstack([tilt_angles_xyzp, tVec_d, chi, tVec_s])
    distortion = panel.distortion  # !!! must be None for now

    # a different parametrization for the sensor
    # (makes for faster quantization)
    base = np.array([x_col_edges[0], y_row_edges[0], ome_edges[0]])
    deltas = np.array([
        x_col_edges[1] - x_col_edges[0], y_row_edges[1] - y_row_edges[0],
        ome_edges[1] - ome_edges[0]
    ])
    inv_deltas = 1.0 / deltas
    clip_vals = np.array([ncols, nrows])

    # dilation
    max_diameter = np.sqrt(3) * 0.005
    row_dilation = int(np.ceil(0.5 * max_diameter / row_ps))
    col_dilation = int(np.ceil(0.5 * max_diameter / col_ps))

    # crystallography data
    beam_energy = valunits.valWUnit("beam_energy", "energy", instr.beam_energy,
                                    "keV")
    beam_wavelength = constants.keVToAngstrom(beam_energy.getVal('keV'))
    dmin = valunits.valWUnit(
        "dmin", "length", 0.5 * beam_wavelength / np.sin(0.5 * max_pixel_tth),
        "angstrom")

    gold = material.Material()
    gold.latticeParameters = [4.0782]
    gold.dmin = dmin
    gold.beamEnergy = beam_energy
    gold.planeData.exclusions = None
    gold.planeData.tThMax = max_pixel_tth  # note this comes detector

    ns = argparse.Namespace()
    # grains related information
    ns.n_grains = n_grains  # this can be derived from other values...
    ns.rMat_c = rMat_c  # n_grains rotation matrices (one per grain)
    ns.exp_maps = exp_maps  # n_grains exp_maps (one per grain)

    ns.plane_data = gold.planeData
    ns.detector_params = detector_params
    ns.pixel_size = pixel_size
    ns.ome_range = ome_range
    ns.ome_period = ome_period
    ns.x_col_edges = x_col_edges
    ns.y_row_edges = y_row_edges
    ns.ome_edges = ome_edges
    ns.ncols = ncols
    ns.nrows = nrows
    ns.nframes = nframes  # used only in simulate...
    ns.rMat_d = rMat_d
    ns.tVec_d = tVec_d
    ns.chi = chi  # note this is used to compute S... why is it needed?
    ns.tVec_s = tVec_s
    ns.rMat_c = rMat_c
    ns.row_dilation = row_dilation
    ns.col_dilation = col_dilation
    ns.distortion = distortion
    ns.panel_dims = panel_dims  # used only in simulate...
    ns.base = base
    ns.inv_deltas = inv_deltas
    ns.clip_vals = clip_vals

    return grain_params, ns
Example #7
0
from enum import Enum
import numpy as np

from hexrd import constants

# Wavelength to kilo electron volt conversion
WAVELENGTH_TO_KEV = constants.keVToAngstrom(1.)
KEV_TO_WAVELENGTH = constants.keVToAngstrom(1.)

DEFAULT_CMAP = 'plasma'

UI_DARK_INDEX_MEDIAN = 0
UI_DARK_INDEX_EMPTY_FRAMES = 1
UI_DARK_INDEX_AVERAGE = 2
UI_DARK_INDEX_MAXIMUM = 3
UI_DARK_INDEX_FILE = 4
UI_DARK_INDEX_NONE = 5

UI_TRANS_INDEX_NONE = 0
UI_TRANS_INDEX_FLIP_VERTICALLY = 1
UI_TRANS_INDEX_FLIP_HORIZONTALLY = 2
UI_TRANS_INDEX_TRANSPOSE = 3
UI_TRANS_INDEX_ROTATE_90 = 4
UI_TRANS_INDEX_ROTATE_180 = 5
UI_TRANS_INDEX_ROTATE_270 = 6

UI_AGG_INDEX_NONE = 0
UI_AGG_INDEX_MAXIMUM = 1
UI_AGG_INDEX_MEDIAN = 2
UI_AGG_INDEX_AVERAGE = 3
Example #8
0
 def wavelength(self):
     return constants.keVToAngstrom(self.energy)
Example #9
0
 def wavelength(self, x):
     """
     in angstrom
     """
     self._energy = constants.keVToAngstrom(x)
instr = instrument.HEDMInstrument(instr_cfg)

data_path = './'
img_series_root = 'ge_scan_114'
img_series = imageseries.open(
        os.path.join(
                img_series_root + '-fcache-dir', img_series_root + '-fcache.yml'
                )
        , 'frame-cache')

nframes = 240

average_frame = imageseries.stats.average(img_series)

#%%
wlen = constants.keVToAngstrom(instr_cfg['beam']['energy'])

matl = make_matl('LSHR', 225, [3.5905,])

pd = matl.planeData
pd.wavelength = instr_cfg['beam']['energy'] # takes keV
pd.exclusions = np.zeros_like(pd.exclusions, dtype=bool)

set_by_tth_max = False
if set_by_tth_max:
    pd.tThMax = np.radians(6.75)
    tth_del = np.radians(0.75)
    tth_avg = np.average(pd.getTTh())
    tth_lo = pd.getTTh()[0] - tth_del
    tth_hi = pd.getTTh()[-1] + tth_del
else:
Example #11
0
    def simulate_laue_pattern(self, crystal_data,
                              minEnergy=5., maxEnergy=35.,
                              rmat_s=None, tvec_s=None,
                              grain_params=None,
                              beam_vec=None):
        """
        """
        if isinstance(crystal_data, PlaneData):

            plane_data = crystal_data

            # grab the expanded list of hkls from plane_data
            hkls = np.hstack(plane_data.getSymHKLs())

            # and the unit plane normals (G-vectors) in CRYSTAL FRAME
            gvec_c = np.dot(plane_data.latVecOps['B'], hkls)
        elif len(crystal_data) == 2:
            # !!! should clean this up
            hkls = np.array(crystal_data[0])
            bmat = crystal_data[1]
            gvec_c = np.dot(bmat, hkls)
        else:
            raise(RuntimeError, 'argument list not understood')
        nhkls_tot = hkls.shape[1]

        # parse energy ranges
        # TODO: allow for spectrum parsing
        multipleEnergyRanges = False
        if hasattr(maxEnergy, '__len__'):
            assert len(maxEnergy) == len(minEnergy), \
                'energy cutoff ranges must have the same length'
            multipleEnergyRanges = True
            lmin = []
            lmax = []
            for i in range(len(maxEnergy)):
                lmin.append(ct.keVToAngstrom(maxEnergy[i]))
                lmax.append(ct.keVToAngstrom(minEnergy[i]))
        else:
            lmin = ct.keVToAngstrom(maxEnergy)
            lmax = ct.keVToAngstrom(minEnergy)

        # parse grain parameters kwarg
        if grain_params is None:
            grain_params = np.atleast_2d(
                np.hstack([np.zeros(6), ct.identity_6x1])
            )
        n_grains = len(grain_params)

        # sample rotation
        if rmat_s is None:
            rmat_s = ct.identity_3x3

        # dummy translation vector... make input
        if tvec_s is None:
            tvec_s = ct.zeros_3

        # beam vector
        if beam_vec is None:
            beam_vec = ct.beam_vec

        # =========================================================================
        # LOOP OVER GRAINS
        # =========================================================================

        # pre-allocate output arrays
        xy_det = np.nan*np.ones((n_grains, nhkls_tot, 2))
        hkls_in = np.nan*np.ones((n_grains, 3, nhkls_tot))
        angles = np.nan*np.ones((n_grains, nhkls_tot, 2))
        dspacing = np.nan*np.ones((n_grains, nhkls_tot))
        energy = np.nan*np.ones((n_grains, nhkls_tot))
        for iG, gp in enumerate(grain_params):
            rmat_c = makeRotMatOfExpMap(gp[:3])
            tvec_c = gp[3:6].reshape(3, 1)
            vInv_s = mutil.vecMVToSymm(gp[6:].reshape(6, 1))

            # stretch them: V^(-1) * R * Gc
            gvec_s_str = np.dot(vInv_s, np.dot(rmat_c, gvec_c))
            ghat_c_str = mutil.unitVector(np.dot(rmat_c.T, gvec_s_str))

            # project
            dpts = gvecToDetectorXY(ghat_c_str.T,
                                    self.rmat, rmat_s, rmat_c,
                                    self.tvec, tvec_s, tvec_c,
                                    beamVec=beam_vec)

            # check intersections with detector plane
            canIntersect = ~np.isnan(dpts[:, 0])
            npts_in = sum(canIntersect)

            if np.any(canIntersect):
                dpts = dpts[canIntersect, :].reshape(npts_in, 2)
                dhkl = hkls[:, canIntersect].reshape(3, npts_in)

                # back to angles
                tth_eta, gvec_l = detectorXYToGvec(
                    dpts,
                    self.rmat, rmat_s,
                    self.tvec, tvec_s, tvec_c,
                    beamVec=beam_vec)
                tth_eta = np.vstack(tth_eta).T

                # warp measured points
                if self.distortion is not None:
                    if len(self.distortion) == 2:
                        dpts = self.distortion[0](
                            dpts, self.distortion[1],
                            invert=True)
                    else:
                        raise(RuntimeError,
                              "something is wrong with the distortion")

                # plane spacings and energies
                dsp = 1. / rowNorm(gvec_s_str[:, canIntersect].T)
                wlen = 2*dsp*np.sin(0.5*tth_eta[:, 0])

                # clip to detector panel
                _, on_panel = self.clip_to_panel(dpts, buffer_edges=True)

                if multipleEnergyRanges:
                    validEnergy = np.zeros(len(wlen), dtype=bool)
                    for i in range(len(lmin)):
                        in_energy_range = np.logical_and(
                                wlen >= lmin[i],
                                wlen <= lmax[i])
                        validEnergy = validEnergy | in_energy_range
                        pass
                else:
                    validEnergy = np.logical_and(wlen >= lmin, wlen <= lmax)
                    pass

                # index for valid reflections
                keepers = np.where(np.logical_and(on_panel, validEnergy))[0]

                # assign output arrays
                xy_det[iG][keepers, :] = dpts[keepers, :]
                hkls_in[iG][:, keepers] = dhkl[:, keepers]
                angles[iG][keepers, :] = tth_eta[keepers, :]
                dspacing[iG, keepers] = dsp[keepers]
                energy[iG, keepers] = ct.keVToAngstrom(wlen[keepers])
                pass    # close conditional on valids
            pass    # close loop on grains
        return xy_det, hkls_in, angles, dspacing, energy
Example #12
0
    def simulate_rotation_series(self, plane_data, grain_param_list,
                                 eta_ranges=[(-np.pi, np.pi), ],
                                 ome_ranges=[(-np.pi, np.pi), ],
                                 ome_period=(-np.pi, np.pi),
                                 chi=0., tVec_s=ct.zeros_3,
                                 wavelength=None):
        """
        """

        # grab B-matrix from plane data
        bMat = plane_data.latVecOps['B']

        # reconcile wavelength
        #   * added sanity check on exclusions here; possible to
        #   * make some reflections invalid (NaN)
        if wavelength is None:
            wavelength = plane_data.wavelength
        else:
            if plane_data.wavelength != wavelength:
                plane_data.wavelength = ct.keVToAngstrom(wavelength)
        assert not np.any(np.isnan(plane_data.getTTh())),\
            "plane data exclusions incompatible with wavelength"

        # vstacked G-vector id, h, k, l
        full_hkls = xrdutil._fetch_hkls_from_planedata(plane_data)

        """ LOOP OVER GRAINS """
        valid_ids = []
        valid_hkls = []
        valid_angs = []
        valid_xys = []
        ang_pixel_size = []
        for gparm in grain_param_list:

            # make useful parameters
            rMat_c = makeRotMatOfExpMap(gparm[:3])
            tVec_c = gparm[3:6]
            vInv_s = gparm[6:]

            # All possible bragg conditions as vstacked [tth, eta, ome]
            # for each omega solution
            angList = np.vstack(
                oscillAnglesOfHKLs(
                    full_hkls[:, 1:], chi,
                    rMat_c, bMat, wavelength,
                    vInv=vInv_s,
                    )
                )

            # filter by eta and omega ranges
            # ??? get eta range from detector?
            allAngs, allHKLs = xrdutil._filter_hkls_eta_ome(
                full_hkls, angList, eta_ranges, ome_ranges
                )
            allAngs[:, 2] = mapAngle(allAngs[:, 2], ome_period)

            # find points that fall on the panel
            det_xy, rMat_s = xrdutil._project_on_detector_plane(
                allAngs,
                self.rmat, rMat_c, chi,
                self.tvec, tVec_c, tVec_s,
                self.distortion)
            xys_p, on_panel = self.clip_to_panel(det_xy)
            valid_xys.append(xys_p)

            # grab hkls and gvec ids for this panel
            valid_hkls.append(allHKLs[on_panel, 1:])
            valid_ids.append(allHKLs[on_panel, 0])

            # reflection angles (voxel centers) and pixel size in (tth, eta)
            valid_angs.append(allAngs[on_panel, :])
            ang_pixel_size.append(self.angularPixelSize(xys_p))
        return valid_ids, valid_hkls, valid_angs, valid_xys, ang_pixel_size
Example #13
0
 def beam_energy(self):
     return keVToAngstrom(self.plane_data.wavelength)
Example #14
0
instr_cfg_file = open('./ge_detector_new.yml', 'r')
instr_cfg = yaml.load(instr_cfg_file)
instr = instrument.HEDMInstrument(instr_cfg)

data_path = './'
img_series_root = 'ge_scan_114'
img_series = imageseries.open(
    os.path.join(img_series_root + '-fcache-dir',
                 img_series_root + '-fcache.yml'), 'frame-cache')

nframes = 240

average_frame = imageseries.stats.average(img_series)

#%%
wlen = constants.keVToAngstrom(instr_cfg['beam']['energy'])

matl = make_matl('LSHR', 225, [
    3.5905,
])

pd = matl.planeData
pd.wavelength = instr_cfg['beam']['energy']  # takes keV
pd.exclusions = np.zeros_like(pd.exclusions, dtype=bool)

set_by_tth_max = False
if set_by_tth_max:
    pd.tThMax = np.radians(6.75)
    tth_del = np.radians(0.75)
    tth_avg = np.average(pd.getTTh())
    tth_lo = pd.getTTh()[0] - tth_del