def contained_in_sst(vectors, vertices_ccw):
    """
    checks hstack array of unit vectors

    !!! inputs must both be unit vectors
    !!! vertices must be CCW
    """
    # column-wise normals to the spherical triangle edges
    sst_normals = np.array([
        np.cross(vertices_ccw[:, i[0]], vertices_ccw[:, i[1]])
        for i in [(0, 1), (1, 2), (2, 0)]
    ]).T
    sst_normals_unit = mutil.unitVector(sst_normals)

    angles = np.arcsin(mutil.columnNorm(sst_normals))
    edges = []
    for i, ang in enumerate(angles):
        sub_ang = np.linspace(0, ang, endpoint=True)
        for j in sub_ang:
            rm = rot.rotMatOfExpMap(j * sst_normals_unit[:, i].reshape(3, 1))
            edges.append(np.dot(vertices_ccw[:, i], rm.T))
        edges.append(np.nan * np.ones(3))

    dim, n = vectors.shape
    contained = []
    for v in vectors.T:
        d0 = np.dot(sst_normals_unit[:, 0], v)
        d1 = np.dot(sst_normals_unit[:, 1], v)
        d2 = np.dot(sst_normals_unit[:, 2], v)
        contained.append(np.all([d0 > 0, d1 > 0, d2 > 0]))
    return contained, np.vstack(edges)
def post_process_stress(grain_data, c_mat_C, schmid_T_list=None):
    num_grains = grain_data.shape[0]

    stress_S = np.zeros([num_grains, 6])
    stress_C = np.zeros([num_grains, 6])
    hydrostatic = np.zeros([num_grains, 1])
    pressure = np.zeros([num_grains, 1])
    von_mises = np.zeros([num_grains, 1])

    if schmid_T_list is not None:
        num_slip_systems = schmid_T_list.shape[0]
        RSS = np.zeros([num_grains, num_slip_systems])

    for jj in np.arange(num_grains):

        expMap = np.atleast_2d(grain_data[jj, 3:6]).T
        strainTmp = np.atleast_2d(grain_data[jj, 15:21]).T

        #Turn exponential map into an orientation matrix
        Rsc = rot.rotMatOfExpMap(expMap)

        strainTenS = np.zeros((3, 3), dtype='float64')
        strainTenS[0, 0] = strainTmp[0]
        strainTenS[1, 1] = strainTmp[1]
        strainTenS[2, 2] = strainTmp[2]
        strainTenS[1, 2] = strainTmp[3]
        strainTenS[0, 2] = strainTmp[4]
        strainTenS[0, 1] = strainTmp[5]
        strainTenS[2, 1] = strainTmp[3]
        strainTenS[2, 0] = strainTmp[4]
        strainTenS[1, 0] = strainTmp[5]

        strainTenC = np.dot(np.dot(Rsc.T, strainTenS), Rsc)
        strainVecC = mutil.strainTenToVec(strainTenC)

        #Calculate stress
        stressVecC = np.dot(c_mat_C, strainVecC)
        stressTenC = mutil.stressVecToTen(stressVecC)
        stressTenS = np.dot(np.dot(Rsc, stressTenC), Rsc.T)
        stressVecS = mutil.stressTenToVec(stressTenS)

        #Calculate hydrostatic stress
        hydrostaticStress = (stressVecS[:3].sum() / 3)

        #Calculate Von Mises Stress
        devStressS = stressTenS - hydrostaticStress * np.identity(3)
        vonMisesStress = np.sqrt((3 / 2) * (devStressS**2).sum())

        #Project on to slip systems
        if schmid_T_list is not None:
            for ii in np.arange(num_slip_systems):
                RSS[jj, ii] = np.abs(
                    (stressTenC * schmid_T_list[ii, :, :]).sum())

        stress_S[jj, :] = stressVecS.flatten()
        stress_C[jj, :] = stressVecC.flatten()

        hydrostatic[jj, 0] = hydrostaticStress
        pressure[jj, 0] = -hydrostaticStress
        von_mises[jj, 0] = vonMisesStress

    stress_data = dict()

    stress_data['stress_S'] = stress_S
    stress_data['stress_C'] = stress_C
    stress_data['hydrostatic'] = hydrostatic
    stress_data['pressure'] = pressure
    stress_data['von_mises'] = von_mises

    if schmid_T_list is not None:
        stress_data['RSS'] = RSS

    return stress_data
quats_final = rot.quatOfExpMap(
    (grain_data['scan%d' % no_load_scans[-1]][:, 3:6].T))

expmaps_final = grain_data['scan111'][:, 3:6].T

grainlist = []
for i in range(ngrains):
    mis = rot.misorientation(quats_init[:, i:i + 1], quats_final[:, i:i + 1],
                             (crystal_symmetry, ))[0]
    mis_deg = np.degrees(mis)
    if mis_deg > 0.05:
        grainlist.append(i)

#%%
rmats_init = rot.rotMatOfExpMap(np.array(expmaps_init)[:, grainlist])
rmats_final = rot.rotMatOfExpMap(np.array(expmaps_final)[:, grainlist])

# getting symmetry group directly here; could also grab from planeData object
# qsym = symm.quatOfLaueGroup('d6h')
plane_data = load_pdata(
    '/Users/rachellim/Documents/Research/CHESS_Jun17/2020-08-03/materials2.hexrd',
    'ti7al')
qsym = plane_data.getQSym()
bmat = plane_data.latVecOps['B']

# this was for 001 triangle
# sst_vertices = mutil.unitVector(matfuncs.triu(np.ones((3, 3))).T)
# this if for the standard triangle
# sst_vertices = mutil.unitVector(matfuncs.triu(np.ones((3, 3))))
sst_vertices = mutil.unitVector(
示例#4
0
def getFriedelPair(tth0, eta0, *ome0, **kwargs):
    """
    Get the diffractometer angular coordinates in degrees for
    the Friedel pair of a given reflection (min angular distance).

    AUTHORS:

    J. V. Bernier -- 10 Nov 2009

    USAGE:

    ome1, eta1 = getFriedelPair(tth0, eta0, *ome0,
                                display=False,
                                units='degrees',
                                convention='hexrd')

    INPUTS:

    1) tth0 is a list (or ndarray) of 1 or n the bragg angles (2theta) for
       the n reflections (tiled to match eta0 if only 1 is given).

    2) eta0 is a list (or ndarray) of 1 or n azimuthal coordinates for the n
       reflections  (tiled to match tth0 if only 1 is given).

    3) ome0 is a list (or ndarray) of 1 or n reference oscillation
       angles for the n reflections (denoted omega in [1]).  This argument
       is optional.

    4) Keyword arguments may be one of the following:

    Keyword             Values|{default}        Action
    --------------      --------------          --------------
    'display'           True|{False}            toggles display info to cmd line
    'units'             'radians'|{'degrees'}   sets units for input angles
    'convention'        'fable'|{'hexrd'}         sets conventions defining
                                                the angles (see below)
    'chiTilt'           None                    the inclination (about Xlab) of
                                                the oscillation axis

    OUTPUTS:

    1) ome1 contains the oscialltion angle coordinates of the
       Friedel pairs associated with the n input reflections, relative to ome0
       (i.e. ome1 = <result> + ome0).  Output is in DEGREES!

    2) eta1 contains the azimuthal coordinates of the Friedel
       pairs associated with the n input reflections.  Output units are
       controlled via the module variable 'outputDegrees'

    NOTES:

    JVB) The ouputs ome1, eta1 are written using the selected convention, but the
         units are alway degrees.  May change this to work with Nathan's global...

    JVB) In the 'fable' convention [1], {XYZ} form a RHON basis where X is
         downstream, Z is vertical, and eta is CCW with +Z defining eta = 0.

    JVB) In the 'hexrd' convention [2], {XYZ} form a RHON basis where Z is upstream,
         Y is vertical, and eta is CCW with +X defining eta = 0.

    REFERENCES:

    [1] E. M. Lauridsen, S. Schmidt, R. M. Suter, and H. F. Poulsen,
        ``Tracking: a method for structural characterization of grains in
        powders or polycrystals''. J. Appl. Cryst. (2001). 34, 744--750

    [2] J. V. Bernier, M. P. Miller, J. -S. Park, and U. Lienert,
        ``Quantitative Stress Analysis of Recrystallized OFHC Cu Subject
        to Deformed In Situ'', J. Eng. Mater. Technol. (2008). 130.
        DOI:10.1115/1.2870234
    """

    dispFlag = False
    fableFlag = False
    chi = None
    c1 = 1.0
    c2 = pi / 180.0
    zTol = 1.0e-7

    # cast to arrays (in case they aren't)
    if num.isscalar(eta0):
        eta0 = [eta0]

    if num.isscalar(tth0):
        tth0 = [tth0]

    if num.isscalar(ome0):
        ome0 = [ome0]

    eta0 = num.asarray(eta0)
    tth0 = num.asarray(tth0)
    ome0 = num.asarray(ome0)

    if eta0.ndim != 1:
        raise RuntimeError, "your azimuthal input was not 1-D, so I do not know what you expect me to do"

    npts = len(eta0)

    if tth0.ndim != 1:
        raise RuntimeError, "your Bragg angle input was not 1-D, so I do not know what you expect me to do"
    else:
        if len(tth0) != npts:
            if len(tth0) == 1:
                tth0 = tth0 * num.ones(npts)
            elif npts == 1:
                npts = len(tth0)
                eta0 = eta0 * num.ones(npts)
            else:
                raise RuntimeError, "the azimuthal and Bragg angle inputs are inconsistent"

    if len(ome0) == 0:
        ome0 = num.zeros(npts)  # dummy ome0
    elif len(ome0) == 1 and npts > 1:
        ome0 = ome0 * num.ones(npts)
    else:
        if len(ome0) != npts:
            raise RuntimeError(
                "your oscialltion angle input is inconsistent; "
                + "it has length %d while it should be %d" % (len(ome0), npts)
            )

    # keyword args processing
    kwarglen = len(kwargs)
    if kwarglen > 0:
        argkeys = kwargs.keys()
        for i in range(kwarglen):
            if argkeys[i] == "display":
                dispFlag = kwargs[argkeys[i]]
            elif argkeys[i] == "convention":
                if kwargs[argkeys[i]].lower() == "fable":
                    fableFlag = True
            elif argkeys[i] == "units":
                if kwargs[argkeys[i]] == "radians":
                    c1 = 180.0 / pi
                    c2 = 1.0
            elif argkeys[i] == "chiTilt":
                if kwargs[argkeys[i]] is not None:
                    chi = kwargs[argkeys[i]]

    # a little talkback...
    if dispFlag:
        if fableFlag:
            print "\nUsing Fable angle convention\n"
        else:
            print "\nUsing image-based angle convention\n"

    # mapped eta input
    #   - in DEGREES, thanks to c1
    eta0 = mapAngle(c1 * eta0, [-180, 180], units="degrees")
    if fableFlag:
        eta0 = 90 - eta0

    # must put args into RADIANS
    #   - eta0 is in DEGREES,
    #   - the others are in whatever was entered, hence c2
    eta0 = d2r * eta0
    tht0 = c2 * tth0 / 2
    if chi is not None:
        chi = c2 * chi
    else:
        chi = 0

    # ---------------------
    # SYSTEM SOLVE
    #
    #
    # cos(chi)cos(eta)cos(theta)sin(x) - cos(chi)sin(theta)cos(x) = sin(theta) - sin(chi)sin(eta)cos(theta)
    #
    #
    # Identity: a sin x + b cos x = sqrt(a**2 + b**2) sin (x + alfa)
    #
    #       /
    #       |      atan(b/a) for a > 0
    # alfa <
    #       | pi + atan(b/a) for a < 0
    #       \
    #
    # => sin (x + alfa) = c / sqrt(a**2 + b**2)
    #
    # must use both branches for sin(x) = n: x = u (+ 2k*pi) | x = pi - u (+ 2k*pi)
    #
    cchi = num.cos(chi)
    schi = num.sin(chi)
    ceta = num.cos(eta0)
    seta = num.sin(eta0)
    ctht = num.cos(tht0)
    stht = num.sin(tht0)

    nchi = num.c_[0.0, cchi, schi].T

    gHat0_l = -num.vstack([ceta * ctht, seta * ctht, stht])

    a = cchi * ceta * ctht
    b = -cchi * stht
    c = stht + schi * seta * ctht

    # form solution
    abMag = num.sqrt(a * a + b * b)
    assert num.all(abMag > 0), "Beam vector specification is infeasible!"
    phaseAng = num.arctan2(b, a)
    rhs = c / abMag
    rhs[abs(rhs) > 1.0] = num.nan
    rhsAng = num.arcsin(rhs)

    # write ome angle output arrays (NaNs persist here)
    ome1 = rhsAng - phaseAng
    ome2 = num.pi - rhsAng - phaseAng

    ome1 = mapAngle(ome1, [-num.pi, num.pi], units="radians")
    ome2 = mapAngle(ome2, [-num.pi, num.pi], units="radians")

    ome_stack = num.vstack([ome1, ome2])

    min_idx = num.argmin(abs(ome_stack), axis=0)

    ome_min = ome_stack[min_idx, range(len(ome1))]
    eta_min = num.nan * num.ones_like(ome_min)

    # mark feasible reflections
    goodOnes = -num.isnan(ome_min)

    numGood = sum(goodOnes)
    tmp_eta = num.empty(numGood)
    tmp_gvec = gHat0_l[:, goodOnes]
    for i in range(numGood):
        come = num.cos(ome_min[goodOnes][i])
        some = num.sin(ome_min[goodOnes][i])
        rchi = rotMatOfExpMap(num.tile(ome_min[goodOnes][i], (3, 1)) * nchi)
        gHat_l = num.dot(rchi, tmp_gvec[:, i].reshape(3, 1))
        tmp_eta[i] = num.arctan2(gHat_l[1], gHat_l[0])
        pass
    eta_min[goodOnes] = tmp_eta

    # everybody back to DEGREES!
    #     - ome1 is in RADIANS here
    #     - convert and put into [-180, 180]
    ome1 = mapAngle(mapAngle(r2d * ome_min, [-180, 180], units="degrees") + c1 * ome0, [-180, 180], units="degrees")

    # put eta1 in [-180, 180]
    eta1 = mapAngle(r2d * eta_min, [-180, 180], units="degrees")

    if not outputDegrees:
        ome1 = d2r * ome1
        eta1 = d2r * eta1

    return ome1, eta1
示例#5
0
文件: indexer.py 项目: B-Rich/hexrd
from hexrd.xrd import transforms      as xf
from hexrd.xrd import transforms_CAPI as xfcapi

if xrdbase.haveMultiProc:
    multiprocessing = xrdbase.multiprocessing # formerly import

# module vars
piby2 = num.pi * 0.5
r2d = 180. / num.pi
d2r = num.pi / 180.

Xl = num.c_[1, 0, 0].T
Yl = num.c_[0, 1, 0].T
Zl = num.c_[0, 0, 1].T

fableSampCOB = num.dot( rotMatOfExpMap(piby2*Zl),
                        rotMatOfExpMap(piby2*Yl) )

# global vars for multiproc paintGrid method
planeData_MP  = None
omeMin_MP     = None
omeMax_MP     = None
etaMin_MP     = None
etaMax_MP     = None
hklList_MP    = None
hklIDs_MP     = None
etaOmeMaps_MP = None
bMat_MP       = None
threshold_MP  = None

class GrainSpotter:
示例#6
0
from hexrd.xrd.symmetry import toFundamentalRegion
from hexrd.xrd import xrdbase

if xrdbase.haveMultiProc:
    multiprocessing = xrdbase.multiprocessing  # formerly import

# module vars
piby2 = num.pi * 0.5
r2d = 180. / num.pi
d2r = num.pi / 180.

Xl = num.c_[1, 0, 0].T
Yl = num.c_[0, 1, 0].T
Zl = num.c_[0, 0, 1].T

fableSampCOB = num.dot(rotMatOfExpMap(piby2 * Zl), rotMatOfExpMap(piby2 * Yl))

# global vars for multiproc paintGrid method
planeData_MP = None
omeMin_MP = None
omeMax_MP = None
etaMin_MP = None
etaMax_MP = None
hklList_MP = None
hklIDs_MP = None
etaOmeMaps_MP = None
bMat_MP = None
threshold_MP = None


class GrainSpotter:
示例#7
0
from hexrd import matrixutil as mutil
from hexrd.xrd import rotations as rot
from hexrd.xrd.transforms import detectorXYToGvec

d2r = np.pi / 180.
r2d = 180. / np.pi

Xl = np.c_[1, 0, 0].T
Yl = np.c_[0, 1, 0].T
Zl = np.c_[0, 0, 1].T

eVec = Xl.flatten()

chi_b = 15
ome_b = 5
rMat_b = np.dot(rot.rotMatOfExpMap(d2r * chi_b * Xl),
                rot.rotMatOfExpMap(d2r * ome_b * Yl))
bVec = np.dot(rMat_b, -Zl)
beam_len = 10

tVec_d = np.c_[-5.0, 3.0, -10.0].T
tVec_s = np.c_[3.0, 0.2, -1.5].T
tVec_c = np.c_[2.0, 0.8, -0.7].T

rMat_d = rot.rotMatOfExpMap(d2r * 21 * mutil.unitVector(np.c_[2, 3, 1].T))

chi = 21 * d2r
ome = 67 * d2r
rMat_s = np.dot(rot.rotMatOfExpMap(chi * Xl), rot.rotMatOfExpMap(ome * Yl))

rMat_c = rot.rotMatOfExpMap(d2r * 36 * mutil.unitVector(np.c_[1, 2, 3].T))
示例#8
0
def gen_trial_exp_data(grain_out_file,det_file,mat_file, x_ray_energy, mat_name, max_tth, comp_thresh, chi2_thresh, misorientation_bnd, \
                       misorientation_spacing,ome_range_deg, nframes, beam_stop_width):

    print('Loading Grain Data.....')
    #gen_grain_data
    ff_data = np.loadtxt(grain_out_file)

    #ff_data=np.atleast_2d(ff_data[2,:])

    exp_maps = ff_data[:, 3:6]
    t_vec_ds = ff_data[:, 6:9]

    #
    completeness = ff_data[:, 1]

    chi2 = ff_data[:, 2]

    n_grains = exp_maps.shape[0]

    rMat_c = rot.rotMatOfExpMap(exp_maps.T)

    cut = np.where(
        np.logical_and(completeness > comp_thresh, chi2 < chi2_thresh))[0]
    exp_maps = exp_maps[cut, :]
    t_vec_ds = t_vec_ds[cut, :]
    chi2 = chi2[cut]

    # Add Misorientation
    mis_amt = misorientation_bnd * np.pi / 180.
    spacing = misorientation_spacing * np.pi / 180.

    mis_steps = int(misorientation_bnd / misorientation_spacing)

    ori_pts = np.arange(-mis_amt, (mis_amt + (spacing * 0.999)), spacing)
    num_ori_grid_pts = ori_pts.shape[0]**3
    num_oris = exp_maps.shape[0]

    XsO, YsO, ZsO = np.meshgrid(ori_pts, ori_pts, ori_pts)

    grid0 = np.vstack([XsO.flatten(), YsO.flatten(), ZsO.flatten()]).T

    exp_maps_expanded = np.zeros([num_ori_grid_pts * num_oris, 3])
    t_vec_ds_expanded = np.zeros([num_ori_grid_pts * num_oris, 3])

    for ii in np.arange(num_oris):
        pts_to_use = np.arange(num_ori_grid_pts) + ii * num_ori_grid_pts
        exp_maps_expanded[pts_to_use, :] = grid0 + np.r_[exp_maps[ii, :]]
        t_vec_ds_expanded[pts_to_use, :] = np.r_[t_vec_ds[ii, :]]

    exp_maps = exp_maps_expanded
    t_vec_ds = t_vec_ds_expanded

    n_grains = exp_maps.shape[0]

    rMat_c = rot.rotMatOfExpMap(exp_maps.T)

    print('Loading Instrument Data.....')
    instr_cfg = yaml.load(open(det_file, 'r'))

    tiltAngles = instr_cfg['detector']['transform']['tilt_angles']
    tVec_d = np.array(instr_cfg['detector']['transform']['t_vec_d']).reshape(
        3, 1)
    #tVec_d[0] = -0.05
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.array(instr_cfg['oscillation_stage']['t_vec_s']).reshape(3, 1)

    rMat_d = makeDetectorRotMat(tiltAngles)
    rMat_s = makeOscillRotMat([chi, 0.])

    pixel_size = instr_cfg['detector']['pixels']['size']

    nrows = instr_cfg['detector']['pixels']['rows']
    ncols = instr_cfg['detector']['pixels']['columns']

    #    row_dim = pixel_size[0]*nrows # in mm
    #    col_dim = pixel_size[1]*ncols # in mm

    x_col_edges = pixel_size[1] * (np.arange(ncols + 1) - 0.5 * ncols)
    y_row_edges = pixel_size[0] * (np.arange(nrows + 1) - 0.5 * nrows)[::-1]

    panel_dims = [(-0.5 * ncols * pixel_size[1], -0.5 * nrows * pixel_size[0]),
                  (0.5 * ncols * pixel_size[1], 0.5 * nrows * pixel_size[0])]

    # a bit overkill, but grab max two-theta from all pixel transforms
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)
    gcrds = detectorXYToGvec(
        np.vstack([rx.flatten(), ry.flatten()]).T, rMat_d, rMat_s, tVec_d,
        tVec_s, np.zeros(3))
    pixel_tth = gcrds[0][0]

    detector_params = np.hstack(
        [tiltAngles, tVec_d.flatten(), chi,
         tVec_s.flatten()])

    ome_period_deg = (ome_range_deg[0][0], (ome_range_deg[0][0] + 360.)
                      )  #degrees
    ome_step_deg = (ome_range_deg[0][1] -
                    ome_range_deg[0][0]) / nframes  #degrees

    ome_period = (ome_period_deg[0] * np.pi / 180.,
                  ome_period_deg[1] * np.pi / 180.)
    ome_range = [(ome_range_deg[0][0] * np.pi / 180.,
                  ome_range_deg[0][1] * np.pi / 180.)]
    ome_step = ome_step_deg * np.pi / 180.

    ome_edges = np.arange(nframes +
                          1) * ome_step + ome_range[0][0]  #fixed 2/26/17

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

    print('Loading Material Data.....')
    #Load Material Data
    materials = cpl.load(open(mat_file, "rb"))

    check = np.zeros(len(materials))
    for ii in np.arange(len(materials)):
        #print materials[ii].name
        check[ii] = materials[ii].name == mat_name

    mat_used = materials[np.where(check)[0][0]]

    #niti_mart.beamEnergy = valunits.valWUnit("wavelength","ENERGY",61.332,"keV")
    mat_used.beamEnergy = valunits.valWUnit("wavelength", "ENERGY",
                                            x_ray_energy, "keV")
    mat_used.planeData.exclusions = np.zeros(len(
        mat_used.planeData.exclusions),
                                             dtype=bool)

    if max_tth > 0.:
        mat_used.planeData.tThMax = np.amax(np.radians(max_tth))
    else:
        mat_used.planeData.tThMax = np.amax(pixel_tth)

    pd = mat_used.planeData

    print('Final Assembly.....')
    experiment = argparse.Namespace()
    # grains related information
    experiment.n_grains = n_grains  # this can be derived from other values...
    experiment.rMat_c = rMat_c  # n_grains rotation matrices (one per grain)
    experiment.exp_maps = exp_maps  # n_grains exp_maps -angle * rotation axis- (one per grain)

    experiment.plane_data = pd
    experiment.detector_params = detector_params
    experiment.pixel_size = pixel_size
    experiment.ome_range = ome_range
    experiment.ome_period = ome_period
    experiment.x_col_edges = x_col_edges
    experiment.y_row_edges = y_row_edges
    experiment.ome_edges = ome_edges
    experiment.ncols = ncols
    experiment.nrows = nrows
    experiment.nframes = nframes  # used only in simulate...
    experiment.rMat_d = rMat_d
    experiment.tVec_d = np.atleast_2d(detector_params[3:6]).T
    experiment.chi = detector_params[
        6]  # note this is used to compute S... why is it needed?
    experiment.tVec_s = np.atleast_2d(detector_params[7:]).T
    experiment.rMat_c = rMat_c
    experiment.distortion = None
    experiment.panel_dims = panel_dims  # used only in simulate...
    experiment.base = base
    experiment.inv_deltas = inv_deltas
    experiment.clip_vals = clip_vals
    experiment.bsw = beam_stop_width

    if mis_steps == 0:
        nf_to_ff_id_map = cut
    else:
        nf_to_ff_id_map = np.tile(cut, 27 * mis_steps)

    return experiment, nf_to_ff_id_map
示例#9
0
def getFriedelPair(tth0, eta0, *ome0, **kwargs):
    """
    Get the diffractometer angular coordinates in degrees for
    the Friedel pair of a given reflection (min angular distance).

    AUTHORS:

    J. V. Bernier -- 10 Nov 2009

    USAGE:

    ome1, eta1 = getFriedelPair(tth0, eta0, *ome0,
                                display=False,
                                units='degrees',
                                convention='hexrd')

    INPUTS:

    1) tth0 is a list (or ndarray) of 1 or n the bragg angles (2theta) for
       the n reflections (tiled to match eta0 if only 1 is given).

    2) eta0 is a list (or ndarray) of 1 or n azimuthal coordinates for the n
       reflections  (tiled to match tth0 if only 1 is given).

    3) ome0 is a list (or ndarray) of 1 or n reference oscillation
       angles for the n reflections (denoted omega in [1]).  This argument
       is optional.

    4) Keyword arguments may be one of the following:

    Keyword             Values|{default}        Action
    --------------      --------------          --------------
    'display'           True|{False}            toggles display info to cmd line
    'units'             'radians'|{'degrees'}   sets units for input angles
    'convention'        'fable'|{'hexrd'}         sets conventions defining
                                                the angles (see below)
    'chiTilt'           None                    the inclination (about Xlab) of
                                                the oscillation axis

    OUTPUTS:

    1) ome1 contains the oscialltion angle coordinates of the
       Friedel pairs associated with the n input reflections, relative to ome0
       (i.e. ome1 = <result> + ome0).  Output is in DEGREES!

    2) eta1 contains the azimuthal coordinates of the Friedel
       pairs associated with the n input reflections.  Output units are
       controlled via the module variable 'outputDegrees'

    NOTES:

    JVB) The ouputs ome1, eta1 are written using the selected convention, but the
         units are alway degrees.  May change this to work with Nathan's global...

    JVB) In the 'fable' convention [1], {XYZ} form a RHON basis where X is
         downstream, Z is vertical, and eta is CCW with +Z defining eta = 0.

    JVB) In the 'hexrd' convention [2], {XYZ} form a RHON basis where Z is upstream,
         Y is vertical, and eta is CCW with +X defining eta = 0.

    REFERENCES:

    [1] E. M. Lauridsen, S. Schmidt, R. M. Suter, and H. F. Poulsen,
        ``Tracking: a method for structural characterization of grains in
        powders or polycrystals''. J. Appl. Cryst. (2001). 34, 744--750

    [2] J. V. Bernier, M. P. Miller, J. -S. Park, and U. Lienert,
        ``Quantitative Stress Analysis of Recrystallized OFHC Cu Subject
        to Deformed In Situ'', J. Eng. Mater. Technol. (2008). 130.
        DOI:10.1115/1.2870234
    """

    dispFlag  = False
    fableFlag = False
    chi       = None
    c1        = 1.
    c2        = pi/180.
    zTol      = 1.e-7

    # cast to arrays (in case they aren't)
    if num.isscalar(eta0):
        eta0 = [eta0]

    if num.isscalar(tth0):
        tth0 = [tth0]

    if num.isscalar(ome0):
        ome0 = [ome0]

    eta0 = num.asarray(eta0)
    tth0 = num.asarray(tth0)
    ome0 = num.asarray(ome0)

    if eta0.ndim != 1:
        raise RuntimeError, 'your azimuthal input was not 1-D, so I do not know what you expect me to do'

    npts = len(eta0)

    if tth0.ndim != 1:
        raise RuntimeError, 'your Bragg angle input was not 1-D, so I do not know what you expect me to do'
    else:
        if len(tth0) != npts:
            if len(tth0) == 1:
                tth0 = tth0*num.ones(npts)
            elif npts == 1:
                npts = len(tth0)
                eta0 = eta0*num.ones(npts)
            else:
                raise RuntimeError, 'the azimuthal and Bragg angle inputs are inconsistent'

    if len(ome0) == 0:
        ome0 = num.zeros(npts)                  # dummy ome0
    elif len(ome0) == 1 and npts > 1:
        ome0 = ome0*num.ones(npts)
    else:
        if len(ome0) != npts:
            raise RuntimeError('your oscialltion angle input is inconsistent; ' \
                               + 'it has length %d while it should be %d' % (len(ome0), npts) )

    # keyword args processing
    kwarglen = len(kwargs)
    if kwarglen > 0:
        argkeys = kwargs.keys()
        for i in range(kwarglen):
            if argkeys[i] == 'display':
                dispFlag = kwargs[argkeys[i]]
            elif argkeys[i] == 'convention':
                if kwargs[argkeys[i]].lower() == 'fable':
                    fableFlag = True
            elif argkeys[i] == 'units':
                if kwargs[argkeys[i]] == 'radians':
                    c1 = 180./pi
                    c2 = 1.
            elif argkeys[i] == 'chiTilt':
                if kwargs[argkeys[i]] is not None:
                    chi = kwargs[argkeys[i]]

    # a little talkback...
    if dispFlag:
        if fableFlag:
            print '\nUsing Fable angle convention\n'
        else:
            print '\nUsing image-based angle convention\n'

    # mapped eta input
    #   - in DEGREES, thanks to c1
    eta0 = mapAngle(c1*eta0, [-180, 180], units='degrees')
    if fableFlag:
        eta0  = 90 - eta0

    # must put args into RADIANS
    #   - eta0 is in DEGREES,
    #   - the others are in whatever was entered, hence c2
    eta0  = d2r*eta0
    tht0  = c2*tth0/2
    if chi is not None:
        chi = c2*chi
    else:
        chi = 0

    # ---------------------
    # SYSTEM SOLVE
    #
    #
    # cos(chi)cos(eta)cos(theta)sin(x) - cos(chi)sin(theta)cos(x) = sin(theta) - sin(chi)sin(eta)cos(theta)
    #
    #
    # Identity: a sin x + b cos x = sqrt(a**2 + b**2) sin (x + alfa)
    #
    #       /
    #       |      atan(b/a) for a > 0
    # alfa <
    #       | pi + atan(b/a) for a < 0
    #       \
    #
    # => sin (x + alfa) = c / sqrt(a**2 + b**2)
    #
    # must use both branches for sin(x) = n: x = u (+ 2k*pi) | x = pi - u (+ 2k*pi)
    #
    cchi = num.cos(chi);     schi = num.sin(chi)
    ceta = num.cos(eta0);    seta = num.sin(eta0)
    ctht = num.cos(tht0);    stht = num.sin(tht0)

    nchi = num.c_[0., cchi, schi].T

    gHat0_l = num.vstack([ceta * ctht,
                          seta * ctht,
                          stht])

    a = cchi*ceta*ctht
    b = cchi*schi*seta*ctht + schi*schi*stht - stht
    c = stht + cchi*schi*seta*ctht + schi*schi*stht

    # form solution
    abMag    = num.sqrt(a*a + b*b); assert num.all(abMag > 0), "Beam vector specification is infealible!"
    phaseAng = num.arctan2(b, a)
    rhs      = c / abMag; rhs[abs(rhs) > 1.] = num.nan
    rhsAng   = num.arcsin(rhs)

    # write ome angle output arrays (NaNs persist here)
    ome1 =          rhsAng - phaseAng
    ome2 = num.pi - rhsAng - phaseAng

    ome1 = mapAngle(ome1, [-num.pi, num.pi], units='radians')
    ome2 = mapAngle(ome2, [-num.pi, num.pi], units='radians')

    ome_stack = num.vstack([ome1, ome2])

    min_idx = num.argmin(abs(ome_stack), axis=0)

    ome_min = ome_stack[min_idx, range(len(ome1))]
    eta_min = num.nan * num.ones_like(ome_min)

    # mark feasible reflections
    goodOnes = -num.isnan(ome_min)

    numGood  = sum(goodOnes)
    tmp_eta  = num.empty(numGood)
    tmp_gvec = gHat0_l[:, goodOnes]
    for i in range(numGood):
        come = num.cos(ome_min[goodOnes][i])
        some = num.sin(ome_min[goodOnes][i])
        rchi = rotMatOfExpMap( num.tile(ome_min[goodOnes][i], (3, 1)) * nchi )
        gHat_l = num.dot(rchi, tmp_gvec[:, i].reshape(3, 1))
        tmp_eta[i] = num.arctan2(gHat_l[1], gHat_l[0])
        pass
    eta_min[goodOnes] = tmp_eta

    # everybody back to DEGREES!
    #     - ome1 is in RADIANS here
    #     - convert and put into [-180, 180]
    ome1 = mapAngle( mapAngle(r2d*ome_min, [-180, 180], units='degrees') + c1*ome0, [-180, 180], units='degrees')

    # put eta1 in [-180, 180]
    eta1 = mapAngle(r2d*eta_min, [-180, 180], units='degrees')

    if not outputDegrees:
        ome1 = d2r * ome1
        eta1 = d2r * eta1

    return ome1, eta1
示例#10
0
def post_process_stress(grain_data,c_mat_C,schmid_T_list=None):
    num_grains=grain_data.shape[0]

    stress_S=np.zeros([num_grains,6])
    stress_C=np.zeros([num_grains,6])
    hydrostatic=np.zeros([num_grains,1])
    pressure=np.zeros([num_grains,1])
    von_mises=np.zeros([num_grains,1])

    if schmid_T_list is not None:
        num_slip_systems=schmid_T_list.shape[0]
        RSS=np.zeros([num_grains,num_slip_systems])


    for jj in np.arange(num_grains):    
    
        expMap=np.atleast_2d(grain_data[jj,3:6]).T    
        strainTmp=np.atleast_2d(grain_data[jj,15:21]).T
        
        #Turn exponential map into an orientation matrix
        Rsc=rot.rotMatOfExpMap(expMap)

        strainTenS = np.zeros((3, 3), dtype='float64')
        strainTenS[0, 0] = strainTmp[0]
        strainTenS[1, 1] = strainTmp[1]
        strainTenS[2, 2] = strainTmp[2]
        strainTenS[1, 2] = strainTmp[3]
        strainTenS[0, 2] = strainTmp[4] 
        strainTenS[0, 1] = strainTmp[5]  
        strainTenS[2, 1] = strainTmp[3] 
        strainTenS[2, 0] = strainTmp[4] 
        strainTenS[1, 0] = strainTmp[5] 

                  
        strainTenC=np.dot(np.dot(Rsc.T,strainTenS),Rsc)
        strainVecC = mutil.strainTenToVec(strainTenC)
        
        
        #Calculate stress        
        stressVecC=np.dot(c_mat_C,strainVecC)
        stressTenC = mutil.stressVecToTen(stressVecC)  
        stressTenS = np.dot(np.dot(Rsc,stressTenC),Rsc.T)
        stressVecS = mutil.stressTenToVec(stressTenS)       
        
        #Calculate hydrostatic stress
        hydrostaticStress=(stressVecS[:3].sum()/3)       
        
        
        #Calculate Von Mises Stress
        devStressS=stressTenS-hydrostaticStress*np.identity(3)        
        vonMisesStress=np.sqrt((3/2)*(devStressS**2).sum())        
        
        
        #Project on to slip systems
        if schmid_T_list is not None:
            for ii in np.arange(num_slip_systems):        
                RSS[jj,ii]=np.abs((stressTenC*schmid_T_list[ii,:,:]).sum())
            
            
        stress_S[jj,:]=stressVecS.flatten()
        stress_C[jj,:]=stressVecC.flatten()
        
        hydrostatic[jj,0]=hydrostaticStress
        pressure[jj,0]=-hydrostaticStress
        von_mises[jj,0]=vonMisesStress
    
    stress_data=dict()    
    
    stress_data['stress_S']=stress_S
    stress_data['stress_C']=stress_C
    stress_data['hydrostatic']=hydrostatic
    stress_data['pressure']=pressure
    stress_data['von_mises']=von_mises
    
    if schmid_T_list is not None:
        stress_data['RSS']=RSS
        
    return stress_data
示例#11
0
文件: nfutil.py 项目: praxes/hexrd
def gen_trial_exp_data(grain_out_file,det_file,mat_file, x_ray_energy, mat_name, max_tth, comp_thresh, chi2_thresh, misorientation_bnd, \
                       misorientation_spacing,ome_range_deg, nframes, beam_stop_width):

    print('Loading Grain Data.....')
    #gen_grain_data
    ff_data=np.loadtxt(grain_out_file)
    
    #ff_data=np.atleast_2d(ff_data[2,:])
    
    exp_maps=ff_data[:,3:6]
    t_vec_ds=ff_data[:,6:9]
    
    
    # 
    completeness=ff_data[:,1]
    
    chi2=ff_data[:,2]
    
    n_grains=exp_maps.shape[0]
    
    rMat_c = rot.rotMatOfExpMap(exp_maps.T)
    
    
    
    
    cut=np.where(np.logical_and(completeness>comp_thresh,chi2<chi2_thresh))[0]
    exp_maps=exp_maps[cut,:]
    t_vec_ds=t_vec_ds[cut,:]
    chi2=chi2[cut]
  
    
    # Add Misorientation
    mis_amt=misorientation_bnd*np.pi/180.
    spacing=misorientation_spacing*np.pi/180.
    
    ori_pts = np.arange(-mis_amt, (mis_amt+(spacing*0.999)),spacing)
    num_ori_grid_pts=ori_pts.shape[0]**3
    num_oris=exp_maps.shape[0]
    
    
    XsO, YsO, ZsO = np.meshgrid(ori_pts, ori_pts, ori_pts)
    
    grid0 = np.vstack([XsO.flatten(), YsO.flatten(), ZsO.flatten()]).T
    
    
    exp_maps_expanded=np.zeros([num_ori_grid_pts*num_oris,3])
    t_vec_ds_expanded=np.zeros([num_ori_grid_pts*num_oris,3])
    
    
    for ii in np.arange(num_oris):
        pts_to_use=np.arange(num_ori_grid_pts)+ii*num_ori_grid_pts  
        exp_maps_expanded[pts_to_use,:]=grid0+np.r_[exp_maps[ii,:] ]
        t_vec_ds_expanded[pts_to_use,:]=np.r_[t_vec_ds[ii,:] ]      
    
    
    exp_maps=exp_maps_expanded
    t_vec_ds=t_vec_ds_expanded
    
    n_grains=exp_maps.shape[0]
    
    rMat_c = rot.rotMatOfExpMap(exp_maps.T)
    

    print('Loading Instrument Data.....')
    instr_cfg = yaml.load(open(det_file, 'r'))
    
    tiltAngles = instr_cfg['detector']['transform']['tilt_angles']
    tVec_d = np.array(instr_cfg['detector']['transform']['t_vec_d']).reshape(3, 1)
    #tVec_d[0] = -0.05
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.array(instr_cfg['oscillation_stage']['t_vec_s']).reshape(3, 1)
    
    rMat_d = makeDetectorRotMat(tiltAngles)
    rMat_s = makeOscillRotMat([chi, 0.])
    
    pixel_size = instr_cfg['detector']['pixels']['size']
    
    nrows = instr_cfg['detector']['pixels']['rows']
    ncols = instr_cfg['detector']['pixels']['columns']
    
#    row_dim = pixel_size[0]*nrows # in mm 
#    col_dim = pixel_size[1]*ncols # in mm 
    
    x_col_edges = pixel_size[1]*(np.arange(ncols+1) - 0.5*ncols)
    y_row_edges = pixel_size[0]*(np.arange(nrows+1) - 0.5*nrows)[::-1]
    
    panel_dims = [(-0.5*ncols*pixel_size[1],
                   -0.5*nrows*pixel_size[0]),
                  ( 0.5*ncols*pixel_size[1],
                    0.5*nrows*pixel_size[0])]
    
    # a bit overkill, but grab max two-theta from all pixel transforms
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)
    gcrds = detectorXYToGvec(np.vstack([rx.flatten(), ry.flatten()]).T,
                             rMat_d, rMat_s,
                             tVec_d, tVec_s, np.zeros(3))
    pixel_tth = gcrds[0][0]
    
    detector_params = np.hstack([tiltAngles, tVec_d.flatten(), chi, tVec_s.flatten()])

    
    ome_period_deg=(ome_range_deg[0][0], (ome_range_deg[0][0]+360.)) #degrees 
    ome_step_deg=(ome_range_deg[0][1]-ome_range_deg[0][0])/nframes #degrees 
    
    
    ome_period = (ome_period_deg[0]*np.pi/180.,ome_period_deg[1]*np.pi/180.)
    ome_range = [(ome_range_deg[0][0]*np.pi/180.,ome_range_deg[0][1]*np.pi/180.)]
    ome_step = ome_step_deg*np.pi/180.


    
    ome_edges = np.arange(nframes+1)*ome_step+ome_range[0][0]#fixed 2/26/17
    
    
    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])

    print('Loading Material Data.....')
    #Load Material Data
    materials=cpl.load(open( mat_file, "rb" ))


    check=np.zeros(len(materials))
    for ii in np.arange(len(materials)):
        #print materials[ii].name
        check[ii]=materials[ii].name==mat_name
    
    mat_used=materials[np.where(check)[0][0]]
    
    #niti_mart.beamEnergy = valunits.valWUnit("wavelength","ENERGY",61.332,"keV")
    mat_used.beamEnergy = valunits.valWUnit("wavelength","ENERGY",x_ray_energy,"keV")            
    mat_used.planeData.exclusions = np.zeros(len(mat_used.planeData.exclusions), dtype=bool)
    
    
    if max_tth>0.:
         mat_used.planeData.tThMax = np.amax(np.radians(max_tth))   
    else:
        mat_used.planeData.tThMax = np.amax(pixel_tth)        
    
    pd=mat_used.planeData
    
    
    print('Final Assembly.....')
    experiment = argparse.Namespace()
    # grains related information
    experiment.n_grains = n_grains # this can be derived from other values...
    experiment.rMat_c = rMat_c # n_grains rotation matrices (one per grain)
    experiment.exp_maps = exp_maps # n_grains exp_maps -angle * rotation axis- (one per grain)
    
    experiment.plane_data = pd
    experiment.detector_params = detector_params
    experiment.pixel_size = pixel_size
    experiment.ome_range = ome_range
    experiment.ome_period = ome_period
    experiment.x_col_edges = x_col_edges
    experiment.y_row_edges = y_row_edges
    experiment.ome_edges = ome_edges
    experiment.ncols = ncols
    experiment.nrows = nrows
    experiment.nframes = nframes# used only in simulate...
    experiment.rMat_d = rMat_d
    experiment.tVec_d = np.atleast_2d(detector_params[3:6]).T
    experiment.chi = detector_params[6] # note this is used to compute S... why is it needed?
    experiment.tVec_s = np.atleast_2d(detector_params[7:]).T
    experiment.rMat_c = rMat_c
    experiment.distortion = None
    experiment.panel_dims = panel_dims # used only in simulate...
    experiment.base = base
    experiment.inv_deltas = inv_deltas
    experiment.clip_vals = clip_vals
    experiment.bsw = beam_stop_width  
    
    nf_to_ff_id_map=cut
    
    return experiment, nf_to_ff_id_map
示例#12
0
Eulers_grain = np.zeros([len(scanIDs), 3])

for i in range(len(scanIDs)):

    q108 = rot.quatOfExpMap(grain_data['scan%d' % scanIDs[i]][:, 3:6].T)
    expmaps_grain.append(grain_data['scan%d' % scanIDs[i]][grain, 3:6])
    mis = rot.misorientation(quats_init[:, grain:grain + 1],
                             q108[:, grain:grain + 1], (crystal_symmetry, ))[0]
    mis_ang.append(mis)

    # rotmats_grain.append(rot.rotMatOfExpMap(grain_data['scan%d'%no_load_scans[i]][grain,3:6].T))
    # Eulers_grain[i,:] = rot.angles_from_rmat_zxz(rot.rotMatOfExpMap(expmaps_grain))

mis_ang_deg = np.degrees(np.array(mis_ang))
#%%
rmats = rot.rotMatOfExpMap(np.array(expmaps_grain).T)

# getting symmetry group directly here; could also grab from planeData object
# qsym = symm.quatOfLaueGroup('d6h')
plane_data = load_pdata(
    '/Users/rachellim/Documents/Research/CHESS_Jun17/2020-08-03/materials2.hexrd',
    'ti7al')
qsym = plane_data.getQSym()
bmat = plane_data.latVecOps['B']

# this was for 001 triangle
# sst_vertices = mutil.unitVector(matfuncs.triu(np.ones((3, 3))).T)
# this if for the standard triangle
# sst_vertices = mutil.unitVector(matfuncs.triu(np.ones((3, 3))))
sst_vertices = mutil.unitVector(
    np.dot(bmat,
示例#13
0
    for v in vectors.T:
        d0 = np.dot(sst_normals_unit[:, 0], v)
        d1 = np.dot(sst_normals_unit[:, 1], v)
        d2 = np.dot(sst_normals_unit[:, 2], v)
        contained.append(np.all([d0 > 0, d1 > 0, d2 > 0]))
    return contained, np.vstack(edges)


# =============================================================================
# %% TRANSFORM GRAINS.OUT DATA
# =============================================================================

gt = np.loadtxt(
    '/Users/rachellim/Documents/Research/Dye_CHESS_Jan20/fd1-q-1_filtered/filtered_scan_0067_grains.out',
    ndmin=2)
rmats = rot.rotMatOfExpMap(gt[:, 3:6].T)

# getting symmetry group directly here; could also grab from planeData object
# qsym = symm.quatOfLaueGroup('d6h')
plane_data = load_pdata(
    '/Users/rachellim/Documents/Research/CHESS_Jun17/2020-08-03/materials2.hexrd',
    'ti7al')
qsym = plane_data.getQSym()
bmat = plane_data.latVecOps['B']

# this was for 001 triangle
# sst_vertices = mutil.unitVector(matfuncs.triu(np.ones((3, 3))).T)
# this if for the standard triangle
# sst_vertices = mutil.unitVector(matfuncs.triu(np.ones((3, 3))))
sst_vertices = mutil.unitVector(
    np.dot(bmat,
示例#14
0
from hexrd                import matrixutil as mutil
from hexrd.xrd            import rotations  as rot
from hexrd.xrd.transforms import detectorXYToGvec

d2r = np.pi / 180.
r2d = 180. / np.pi

Xl = np.c_[1, 0, 0].T
Yl = np.c_[0, 1, 0].T
Zl = np.c_[0, 0, 1].T

eVec = Xl.flatten()

chi_b  = 15
ome_b  = 5
rMat_b = np.dot(rot.rotMatOfExpMap(d2r * chi_b * Xl), 
                rot.rotMatOfExpMap(d2r * ome_b * Yl))
bVec   = np.dot(rMat_b, -Zl)
beam_len = 10

tVec_d = np.c_[ -5.0,   3.0, -10.0].T
tVec_s = np.c_[  3.0,   0.2,  -1.5].T
tVec_c = np.c_[  2.0,   0.8,  -0.7].T


rMat_d = rot.rotMatOfExpMap(d2r*21*mutil.unitVector(np.c_[2, 3, 1].T))

chi = 21 * d2r
ome = 67 * d2r
rMat_s = np.dot(rot.rotMatOfExpMap(chi * Xl), 
                rot.rotMatOfExpMap(ome * Yl))