예제 #1
1
파일: indexer.py 프로젝트: B-Rich/hexrd
def convertUToRotMat(Urows, U0, symTag='Oh', display=False):
    """
    Takes GrainSpotter gff ouput in rows

    U11 U12 U13 U21 U22 U23 U13 U23 U33

    and takes it into the hexrd/APS frame of reference

    Urows comes from grainspotter's gff output
    U0 comes from xrd.crystallography.latticeVectors.U0
    """

    numU, testDim = Urows.shape
    assert testDim == 9, "Your input must have 9 columns; yours has %d" % (testDim)

    qin  = quatOfRotMat(Urows.reshape(numU, 3, 3))
    qout = num.dot( quatProductMatrix( quatOfRotMat(fableSampCOB), mult='left' ), \
                    num.dot( quatProductMatrix( quatOfRotMat(U0.T), mult='right'),  \
                             qin ).squeeze() ).squeeze()
    if qout.ndim == 1:
        qout = toFundamentalRegion(qout.reshape(4, 1), crysSym=symTag, sampSym=None)
    else:
        qout = toFundamentalRegion(qout, crysSym=symTag, sampSym=None)
    if display:
        print "quaternions in (Fable convention):"
        print qin.T
        print "quaternions out (hexrd convention, symmetrically reduced)"
        print qout.T
        pass
    Uout = rotMatOfQuat(qout)
    return Uout
예제 #2
0
def get_job_queue(cfg, ids_to_refine=None):
    job_queue = mp.JoinableQueue()
    # load the queue
    try:
        # use an estimate of the grain parameters, if available
        estimate_f = cfg.fit_grains.estimate
        grain_params_list = np.atleast_2d(np.loadtxt(estimate_f))
        n_quats = len(grain_params_list)
        n_jobs = 0
        for grain_params in grain_params_list:
            grain_id = grain_params[0]
            if ids_to_refine is None or grain_id in ids_to_refine:
                job_queue.put((grain_id, grain_params[3:15]))
                n_jobs += 1
        logger.info('fitting grains using "%s" for the initial estimate',
                    estimate_f)
    except (ValueError, IOError):
        # no estimate available, use orientations and defaults
        logger.info('fitting grains using default initial estimate')
        # load quaternion file
        quats = np.atleast_2d(
            np.loadtxt(
                os.path.join(cfg.working_dir, 'accepted_orientations.dat')))
        n_quats = len(quats)
        n_jobs = 0
        phi, n = angleAxisOfRotMat(rotMatOfQuat(quats.T))
        for i, (phi, n) in enumerate(zip(phi, n.T)):
            if ids_to_refine is None or i in ids_to_refine:
                exp_map = phi * n
                grain_params = np.hstack(
                    [exp_map, 0., 0., 0., 1., 1., 1., 0., 0., 0.])
                job_queue.put((i, grain_params))
                n_jobs += 1
    logger.info("fitting grains for %d of %d orientations", n_jobs, n_quats)
    return job_queue, n_jobs
예제 #3
0
파일: indexer.py 프로젝트: B-Rich/hexrd
def convertRotMatToFableU(rMats, U0=num.eye(3), symTag='Oh', display=False):
    """
    Makes GrainSpotter gff ouput

    U11 U12 U13 U21 U22 U23 U13 U23 U33

    and takes it into the hexrd/APS frame of reference

    Urows comes from grainspotter's gff output
    U0 comes from xrd.crystallography.latticeVectors.U0
    """
    numU = num.shape(num.atleast_3d(rMats))[0]

    qin  = quatOfRotMat(num.atleast_3d(rMats))
    qout = num.dot( quatProductMatrix( quatOfRotMat(fableSampCOB.T), mult='left' ), \
                    num.dot( quatProductMatrix( quatOfRotMat(U0), mult='right'),  \
                             qin ).squeeze() ).squeeze()
    if qout.ndim == 1:
        qout = toFundamentalRegion(qout.reshape(4, 1), crysSym=symTag, sampSym=None)
    else:
        qout = toFundamentalRegion(qout, crysSym=symTag, sampSym=None)
    if display:
        print "quaternions in (hexrd convention):"
        print qin.T
        print "quaternions out (Fable convention, symmetrically reduced)"
        print qout.T
        pass
    Uout = rotMatOfQuat(qout)
    return Uout
예제 #4
0
파일: fitgrains.py 프로젝트: ddale/hexrd
def get_job_queue(cfg):
    job_queue = mp.JoinableQueue()
    # load the queue
    try:
        estimate_f = cfg.fit_grains.estimate
        grain_params_list = np.loadtxt(estimate_f)
        n_quats = len(grain_params_list)
        for grain_params in grain_params_list:
            grain_id = grain_params[0]
            job_queue.put((grain_id, grain_params[3:15]))
        logger.info(
            'fitting grains using "%s" for the initial estimate',
            estimate_f
            )
    except (ValueError, IOError):
        logger.info('fitting grains using default initial estimate')
        # load quaternion file
        quats = np.atleast_2d(
            np.loadtxt(os.path.join(cfg.analysis_dir, 'quats.out'))
            )
        n_quats = len(quats)
        quats = quats.T
        phi, n = angleAxisOfRotMat(rotMatOfQuat(quats))
        for i, quat in enumerate(quats.T):
            exp_map = phi[i]*n[:, i]
            grain_params = np.hstack(
                [exp_map.flatten(), 0., 0., 0., 1., 1., 1., 0., 0., 0.]
                )
            job_queue.put((i, grain_params))
    logger.info("fitting grains for %d orientations", n_quats)
    return job_queue
예제 #5
0
def convertUToRotMat(Urows, U0, symTag='Oh', display=False):
    """
    Takes GrainSpotter gff ouput in rows

    U11 U12 U13 U21 U22 U23 U13 U23 U33

    and takes it into the hexrd/APS frame of reference

    Urows comes from grainspotter's gff output
    U0 comes from xrd.crystallography.latticeVectors.U0
    """

    numU, testDim = Urows.shape
    assert testDim == 9, "Your input must have 9 columns; yours has %d" % (
        testDim)

    qin = quatOfRotMat(Urows.reshape(numU, 3, 3))
    qout = num.dot( quatProductMatrix( quatOfRotMat(fableSampCOB), mult='left' ), \
                    num.dot( quatProductMatrix( quatOfRotMat(U0.T), mult='right'),  \
                             qin ).squeeze() ).squeeze()
    if qout.ndim == 1:
        qout = toFundamentalRegion(qout.reshape(4, 1),
                                   crysSym=symTag,
                                   sampSym=None)
    else:
        qout = toFundamentalRegion(qout, crysSym=symTag, sampSym=None)
    if display:
        print "quaternions in (Fable convention):"
        print qin.T
        print "quaternions out (hexrd convention, symmetrically reduced)"
        print qout.T
        pass
    Uout = rotMatOfQuat(qout)
    return Uout
예제 #6
0
def convertRotMatToFableU(rMats, U0=num.eye(3), symTag='Oh', display=False):
    """
    Makes GrainSpotter gff ouput

    U11 U12 U13 U21 U22 U23 U13 U23 U33

    and takes it into the hexrd/APS frame of reference

    Urows comes from grainspotter's gff output
    U0 comes from xrd.crystallography.latticeVectors.U0
    """
    numU = num.shape(num.atleast_3d(rMats))[0]

    qin = quatOfRotMat(num.atleast_3d(rMats))
    qout = num.dot( quatProductMatrix( quatOfRotMat(fableSampCOB.T), mult='left' ), \
                    num.dot( quatProductMatrix( quatOfRotMat(U0), mult='right'),  \
                             qin ).squeeze() ).squeeze()
    if qout.ndim == 1:
        qout = toFundamentalRegion(qout.reshape(4, 1),
                                   crysSym=symTag,
                                   sampSym=None)
    else:
        qout = toFundamentalRegion(qout, crysSym=symTag, sampSym=None)
    if display:
        print "quaternions in (hexrd convention):"
        print qin.T
        print "quaternions out (Fable convention, symmetrically reduced)"
        print qout.T
        pass
    Uout = rotMatOfQuat(qout)
    return Uout
예제 #7
0
def get_job_queue(cfg, ids_to_refine=None):
    job_queue = mp.JoinableQueue()
    # load the queue
    try:
        # use an estimate of the grain parameters, if available
        estimate_f = cfg.fit_grains.estimate
        grain_params_list = np.atleast_2d(np.loadtxt(estimate_f))
        n_quats = len(grain_params_list)
        n_jobs = 0
        for grain_params in grain_params_list:
            grain_id = grain_params[0]
            if ids_to_refine is None or grain_id in ids_to_refine:
                job_queue.put((grain_id, grain_params[3:15]))
                n_jobs += 1
        logger.info(
            'fitting grains using "%s" for the initial estimate',
            estimate_f
            )
    except (ValueError, IOError):
        # no estimate available, use orientations and defaults
        logger.info('fitting grains using default initial estimate')

        # ...make this an attribute in cfg?
        analysis_id = '%s_%s' % (
            cfg.analysis_name.strip().replace(' ', '-'),
            cfg.material.active.strip().replace(' ', '-'),
            )

        # load quaternion file
        quats = np.atleast_2d(
            np.loadtxt(
                os.path.join(
                    cfg.working_dir,
                    'accepted_orientations_%s.dat' % analysis_id
                    )
                )
            )
        n_quats = len(quats)
        n_jobs = 0
        phi, n = angleAxisOfRotMat(rotMatOfQuat(quats.T))
        for i, (phi, n) in enumerate(zip(phi, n.T)):
            if ids_to_refine is None or i in ids_to_refine:
                exp_map = phi*n
                grain_params = np.hstack(
                    [exp_map, 0., 0., 0., 1., 1., 1., 0., 0., 0.]
                    )
                job_queue.put((i, grain_params))
                n_jobs += 1
    logger.info("fitting grains for %d of %d orientations", n_jobs, n_quats)
    return job_queue, n_jobs
예제 #8
0
def testThisQ(thisQ):
    """
    NOTES:
    (*) doFit is not done here -- in multiprocessing, that would end
        up happening on a remote process and then different processes
        would have different data, unless spotsArray were made to be
        fancier

    (*) kludge stuff so that this function is outside of fiberSearch
    """
    global multiProcMode_MP
    global spotsArray_MP
    global candidate_MP
    global dspTol_MP
    global minCompleteness_MP
    global doRefinement_MP
    global nStdDev_MP
    # assign locals
    multiProcMode = multiProcMode_MP
    spotsArray = spotsArray_MP
    candidate = candidate_MP
    dspTol = dspTol_MP
    minCompleteness = minCompleteness_MP
    doRefinement = doRefinement_MP
    nStdDev = nStdDev_MP
    nSigmas = 2  # ... make this a settable option?
    if multiProcMode:
        global foundFlagShared

    foundGrainData = None
    #print "testing %d of %d"% (iR+1, numTrials)
    thisRMat = rotMatOfQuat(thisQ)

    ppfx = ''
    if multiProcMode:
        proc = multiprocessing.current_process()
        ppfx = str(proc.name) + ' : '
        if multiProcMode and foundFlagShared.value:
            """
            map causes this function to be applied to all trial orientations,
            but skip evaluations after an acceptable grain has been found
            """
            if debugMultiproc > 1:
                print ppfx + 'skipping on ' + str(thisQ)
            return foundGrainData
        else:
            if debugMultiproc > 1:
                print ppfx + 'working on  ' + str(thisQ)
            pass
    candidate.findMatches(rMat=thisRMat,
                          strainMag=dspTol,
                          claimingSpots=False,
                          testClaims=True,
                          updateSelf=True)
    if debugMultiproc > 1:
        print ppfx + ' for ' + str(thisQ) + ' got completeness : ' + str(
            candidate.completeness)
    if candidate.completeness >= minCompleteness:
        ## attempt to filter out 'junk' spots here by performing full
        ## refinement before claiming
        fineEtaTol = candidate.etaTol
        fineOmeTol = candidate.omeTol
        if doRefinement:
            if multiProcMode and foundFlagShared.value:
                'some other process beat this one to it'
                return foundGrainData
            print ppfx + "testing candidate q = [%1.2e, %1.2e, %1.2e, %1.2e]" % tuple(
                thisQ)
            # not needed # candidate.fitPrecession(display=False)
            ## first fit
            candidate.fit(display=False)
            ## auto-tolerace based on statistics of current matches
            validRefls = candidate.grainSpots['iRefl'] > 0
            fineEtaTol = nStdDev * num.std(
                candidate.grainSpots['diffAngles'][validRefls, 1])
            fineOmeTol = nStdDev * num.std(
                candidate.grainSpots['diffAngles'][validRefls, 2])
            ## next fits with finer tolerances
            for iLoop in range(3):
                candidate.findMatches(etaTol=fineEtaTol,
                                      omeTol=fineOmeTol,
                                      claimingSpots=False,
                                      testClaims=True,
                                      updateSelf=True)
                # not needed # candidate.fitPrecession(display=False)
                candidate.fit(display=False)
            if candidate.completeness < minCompleteness:
                print ppfx + "candidate failed"
                return foundGrainData
            if multiProcMode and foundFlagShared.value:
                'some other process beat this one to it'
                return foundGrainData
            # not needed # candidate.fitPrecession(display=False)
            # not needed? # candidate.fit(display=False)
            # not needed? # candidate.findMatches(etaTol=fineEtaTol,
            # not needed? #                       omeTol=fineOmeTol,
            # not needed? #                       claimingSpots=False,
            # not needed? #                       testClaims=True,
            # not needed? #                       updateSelf=True)
        else:
            ## at least do precession correction
            candidate.fitPrecession(display=False)
            candidate.findMatches(rMat=thisRMat,
                                  strainMag=dspTol,
                                  claimingSpots=False,
                                  testClaims=True,
                                  updateSelf=True)
            fineEtaTol = candidate.etaTol
            fineOmeTol = candidate.omeTol
            if candidate.completeness < minCompleteness:
                print ppfx + "candidate failed"
                return foundGrainData
            if multiProcMode and foundFlagShared.value:
                'some other process beat this one to it'
                return foundGrainData
        if multiProcMode:
            foundFlagShared.value = True
        # # newGrain uses current candidate.rMat
        # # do not do claims here -- those handled outside of this call
        # foundGrain = candidate.newGrain(
        #     spotsArray, claimingSpots=False,
        #     omeTol=fineOmeTol,
        #     etaTol=fineEtaTol)
        # if multiProcMode:
        #     foundGrain.strip()
        cInfo = quatOfRotMat(candidate.rMat).flatten().tolist()
        cInfo.append(candidate.completeness)
        print ppfx+"Grain found at q = [%1.2e, %1.2e, %1.2e, %1.2e] with completeness %g" \
              % tuple(cInfo)
        foundGrainData = candidate.getGrainData()
        'tolerances not actually set in candidate, so set them manually'
        foundGrainData['omeTol'] = fineOmeTol
        foundGrainData['etaTol'] = fineEtaTol

    return foundGrainData
예제 #9
0
import sys, os, time

import numpy as np

from hexrd import matrixutil as mutil

from hexrd.xrd import rotations as rot
from hexrd.xrd import transforms_CAPI as xfcapi

n_quats = 1e6
rq = mutil.unitVector(np.random.randn(4, n_quats))
quats = np.array(rq.T, dtype=float, order='C')

""" NUMPY """
start0 = time.clock()                      # time this
rMats0 = rot.rotMatOfQuat(rq)
elapsed0 = (time.clock() - start0)

""" CAPI """
start1 = time.time()                      # time this
rMats1 = xfcapi.makeRotMatOfQuat(quats)
# rMats1 = np.zeros((n_quats, 3, 3))
# for i in range(n_quats):
#     rMats1[i, :, :] = xfcapi.makeRotMatOfQuat(quats[i, :])
elapsed1 = (time.time() - start1)
print "Time for %d quats:\t%g v. %g (%f)"%(n_quats, elapsed0/float(n_quats), elapsed1/float(n_quats), elapsed0/elapsed1)
print "Maximum discrepancy:\t%f" % (np.amax(abs(rMats0 - rMats1)))

""" NOTES

If I call xfcapi.makeRotMatOfQuat(quats) I get:
예제 #10
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.1834835 ],
                      [ 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 = mutil.unitVector(quats[1:, :]) # ns contains the rotation axis as an unit vector
    exp_maps = np.array([phis[i]*ns[:, i] for i in range(n_grains)])
    rMat_c = rot.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, :], xf.vInv_ref.flatten()])
            )

    # 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)):
        del_ome = ome_range[i][1]-ome_range[i][0]
        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_cfg = yaml.load(fildes)

    tiltAngles = instr_cfg['detector']['transform']['tilt_angles']
    tVec_d = np.array(instr_cfg['detector']['transform']['t_vec_d']).reshape(3,1)
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.array(instr_cfg['oscillation_stage']['t_vec_s']).reshape(3,1)
    rMat_d = xfcapi.makeDetectorRotMat(tiltAngles)
    rMat_s = xfcapi.makeOscillRotMat([chi, 0.])

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

    col_ps = pixel_size[1]
    row_ps = pixel_size[0]

    row_dim = row_ps*nrows # in mm
    col_dim = col_ps*ncols # in mm
    panel_dims = [(-0.5*ncols*col_ps, -0.5*nrows*row_ps),
                  ( 0.5*ncols*col_ps,  0.5*nrows*row_ps)]

    x_col_edges = col_ps * (np.arange(ncols + 1) - 0.5*ncols)
    y_row_edges = row_ps * (np.arange(nrows, -1, -1) - 0.5*nrows)
    #x_col_edges = np.arange(panel_dims[0][0], panel_dims[1][0] + 0.5*col_ps, col_ps)
    #y_row_edges = np.arange(panel_dims[0][1], panel_dims[1][1] + 0.5*row_ps, row_ps)
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)

    gcrds = xfcapi.detectorXYToGvec(np.vstack([rx.flatten(), ry.flatten()]).T,
                                    rMat_d, rMat_s,
                                    tVec_d, tVec_s, np.zeros(3))

    max_pixel_tth = np.amax(gcrds[0][0])
    detector_params = np.hstack([tiltAngles, tVec_d.flatten(), chi,
                                 tVec_s.flatten()])
    distortion = None

    # 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 = np.ceil(0.5 * max_diameter/row_ps)
    col_dilation = np.ceil(0.5 * max_diameter/col_ps)

    # crystallography data
    from hexrd import valunits
    gold = material.Material('gold')
    gold.sgnum = 225
    gold.latticeParameters = [4.0782, ]
    gold.hklMax = 200
    gold.beamEnergy = valunits.valWUnit("wavelength", "ENERGY", 52, "keV")
    gold.planeData.exclusions = None
    gold.planeData.tThMax = max_pixel_tth #note this comes from info in the 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 -angle * rotation axis- (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_s = rMat_s
    # 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
예제 #11
0
        distortion = (dFuncs.GE_41RT, detector.getParams(allParams=True)[6:])

        tVec_d = tVec_d_from_old_parfile(geomParams, det_origin)
        detector_params = np.hstack(
            [geomParams[3:6, 0],
             tVec_d.flatten(), 0.,
             np.zeros(3)])

        use_tth_max = parser.get('pull_spots', 'use_tth_max')
        if use_tth_max.strip() == '1' or use_tth_max.strip().lower() == 'true':
            excl = np.zeros_like(pd.exclusions, dtype=bool)
            pd.exclusions = excl
            excl = pd.getTTh() > detector.getTThMax()
            pd.exclusions = excl
            pass
        phi, n = rot.angleAxisOfRotMat(rot.rotMatOfQuat(qbar))
        if have_progBar:
            widgets = [Bar('>'), ' ', ETA(), ' ', ReverseBar('<')]
            pbar = ProgressBar(widgets=widgets, maxval=len(qbar.T)).start()
            pass
        print "pulling spots for %d orientations..." % len(qbar.T)
        for iq, quat in enumerate(qbar.T):
            if have_progBar:
                pbar.update(iq)
            exp_map = phi[iq] * n[:, iq]
            grain_params = np.hstack(
                [exp_map.flatten(), 0., 0., 0., 1., 1., 1., 0., 0., 0.])
            sd = xrdutil.pullSpots(pd,
                                   detector_params,
                                   grain_params,
                                   reader,
예제 #12
0
파일: indexer.py 프로젝트: lind9/hexrd
def paintGridThis(quat):
    """
    """
    # Unpack common parameters into locals
    symHKLs = paramMP['symHKLs']
    symHKLs_ix = paramMP['symHKLs_ix']
    wavelength = paramMP['wavelength']
    hklList = paramMP['hklList']
    omeMin = paramMP['omeMin']
    omeMax = paramMP['omeMax']
    omeTol = paramMP['omeTol']
    omePeriod = paramMP['omePeriod']
    omeIndices = paramMP['omeIndices']
    omeEdges = paramMP['omeEdges']
    etaMin = paramMP['etaMin']
    etaMax = paramMP['etaMax']
    etaTol = paramMP['etaTol']
    etaIndices = paramMP['etaIndices']
    etaEdges = paramMP['etaEdges']
    etaOmeMaps = paramMP['etaOmeMaps']
    bMat = paramMP['bMat']
    threshold = paramMP['threshold']

    # need this for proper index generation

    delOmeSign = num.sign(omeEdges[1] - omeEdges[0])

    del_ome = abs(omeEdges[1] - omeEdges[0])
    del_eta = abs(etaEdges[1] - etaEdges[0])

    dpix_ome = round(omeTol / del_ome)
    dpix_eta = round(etaTol / del_eta)

    debug = False
    if debug:
        print "using ome, eta dilitations of (%d, %d) pixels" \
              % (dpix_ome, dpix_eta)

    nHKLs = len(symHKLs_ix) - 1

    rMat = rotMatOfQuat(quat)

    nPredRefl = 0
    nMeasRefl = 0
    reflInfoList = []
    dummySpotInfo = num.nan * num.ones(3)

    # Compute the oscillation angles of all the symHKLs at once
    oangs_pair = xfcapi.oscillAnglesOfHKLs(
        symHKLs, 0., rMat, bMat, wavelength)
    # Interleave the two produced oang solutions to simplify later processing
    oangs = num.empty((len(symHKLs)*2, 3), dtype=oangs_pair[0].dtype)
    oangs[0::2] = oangs_pair[0]
    oangs[1::2] = oangs_pair[1]

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

    # Create a mask of the good ones
    oangMask = num.logical_and(
                ~num.isnan(oangs[:, 0]),
            num.logical_and(
                xf.validateAngleRanges(oangs[:, 1], etaMin, etaMax),
                xf.validateAngleRanges(oangs[:, 2], omeMin, omeMax)))

    hklCounterP = 0 # running count of excpected (predicted) HKLs
    hklCounterM = 0 # running count of "hit" HKLs
    for iHKL in range(nHKLs):
        start, stop = symHKLs_ix[iHKL:iHKL+2]
        start, stop = (2*start, 2*stop)

        angList = oangs[start:stop]
        angMask = oangMask[start:stop]

        allAngs_m = angList[angMask, :]
        if len(allAngs_m) > 0:
            # not output # # duplicate HKLs
            # not output # allHKLs_m = num.vstack(
            #     [these_hkls, these_hkls]
            #     )[angMask, :]

            culledTTh  = allAngs_m[:, 0]
            culledEta  = allAngs_m[:, 1]
            culledOme  = allAngs_m[:, 2]
            # not output # culledHKLs = allHKLs_m.T

            nThisPredRefl = len(culledTTh)
            hklCounterP += nThisPredRefl
            for iTTh in range(nThisPredRefl):
                culledEtaIdx = num.where(etaEdges - culledEta[iTTh] > 0)[0]
                if len(culledEtaIdx) > 0:
                    culledEtaIdx = culledEtaIdx[0] - 1
                    if culledEtaIdx < 0:
                        culledEtaIdx = None
                else:
                    culledEtaIdx = None
                culledOmeIdx = num.where(omeEdges - culledOme[iTTh] > 0)[0]
                if len(culledOmeIdx) > 0:
                    if delOmeSign > 0:
                        culledOmeIdx = culledOmeIdx[0] - 1
                    else:
                        culledOmeIdx = culledOmeIdx[-1]
                    if culledOmeIdx < 0:
                        culledOmeIdx = None
                else:
                    culledOmeIdx = None

                if culledEtaIdx is not None and culledOmeIdx is not None:
                    if dpix_ome > 0 or dpix_eta > 0:
                        i_dil, j_dil = _meshgrid2d(
                            num.arange(-dpix_ome, dpix_ome + 1),
                            num.arange(-dpix_eta, dpix_eta + 1)
                            )
                        i_sup = omeIndices[culledOmeIdx] + num.array(
                            [i_dil.flatten()], dtype=int
                            )
                        j_sup = etaIndices[culledEtaIdx] + num.array(
                            [j_dil.flatten()], dtype=int
                            )
                        # catch shit that falls off detector...
                        # ...maybe make this fancy enough to wrap at 2pi?
                        i_max, j_max = etaOmeMaps[iHKL].shape
                        idx_mask = num.logical_and(
                            num.logical_and(i_sup >= 0, i_sup < i_max),
                            num.logical_and(j_sup >= 0, j_sup < j_max)
                            )
                        pixelVal = etaOmeMaps[iHKL][
                            i_sup[idx_mask], j_sup[idx_mask]
                            ]
                    else:
                        pixelVal = etaOmeMaps[iHKL][
                            omeIndices[culledOmeIdx], etaIndices[culledEtaIdx]
                            ]
                    isHit = num.any(pixelVal >= threshold[iHKL])
                    if isHit:
                        hklCounterM += 1
                # if debug:
                #     print "hkl %d -->\t%d\t%d\t%d\t" % (
                #         iHKL, culledHKLs[0, iTTh], culledHKLs[1, iTTh],
                #         culledHKLs[2, iTTh]
                #         ) \
                #         + "isHit=%d\tpixel value: %g\n" % (isHit, pixelVal) \
                #         + "eta index: %d,%d\tetaP: %g\n" % (
                #         culledEtaIdx, etaIndices[culledEtaIdx],
                #         r2d*culledEta[iTTh]
                #         ) \
                #         + "ome index: %d,%d\tomeP: %g\n" % (
                #         culledOmeIdx, omeIndices[culledOmeIdx],
                #         r2d*culledOme[iTTh]
                #         )
                #
                # close conditional on valid reflections
            # close loop on signed reflections
        # close loop on HKL
    if hklCounterP == 0:
        retval = 0.
    else:
        retval = float(hklCounterM) / float(hklCounterP)
    return retval
예제 #13
0
파일: indexer.py 프로젝트: B-Rich/hexrd
def paintGridThis(quat):
    """
    """
    # pull local vars from globals set in paintGrid
    global symHKLs_MP, wavelength_MP
    global omeMin_MP, omeMax_MP, omeTol_MP
    global etaMin_MP, etaMax_MP, etaTol_MP
    global omeIndices_MP, etaIndices_MP
    global omeEdges_MP, etaEdges_MP
    global hklList_MP, hklIDs_MP
    global etaOmeMaps_MP
    global bMat_MP
    global threshold_MP
    symHKLs    = symHKLs_MP
    wavelength = wavelength_MP
    hklIDs     = hklIDs_MP
    hklList    = hklList_MP
    omeMin     = omeMin_MP
    omeMax     = omeMax_MP
    omeTol     = omeTol_MP
    omeIndices = omeIndices_MP
    omeEdges   = omeEdges_MP
    etaMin     = etaMin_MP
    etaMax     = etaMax_MP
    etaTol     = etaTol_MP
    etaIndices = etaIndices_MP
    etaEdges   = etaEdges_MP
    etaOmeMaps = etaOmeMaps_MP
    bMat       = bMat_MP
    threshold  = threshold_MP

    # need this for proper index generation

    omegas = [omeEdges[0] + (i+0.5)*(omeEdges[1] - omeEdges[0]) for i in range(len(omeEdges) - 1)]
    etas   = [etaEdges[0] + (i+0.5)*(etaEdges[1] - etaEdges[0]) for i in range(len(etaEdges) - 1)]
    
    delOmeSign = num.sign(omegas[1] - omegas[0])
    
    del_ome = abs(omegas[1] - omegas[0])
    del_eta = abs(etas[1] - etas[0])
    
    dpix_ome = round(omeTol / del_ome)
    dpix_eta = round(etaTol / del_eta)
    
    debug = False
    if debug:
        print "using ome, eta dilitations of (%d, %d) pixels" % (dpix_ome, dpix_eta)
    
    nHKLs = len(hklIDs)

    rMat = rotMatOfQuat(quat)

    nPredRefl = 0
    nMeasRefl = 0
    reflInfoList = []
    dummySpotInfo = num.nan * num.ones(3)

    hklCounterP = 0                 # running count of excpected (predicted) HKLs
    hklCounterM = 0                 # running count of "hit" HKLs
    for iHKL in range(nHKLs):
        # select and C-ify symmetric HKLs
        these_hkls = num.array(symHKLs[hklIDs[iHKL]].T, dtype=float, order='C')
        
        # oscillation angle arrays
        oangs   = xfcapi.oscillAnglesOfHKLs(these_hkls, 0., rMat, bMat, wavelength)
        angList = num.vstack(oangs)
        if not num.all(num.isnan(angList)):
            angList[:, 1] = xf.mapAngle(angList[:, 1])
            angList[:, 2] = xf.mapAngle(angList[:, 2])
            
            if omeMin is None:
                omeMin = [-num.pi, ]
                omeMax = [ num.pi, ]
            if etaMin is None:
                etaMin = [-num.pi, ]
                etaMax = [ num.pi, ]
                
            angMask = num.logical_and(
                xf.validateAngleRanges(angList[:, 1], etaMin, etaMax),
                xf.validateAngleRanges(angList[:, 2], omeMin, omeMax))
            
            allAngs_m = angList[angMask, :]
            
            # not output # # duplicate HKLs
            # not output # allHKLs_m = num.vstack([these_hkls, these_hkls])[angMask, :]
            
            culledTTh  = allAngs_m[:, 0]
            culledEta  = allAngs_m[:, 1]
            culledOme  = allAngs_m[:, 2]
            # not output # culledHKLs = allHKLs_m.T
            
            nThisPredRefl = len(culledTTh)
            hklCounterP += nThisPredRefl
            for iTTh in range(nThisPredRefl):
                culledEtaIdx = num.where(etaEdges - culledEta[iTTh] > 0)[0]
                if len(culledEtaIdx) > 0:
                    culledEtaIdx = culledEtaIdx[0] - 1
                    if culledEtaIdx < 0:
                        culledEtaIdx = None
                else:
                    culledEtaIdx = None
                culledOmeIdx = num.where(omeEdges - culledOme[iTTh] > 0)[0]
                if len(culledOmeIdx) > 0:
                    if delOmeSign > 0:
                        culledOmeIdx = culledOmeIdx[0] - 1
                    else:
                        culledOmeIdx = culledOmeIdx[-1]
                    if culledOmeIdx < 0:
                        culledOmeIdx = None
                else:
                    culledOmeIdx = None
                
                if culledEtaIdx is not None and culledOmeIdx is not None:
                    if dpix_ome > 0 or dpix_eta > 0:
                        i_dil, j_dil = num.meshgrid(num.arange(-dpix_ome, dpix_ome + 1),
                                                    num.arange(-dpix_eta, dpix_eta + 1))
                        i_sup = omeIndices[culledOmeIdx] + num.array([i_dil.flatten()], dtype=int)
                        j_sup = etaIndices[culledEtaIdx] + num.array([j_dil.flatten()], dtype=int)
                        # catch shit that falls off detector... 
                        # ...maybe make this fancy enough to wrap at 2pi?
                        i_max, j_max = etaOmeMaps[iHKL].shape
                        idx_mask = num.logical_and(num.logical_and(i_sup >= 0, i_sup < i_max),
                                                   num.logical_and(j_sup >= 0, j_sup < j_max))                    
                        pixelVal = etaOmeMaps[iHKL][i_sup[idx_mask], j_sup[idx_mask]]
                    else:
                        pixelVal = etaOmeMaps[iHKL][omeIndices[culledOmeIdx], etaIndices[culledEtaIdx] ]
                    isHit = num.any(pixelVal >= threshold[iHKL])
                    if isHit:
                        hklCounterM += 1
                        pass
                    pass
                # disabled # if debug:
                # disabled #     print "hkl %d -->\t%d\t%d\t%d\t" % (iHKL, culledHKLs[0, iTTh], culledHKLs[1, iTTh], culledHKLs[2, iTTh]) + \
                # disabled #           "isHit=%d\tpixel value: %g\n" % (isHit, pixelVal) + \
                # disabled #           "eta index: %d,%d\tetaP: %g\n" % (culledEtaIdx, etaIndices[culledEtaIdx], r2d*culledEta[iTTh]) + \
                # disabled #           "ome index: %d,%d\tomeP: %g\n" % (culledOmeIdx, omeIndices[culledOmeIdx], r2d*culledOme[iTTh])
                # disabled #     pass
                pass # close conditional on valid reflections
            pass # close loop on signed reflections
        pass # close loop on HKL
    if hklCounterP == 0:
        retval = 0.
    else:
        retval = float(hklCounterM) / float(hklCounterP)
    return retval
예제 #14
0
        geomParams = np.vstack([detector.getParams(allParams=True)[:6],
                                np.zeros(6)]).T

        distortion = (dFuncs.GE_41RT, detector.getParams(allParams=True)[6:])

        tVec_d = tVec_d_from_old_parfile(geomParams, det_origin)
        detector_params = np.hstack([geomParams[3:6, 0], tVec_d.flatten(), 0., np.zeros(3)])

        use_tth_max = parser.get('pull_spots', 'use_tth_max')
        if use_tth_max.strip() == '1' or use_tth_max.strip().lower() == 'true':
            excl = np.zeros_like(pd.exclusions, dtype=bool)
            pd.exclusions = excl
            excl = pd.getTTh() > detector.getTThMax()
            pd.exclusions = excl
            pass
        phi, n = rot.angleAxisOfRotMat(rot.rotMatOfQuat(qbar))
        if have_progBar:
            widgets = [Bar('>'), ' ', ETA(), ' ', ReverseBar('<')]
            pbar = ProgressBar(widgets=widgets, maxval=len(qbar.T)).start()
            pass
        print "pulling spots for %d orientations..." %len(qbar.T)
        for iq, quat in enumerate(qbar.T):
            if have_progBar:
                pbar.update(iq)
            exp_map = phi[iq]*n[:, iq]
            grain_params = np.hstack([exp_map.flatten(), 0., 0., 0., 1., 1., 1., 0., 0., 0.])
            sd = xrdutil.pullSpots(pd, detector_params, grain_params, reader,
                                   filename=pull_filename %iq,
                                   eta_range=etaRange, ome_period=ome_period,
                                   eta_tol=eta_tol, ome_tol=ome_tol,
                                   threshold=pthresh, tth_tol=tth_tol,
예제 #15
0
    nhkls = len(matl.planeData.exclusions)
    matl.planeData.set_exclusions(np.zeros(nhkls, dtype=bool))
    return matl


#==============================================================================
# %% USER OPTIONS
#==============================================================================
n_grains = 2
quats = np.array([[0.91836393, 0.90869942], [0.33952917, 0.1834835],
                  [0.17216207, 0.10095837], [0.10811041, 0.36111851]])
phis = 2. * np.arccos(quats[0, :])
ns = mutil.unitVector(quats[1:, :])
exp_maps = np.array([phis[i] * ns[:, i] for i in range(n_grains)])
rMat_c = rot.rotMatOfQuat(quats)

# base 1-micron grid for 50 micron cube
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, :],
예제 #16
0
def paintGridThis(quat):
    """
    """
    # pull local vars from globals set in paintGrid
    global symHKLs_MP, wavelength_MP
    global omeMin_MP, omeMax_MP, omeTol_MP, omePeriod_MP
    global etaMin_MP, etaMax_MP, etaTol_MP
    global omeIndices_MP, etaIndices_MP
    global omeEdges_MP, etaEdges_MP
    global hklList_MP, hklIDs_MP
    global etaOmeMaps_MP
    global bMat_MP
    global threshold_MP
    symHKLs = symHKLs_MP
    wavelength = wavelength_MP
    hklIDs = hklIDs_MP
    hklList = hklList_MP
    omeMin = omeMin_MP
    omeMax = omeMax_MP
    omeTol = omeTol_MP
    omePeriod = omePeriod_MP
    omeIndices = omeIndices_MP
    omeEdges = omeEdges_MP
    etaMin = etaMin_MP
    etaMax = etaMax_MP
    etaTol = etaTol_MP
    etaIndices = etaIndices_MP
    etaEdges = etaEdges_MP
    etaOmeMaps = etaOmeMaps_MP
    bMat = bMat_MP
    threshold = threshold_MP

    # need this for proper index generation

    omegas = [
        omeEdges[0] + (i + 0.5) * (omeEdges[1] - omeEdges[0])
        for i in range(len(omeEdges) - 1)
    ]
    etas = [
        etaEdges[0] + (i + 0.5) * (etaEdges[1] - etaEdges[0])
        for i in range(len(etaEdges) - 1)
    ]

    delOmeSign = num.sign(omegas[1] - omegas[0])

    del_ome = abs(omegas[1] - omegas[0])
    del_eta = abs(etas[1] - etas[0])

    dpix_ome = round(omeTol / del_ome)
    dpix_eta = round(etaTol / del_eta)

    debug = False
    if debug:
        print "using ome, eta dilitations of (%d, %d) pixels" % (dpix_ome,
                                                                 dpix_eta)

    nHKLs = len(hklIDs)

    rMat = rotMatOfQuat(quat)

    nPredRefl = 0
    nMeasRefl = 0
    reflInfoList = []
    dummySpotInfo = num.nan * num.ones(3)

    hklCounterP = 0  # running count of excpected (predicted) HKLs
    hklCounterM = 0  # running count of "hit" HKLs
    for iHKL in range(nHKLs):
        # select and C-ify symmetric HKLs
        these_hkls = num.array(symHKLs[hklIDs[iHKL]].T, dtype=float, order='C')

        # oscillation angle arrays
        oangs = xfcapi.oscillAnglesOfHKLs(these_hkls, 0., rMat, bMat,
                                          wavelength)
        angList = num.vstack(oangs)
        if not num.all(num.isnan(angList)):
            idx = -num.isnan(angList[:, 0])
            angList = angList[idx, :]
            angList[:, 1] = xf.mapAngle(angList[:, 1])
            angList[:, 2] = xf.mapAngle(angList[:, 2], omePeriod)

            if omeMin is None:
                omeMin = [
                    -num.pi,
                ]
                omeMax = [
                    num.pi,
                ]
            if etaMin is None:
                etaMin = [
                    -num.pi,
                ]
                etaMax = [
                    num.pi,
                ]

            angMask = num.logical_and(
                xf.validateAngleRanges(angList[:, 1], etaMin, etaMax),
                xf.validateAngleRanges(angList[:, 2], omeMin, omeMax))

            allAngs_m = angList[angMask, :]

            # not output # # duplicate HKLs
            # not output # allHKLs_m = num.vstack([these_hkls, these_hkls])[angMask, :]

            culledTTh = allAngs_m[:, 0]
            culledEta = allAngs_m[:, 1]
            culledOme = allAngs_m[:, 2]
            # not output # culledHKLs = allHKLs_m.T

            nThisPredRefl = len(culledTTh)
            hklCounterP += nThisPredRefl
            for iTTh in range(nThisPredRefl):
                culledEtaIdx = num.where(etaEdges - culledEta[iTTh] > 0)[0]
                if len(culledEtaIdx) > 0:
                    culledEtaIdx = culledEtaIdx[0] - 1
                    if culledEtaIdx < 0:
                        culledEtaIdx = None
                else:
                    culledEtaIdx = None
                culledOmeIdx = num.where(omeEdges - culledOme[iTTh] > 0)[0]
                if len(culledOmeIdx) > 0:
                    if delOmeSign > 0:
                        culledOmeIdx = culledOmeIdx[0] - 1
                    else:
                        culledOmeIdx = culledOmeIdx[-1]
                    if culledOmeIdx < 0:
                        culledOmeIdx = None
                else:
                    culledOmeIdx = None

                if culledEtaIdx is not None and culledOmeIdx is not None:
                    if dpix_ome > 0 or dpix_eta > 0:
                        i_dil, j_dil = num.meshgrid(
                            num.arange(-dpix_ome, dpix_ome + 1),
                            num.arange(-dpix_eta, dpix_eta + 1))
                        i_sup = omeIndices[culledOmeIdx] + num.array(
                            [i_dil.flatten()], dtype=int)
                        j_sup = etaIndices[culledEtaIdx] + num.array(
                            [j_dil.flatten()], dtype=int)
                        # catch shit that falls off detector...
                        # ...maybe make this fancy enough to wrap at 2pi?
                        i_max, j_max = etaOmeMaps[iHKL].shape
                        idx_mask = num.logical_and(
                            num.logical_and(i_sup >= 0, i_sup < i_max),
                            num.logical_and(j_sup >= 0, j_sup < j_max))
                        pixelVal = etaOmeMaps[iHKL][i_sup[idx_mask],
                                                    j_sup[idx_mask]]
                    else:
                        pixelVal = etaOmeMaps[iHKL][omeIndices[culledOmeIdx],
                                                    etaIndices[culledEtaIdx]]
                    isHit = num.any(pixelVal >= threshold[iHKL])
                    if isHit:
                        hklCounterM += 1
                        pass
                    pass
                # disabled # if debug:
                # disabled #     print "hkl %d -->\t%d\t%d\t%d\t" % (iHKL, culledHKLs[0, iTTh], culledHKLs[1, iTTh], culledHKLs[2, iTTh]) + \
                # disabled #           "isHit=%d\tpixel value: %g\n" % (isHit, pixelVal) + \
                # disabled #           "eta index: %d,%d\tetaP: %g\n" % (culledEtaIdx, etaIndices[culledEtaIdx], r2d*culledEta[iTTh]) + \
                # disabled #           "ome index: %d,%d\tomeP: %g\n" % (culledOmeIdx, omeIndices[culledOmeIdx], r2d*culledOme[iTTh])
                # disabled #     pass
                pass  # close conditional on valid reflections
            pass  # close loop on signed reflections
        pass  # close loop on HKL
    if hklCounterP == 0:
        retval = 0.
    else:
        retval = float(hklCounterM) / float(hklCounterP)
    return retval
예제 #17
0
#==============================================================================
# %% NEAR FIELD - LOAD IMAGE DATA AND PROCESS
#==============================================================================

image_stack=gen_nf_cleaned_image_stack(data_folder,img_nums,dark,ome_dilation_iter,threshold,experiment.nrows,experiment.ncols,num_digits=6,grey_bnds=(5,5),gaussian=4.5)

#%%

test_crds_load = np.load(output_dir + missing_grain_coordinates)
test_crds = test_crds_load[:,:]
n_crds = test_crds.shape[0]

random_quaternions = np.load(output_dir + quaternion_test_list)

n_grains = random_quaternions.shape[1]
rMat_c = rot.rotMatOfQuat(random_quaternions)
exp_maps = np.zeros([random_quaternions.shape[1],3])
for i in range(0,random_quaternions.shape[1]):
    phi = 2*np.arccos(random_quaternions[0,i])
    n = xfcapi.unitRowVector(random_quaternions[1:,i])
    exp_maps[i,:] = phi*n

#%%

experiment.n_grains = n_grains
experiment.rMat_c = rMat_c
experiment.exp_maps = exp_maps

#==============================================================================
# %% INSTANTIATE CONTROLLER - RUN BLOCK NO EDITING
#==============================================================================
예제 #18
0
    nhkls = len(matl.planeData.exclusions)
    matl.planeData.set_exclusions(np.zeros(nhkls, dtype=bool))
    return matl

#==============================================================================
# %% USER OPTIONS
#==============================================================================
n_grains = 2
quats = np.array([[ 0.91836393,  0.90869942],
                  [ 0.33952917,  0.1834835 ],
                  [ 0.17216207,  0.10095837],
                  [ 0.10811041,  0.36111851]])
phis = 2.*np.arccos(quats[0, :])
ns = mutil.unitVector(quats[1:, :])
exp_maps = np.array([phis[i]*ns[:, i] for i in range(n_grains)])
rMat_c = rot.rotMatOfQuat(quats)

# base 1-micron grid for 50 micron cube
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, :], xf.vInv_ref.flatten()])
예제 #19
0
파일: indexer.py 프로젝트: B-Rich/hexrd
def testThisQ(thisQ):
    """
    NOTES:
    (*) doFit is not done here -- in multiprocessing, that would end
        up happening on a remote process and then different processes
        would have different data, unless spotsArray were made to be
        fancier

    (*) kludge stuff so that this function is outside of fiberSearch
    """
    global multiProcMode_MP
    global spotsArray_MP
    global candidate_MP
    global dspTol_MP
    global minCompleteness_MP
    global doRefinement_MP
    global nStdDev_MP
    # assign locals
    multiProcMode   = multiProcMode_MP
    spotsArray      = spotsArray_MP
    candidate       = candidate_MP
    dspTol          = dspTol_MP
    minCompleteness = minCompleteness_MP
    doRefinement    = doRefinement_MP
    nStdDev         = nStdDev_MP
    nSigmas = 2                         # ... make this a settable option?
    if multiProcMode:
        global foundFlagShared

    foundGrainData = None
    #print "testing %d of %d"% (iR+1, numTrials)
    thisRMat = rotMatOfQuat(thisQ)

    ppfx = ''
    if multiProcMode:
        proc = multiprocessing.current_process()
        ppfx = str(proc.name)+' : '
        if multiProcMode and foundFlagShared.value:
            """
            map causes this function to be applied to all trial orientations,
            but skip evaluations after an acceptable grain has been found
            """
            if debugMultiproc > 1:
                print ppfx+'skipping on '+str(thisQ)
            return foundGrainData
        else:
            if debugMultiproc > 1:
                print ppfx+'working on  '+str(thisQ)
            pass
    candidate.findMatches(rMat=thisRMat,
                          strainMag=dspTol,
                          claimingSpots=False,
                          testClaims=True,
                          updateSelf=True)
    if debugMultiproc > 1:
        print ppfx+' for '+str(thisQ)+' got completeness : '+str(candidate.completeness)
    if candidate.completeness >= minCompleteness:
        ## attempt to filter out 'junk' spots here by performing full
        ## refinement before claiming
        fineEtaTol = candidate.etaTol
        fineOmeTol = candidate.omeTol
        if doRefinement:
            if multiProcMode and foundFlagShared.value:
                'some other process beat this one to it'
                return foundGrainData
            print ppfx+"testing candidate q = [%1.2e, %1.2e, %1.2e, %1.2e]" %tuple(thisQ)
            # not needed # candidate.fitPrecession(display=False)
            ## first fit
            candidate.fit(display=False)
            ## auto-tolerace based on statistics of current matches
            validRefls = candidate.grainSpots['iRefl'] > 0
            fineEtaTol = nStdDev * num.std(candidate.grainSpots['diffAngles'][validRefls, 1])
            fineOmeTol = nStdDev * num.std(candidate.grainSpots['diffAngles'][validRefls, 2])
            ## next fits with finer tolerances
            for iLoop in range(3):
                candidate.findMatches(etaTol=fineEtaTol,
                                      omeTol=fineOmeTol,
                                      claimingSpots=False,
                                      testClaims=True,
                                      updateSelf=True)
                # not needed # candidate.fitPrecession(display=False)
                candidate.fit(display=False)
            if candidate.completeness < minCompleteness:
                print ppfx+"candidate failed"
                return foundGrainData
            if multiProcMode and foundFlagShared.value:
                'some other process beat this one to it'
                return foundGrainData
            # not needed # candidate.fitPrecession(display=False)
            # not needed? # candidate.fit(display=False)
            # not needed? # candidate.findMatches(etaTol=fineEtaTol,
            # not needed? #                       omeTol=fineOmeTol,
            # not needed? #                       claimingSpots=False,
            # not needed? #                       testClaims=True,
            # not needed? #                       updateSelf=True)
        else:
            ## at least do precession correction
            candidate.fitPrecession(display=False)
            candidate.findMatches(rMat=thisRMat,
                                  strainMag=dspTol,
                                  claimingSpots=False,
                                  testClaims=True,
                                  updateSelf=True)
            fineEtaTol = candidate.etaTol
            fineOmeTol = candidate.omeTol
            if candidate.completeness < minCompleteness:
                print ppfx+"candidate failed"
                return foundGrainData
            if multiProcMode and foundFlagShared.value:
                'some other process beat this one to it'
                return foundGrainData
        if multiProcMode:
            foundFlagShared.value = True
        # # newGrain uses current candidate.rMat
        # # do not do claims here -- those handled outside of this call
        # foundGrain = candidate.newGrain(
        #     spotsArray, claimingSpots=False,
        #     omeTol=fineOmeTol,
        #     etaTol=fineEtaTol)
        # if multiProcMode:
        #     foundGrain.strip()
        cInfo = quatOfRotMat(candidate.rMat).flatten().tolist()
        cInfo.append(candidate.completeness)
        print ppfx+"Grain found at q = [%1.2e, %1.2e, %1.2e, %1.2e] with completeness %g" \
              % tuple(cInfo)
        foundGrainData = candidate.getGrainData()
        'tolerances not actually set in candidate, so set them manually'
        foundGrainData['omeTol'] = fineOmeTol
        foundGrainData['etaTol'] = fineEtaTol

    return foundGrainData
예제 #20
0
def paintGridThis(quat):
    """
    """
    # pull local vars from globals set in paintGrid
    global planeData_MP
    global omeMin_MP, omeMax_MP
    global etaMin_MP, etaMax_MP
    global omeIndices_MP, etaIndices_MP
    global hklList_MP, hklIDs_MP
    global etaOmeMaps_MP
    global bMat_MP
    global threshold_MP
    planeData = planeData_MP
    hklIDs = hklIDs_MP
    hklList = hklList_MP
    omeMin = omeMin_MP
    omeMax = omeMax_MP
    omeIndices = omeIndices_MP
    etaMin = etaMin_MP
    etaMax = etaMax_MP
    etaIndices = etaIndices_MP
    etaOmeMaps = etaOmeMaps_MP
    bMat = bMat_MP
    threshold = threshold_MP

    # need this for proper index generation
    delOmeSign = num.sign(etaOmeMaps.omegas[1] - etaOmeMaps.omegas[0])

    debug = False

    nHKLS = len(hklIDs)

    rMat = rotMatOfQuat(quat.reshape(4, 1))

    nPredRefl = 0
    nMeasRefl = 0
    reflInfoList = []
    dummySpotInfo = num.nan * num.ones(3)

    hklCounterP = 0  # running count of excpected (predicted) HKLs
    hklCounterM = 0  # running count of "hit" HKLs
    for iHKL in range(nHKLS):
        # for control of tolerancing
        symHKLs = planeData.getSymHKLs()[hklIDs[iHKL]]
        tThRanges = planeData.getTThRanges()[hklIDs[iHKL]]

        # make all theoretical scattering vectors
        predQvec, predQAng0, predQAng1 = \
                  planeData.makeTheseScatteringVectors([hklList[iHKL]], rMat, bMat=bMat)

        # work with generated spots for iHKL
        # allPredAng = zip(predQAng0[iHKL], predQAng1[iHKL])
        allPredAng = zip(predQAng0, predQAng1)

        # filter using omega range
        if omeMin is not None:
            reflInRangeOme0 = num.zeros(allPredAng[2][0].shape, dtype=bool)
            reflInRangeOme1 = num.zeros(allPredAng[2][1].shape, dtype=bool)
            for iOme in range(len(omeMin)):
                reflInRangeOme0 = reflInRangeOme0 | (
                    (allPredAng[2][0] >= omeMin[iOme]) &
                    (allPredAng[2][0] <= omeMax[iOme]))
                reflInRangeOme1 = reflInRangeOme1 | (
                    (allPredAng[2][1] >= omeMin[iOme]) &
                    (allPredAng[2][1] <= omeMax[iOme]))
                pass
        else:
            reflInRangeOme0 = num.ones(allPredAng[2][0].shape, dtype=bool)
            reflInRangeOme1 = num.ones(allPredAng[2][1].shape, dtype=bool)
            pass

        if etaMin is not None:
            reflInRangeEta0 = num.zeros(allPredAng[2][0].shape, dtype=bool)
            reflInRangeEta1 = num.zeros(allPredAng[2][1].shape, dtype=bool)
            for iEta in range(len(etaMin)):
                reflInRangeEta0 = reflInRangeEta0 | (
                    (allPredAng[1][0] >= etaMin[iEta]) &
                    (allPredAng[1][0] <= etaMax[iEta]))
                reflInRangeEta1 = reflInRangeEta1 | (
                    (allPredAng[1][1] >= etaMin[iEta]) &
                    (allPredAng[1][1] <= etaMax[iEta]))
                pass
        else:
            reflInRangeEta0 = num.ones(allPredAng[2][0].shape, dtype=bool)
            reflInRangeEta1 = num.ones(allPredAng[2][1].shape, dtype=bool)
            pass

        reflInRange0 = reflInRangeOme0 & reflInRangeEta0
        reflInRange1 = reflInRangeOme1 & reflInRangeEta1

        # get culled angle and hkl lists for predicted spots
        culledTTh = num.r_[allPredAng[0][0][reflInRange0],
                           allPredAng[0][1][reflInRange1]]
        culledEta = num.r_[allPredAng[1][0][reflInRange0],
                           allPredAng[1][1][reflInRange1]]
        culledOme = num.r_[allPredAng[2][0][reflInRange0],
                           allPredAng[2][1][reflInRange1]]

        culledHKLs = num.hstack(
            [symHKLs[:, reflInRange0], symHKLs[:, reflInRange1]])

        culledQvec = num.c_[predQvec[:, reflInRange0], predQvec[:,
                                                                reflInRange1]]

        nThisPredRefl = len(culledTTh)
        hklCounterP += nThisPredRefl
        for iTTh in range(nThisPredRefl):
            culledEtaIdx = num.where(
                etaOmeMaps.etaEdges - culledEta[iTTh] > 0)[0]
            if len(culledEtaIdx) > 0:
                culledEtaIdx = culledEtaIdx[0] - 1
                if culledEtaIdx < 0:
                    culledEtaIdx = None
            else:
                culledEtaIdx = None
            culledOmeIdx = num.where(
                etaOmeMaps.omeEdges - culledOme[iTTh] > 0)[0]
            if len(culledOmeIdx) > 0:
                if delOmeSign > 0:
                    culledOmeIdx = culledOmeIdx[0] - 1
                else:
                    culledOmeIdx = culledOmeIdx[-1]
                if culledOmeIdx < 0:
                    culledOmeIdx = None
            else:
                culledOmeIdx = None

            if culledEtaIdx is not None and culledOmeIdx is not None:
                pixelVal = etaOmeMaps.dataStore[iHKL][omeIndices[culledOmeIdx],
                                                      etaIndices[culledEtaIdx]]
                isHit = pixelVal >= threshold[iHKL]
                if isHit:
                    hklCounterM += 1
                    pass
                pass
            if debug:
                print "hkl %d -->\t%d\t%d\t%d\t" % (iHKL, culledHKLs[0, iTTh], culledHKLs[1, iTTh], culledHKLs[2, iTTh]) + \
                      "isHit=%d\tpixel value: %g\n" % (isHit, pixelVal) + \
                      "eta index: %d,%d\tetaP: %g\n" % (culledEtaIdx, etaIndices[culledEtaIdx], r2d*culledEta[iTTh]) + \
                      "ome index: %d,%d\tomeP: %g\n" % (culledOmeIdx, omeIndices[culledOmeIdx], r2d*culledOme[iTTh])
                pass
            pass  # close loop on signed reflections
        pass  # close loop on HKL
    retval = float(hklCounterM) / float(hklCounterP)
    return retval
예제 #21
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.1834835],
                      [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 = mutil.unitVector(
        quats[1:, :])  # ns contains the rotation axis as an unit vector
    exp_maps = np.array([phis[i] * ns[:, i] for i in range(n_grains)])
    rMat_c = rot.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, :],
                     xf.vInv_ref.flatten()]))

    # 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)):
        del_ome = ome_range[i][1] - ome_range[i][0]
        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_cfg = yaml.load(fildes)

    tiltAngles = instr_cfg['detector']['transform']['tilt_angles']
    tVec_d = np.array(instr_cfg['detector']['transform']['t_vec_d']).reshape(
        3, 1)
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.array(instr_cfg['oscillation_stage']['t_vec_s']).reshape(3, 1)
    rMat_d = xfcapi.makeDetectorRotMat(tiltAngles)
    rMat_s = xfcapi.makeOscillRotMat([chi, 0.])

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

    col_ps = pixel_size[1]
    row_ps = pixel_size[0]

    row_dim = row_ps * nrows  # in mm
    col_dim = col_ps * ncols  # in mm
    panel_dims = [(-0.5 * ncols * col_ps, -0.5 * nrows * row_ps),
                  (0.5 * ncols * col_ps, 0.5 * nrows * row_ps)]

    x_col_edges = col_ps * (np.arange(ncols + 1) - 0.5 * ncols)
    y_row_edges = row_ps * (np.arange(nrows, -1, -1) - 0.5 * nrows)
    #x_col_edges = np.arange(panel_dims[0][0], panel_dims[1][0] + 0.5*col_ps, col_ps)
    #y_row_edges = np.arange(panel_dims[0][1], panel_dims[1][1] + 0.5*row_ps, row_ps)
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)

    gcrds = xfcapi.detectorXYToGvec(
        np.vstack([rx.flatten(), ry.flatten()]).T, rMat_d, rMat_s, tVec_d,
        tVec_s, np.zeros(3))

    max_pixel_tth = np.amax(gcrds[0][0])
    detector_params = np.hstack(
        [tiltAngles, tVec_d.flatten(), chi,
         tVec_s.flatten()])
    distortion = None

    # 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 = np.ceil(0.5 * max_diameter / row_ps)
    col_dilation = np.ceil(0.5 * max_diameter / col_ps)

    # crystallography data
    from hexrd import valunits
    gold = material.Material('gold')
    gold.sgnum = 225
    gold.latticeParameters = [
        4.0782,
    ]
    gold.hklMax = 200
    gold.beamEnergy = valunits.valWUnit("wavelength", "ENERGY", 52, "keV")
    gold.planeData.exclusions = None
    gold.planeData.tThMax = max_pixel_tth  #note this comes from info in the 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 -angle * rotation axis- (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_s = rMat_s
    # 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
예제 #22
0
파일: indexer.py 프로젝트: mlstowell/hexrd
def paintGridThis(quat):
    """
    """
    # pull local vars from globals set in paintGrid
    global planeData_MP
    global omeMin_MP, omeMax_MP
    global etaMin_MP, etaMax_MP
    global omeIndices_MP, etaIndices_MP
    global hklList_MP, hklIDs_MP
    global etaOmeMaps_MP
    global bMat_MP
    global threshold_MP
    planeData  = planeData_MP
    hklIDs     = hklIDs_MP
    hklList    = hklList_MP
    omeMin     = omeMin_MP
    omeMax     = omeMax_MP
    omeIndices = omeIndices_MP
    etaMin     = etaMin_MP
    etaMax     = etaMax_MP
    etaIndices = etaIndices_MP
    etaOmeMaps = etaOmeMaps_MP
    bMat       = bMat_MP
    threshold  = threshold_MP

    # need this for proper index generation
    delOmeSign = num.sign(etaOmeMaps.omegas[1] - etaOmeMaps.omegas[0])

    debug = False

    nHKLS     = len(hklIDs)

    rMat = rotMatOfQuat(quat.reshape(4, 1))

    nPredRefl = 0
    nMeasRefl = 0
    reflInfoList = []
    dummySpotInfo = num.nan * num.ones(3)

    hklCounterP = 0                 # running count of excpected (predicted) HKLs
    hklCounterM = 0                 # running count of "hit" HKLs
    for iHKL in range(nHKLS):
        # for control of tolerancing
        symHKLs   = planeData.getSymHKLs()[hklIDs[iHKL]]
        tThRanges = planeData.getTThRanges()[hklIDs[iHKL]]

        # make all theoretical scattering vectors
        predQvec, predQAng0, predQAng1 = \
                  planeData.makeTheseScatteringVectors([hklList[iHKL]], rMat, bMat=bMat)

        # work with generated spots for iHKL
        # allPredAng = zip(predQAng0[iHKL], predQAng1[iHKL])
        allPredAng = zip(predQAng0, predQAng1)

        # filter using omega range
        if omeMin is not None:
            reflInRangeOme0 = num.zeros(allPredAng[2][0].shape, dtype=bool)
            reflInRangeOme1 = num.zeros(allPredAng[2][1].shape, dtype=bool)
            for iOme in range(len(omeMin)):
                reflInRangeOme0 = reflInRangeOme0 | (
                    (allPredAng[2][0] >= omeMin[iOme]) &
                    (allPredAng[2][0] <= omeMax[iOme]) )
                reflInRangeOme1 = reflInRangeOme1 | (
                    (allPredAng[2][1] >= omeMin[iOme]) &
                    (allPredAng[2][1] <= omeMax[iOme]) )
                pass
        else:
            reflInRangeOme0 = num.ones(allPredAng[2][0].shape, dtype=bool)
            reflInRangeOme1 = num.ones(allPredAng[2][1].shape, dtype=bool)
            pass

        if etaMin is not None:
            reflInRangeEta0 = num.zeros(allPredAng[2][0].shape, dtype=bool)
            reflInRangeEta1 = num.zeros(allPredAng[2][1].shape, dtype=bool)
            for iEta in range(len(etaMin)):
                reflInRangeEta0 = reflInRangeEta0 | (
                    (allPredAng[1][0] >= etaMin[iEta]) &
                    (allPredAng[1][0] <= etaMax[iEta]) )
                reflInRangeEta1 = reflInRangeEta1 | (
                    (allPredAng[1][1] >= etaMin[iEta]) &
                    (allPredAng[1][1] <= etaMax[iEta]) )
                pass
        else:
            reflInRangeEta0 = num.ones(allPredAng[2][0].shape, dtype=bool)
            reflInRangeEta1 = num.ones(allPredAng[2][1].shape, dtype=bool)
            pass

        reflInRange0 = reflInRangeOme0 & reflInRangeEta0
        reflInRange1 = reflInRangeOme1 & reflInRangeEta1

        # get culled angle and hkl lists for predicted spots
        culledTTh = num.r_[ allPredAng[0][0][reflInRange0], allPredAng[0][1][reflInRange1] ]
        culledEta = num.r_[ allPredAng[1][0][reflInRange0], allPredAng[1][1][reflInRange1] ]
        culledOme = num.r_[ allPredAng[2][0][reflInRange0], allPredAng[2][1][reflInRange1] ]

        culledHKLs = num.hstack( [
            symHKLs[:, reflInRange0],
            symHKLs[:, reflInRange1] ] )

        culledQvec = num.c_[ predQvec[:, reflInRange0], predQvec[:, reflInRange1] ]

        nThisPredRefl = len(culledTTh)
        hklCounterP += nThisPredRefl
        for iTTh in range(nThisPredRefl):
            culledEtaIdx = num.where(etaOmeMaps.etaEdges - culledEta[iTTh] > 0)[0]
            if len(culledEtaIdx) > 0:
                culledEtaIdx = culledEtaIdx[0] - 1
                if culledEtaIdx < 0:
                    culledEtaIdx = None
            else:
                culledEtaIdx = None
            culledOmeIdx = num.where(etaOmeMaps.omeEdges - culledOme[iTTh] > 0)[0]
            if len(culledOmeIdx) > 0:
                if delOmeSign > 0:
                    culledOmeIdx = culledOmeIdx[0] - 1
                else:
                    culledOmeIdx = culledOmeIdx[-1]
                if culledOmeIdx < 0:
                    culledOmeIdx = None
            else:
                culledOmeIdx = None

            if culledEtaIdx is not None and culledOmeIdx is not None:
                pixelVal = etaOmeMaps.dataStore[iHKL][omeIndices[culledOmeIdx], etaIndices[culledEtaIdx] ]
                isHit = pixelVal >= threshold[iHKL]
                if isHit:
                    hklCounterM += 1
                    pass
                pass
            if debug:
                print "hkl %d -->\t%d\t%d\t%d\t" % (iHKL, culledHKLs[0, iTTh], culledHKLs[1, iTTh], culledHKLs[2, iTTh]) + \
                      "isHit=%d\tpixel value: %g\n" % (isHit, pixelVal) + \
                      "eta index: %d,%d\tetaP: %g\n" % (culledEtaIdx, etaIndices[culledEtaIdx], r2d*culledEta[iTTh]) + \
                      "ome index: %d,%d\tomeP: %g\n" % (culledOmeIdx, omeIndices[culledOmeIdx], r2d*culledOme[iTTh])
                pass
            pass # close loop on signed reflections
        pass # close loop on HKL
    retval = float(hklCounterM) / float(hklCounterP)
    return retval
예제 #23
0
파일: test_rmats.py 프로젝트: lind9/hexrd
import numpy as np

from hexrd import matrixutil as mutil

from hexrd.xrd import rotations as rot
from hexrd.xrd import transforms_CAPI as xfcapi

n_quats = 1000000
rq = mutil.unitVector(np.random.randn(4, n_quats))
quats = np.array(rq.T, dtype=float, order='C')

# phi = 2. * rot.arccosSafe(rq[0, :])
# n   = np.tile(1. / np.sin(0.5*phi), (3, 1)) * rq[1:, :]

start0 = time.clock()  # time this
rMats0 = rot.rotMatOfQuat(rq)
elapsed0 = (time.clock() - start0)

# rMats1 = np.zeros((n_quats, 3, 3))
# for i in range(n_quats):
#     rMats1[i, :, :] = xfcapi.makeRotMatOfQuat(quats[i, :])

start1 = time.time()  # time this
rMats1 = xfcapi.makeRotMatOfQuat(quats)
elapsed1 = (time.time() - start1)
print "Time for %d quats:\t%g v. %g (%f)" % (
    n_quats, elapsed0 / float(n_quats), elapsed1 / float(n_quats),
    elapsed0 / elapsed1)
print "Maximum discrepancy:\t%f" % (np.amax(abs(rMats0 - rMats1)))
    def get_diffraction_angles(self):
        cfg = self.cfg
        logger = self.logger
        detector = self.detector

        # Number of cores for multiprocessing
        num_cores = cfg.multiprocessing

        # Initialize a new heXRD experiment
        ws = expt.Experiment()

        cwd = cfg.working_dir

        materials_fname = cfg.material.definitions
        material_name = cfg.material.active
        detector_fname = cfg.instrument.detector.parameters_old

        # load materials
        ws.loadMaterialList(os.path.join(cwd, materials_fname))
        mat_name_list = ws.matNames

        # Create an array of all the essential parameters to be
        # sent to parallel diffraction angle calculation routine
        fwd_model_input = []

        for xyz_i, mat_name_i, quat_i, defgrad_i in zip(
                self.ms_grid, self.ms_material_ids, self.ms_quaternions,
                self.ms_lat_defgrads):

            # Set chi tilt
            if detector.chiTilt is not None:
                chi = detector.chiTilt
            else:
                chi = 0.0

# Obtain all symmetric hkls for the material
            ws.activeMaterial = mat_name_i.strip()  #material_name

            hkls = ws.activeMaterial.planeData.getSymHKLs()
            hkls = np.transpose(np.hstack(hkls))
            # Rotational matrix from the orientation/quaternion
            rmat_c = rot.rotMatOfQuat(quat_i)
            # bmat
            bmat = ws.activeMaterial.planeData.latVecOps['B']
            wavelength = ws.activeMaterial.planeData.wavelength
            # Create a dictionary of inputs to be sent to the MP worker
            fwd_model_input.append({
                'chi': chi,
                'hkls': hkls,
                'rmat_c': rmat_c,
                'bmat': bmat,
                'wavelength': wavelength,
                'defgrad_i': defgrad_i
            })

        # Now we have the data, run eta, twoth, omega calculations in parallel
        logger.info(
            "Starting virtual diffraction calculations using %i processors",
            num_cores)
        synth_angles_MP_output = Parallel(n_jobs=num_cores, verbose=5)(
            delayed(get_diffraction_angles_MP)(fwd_model_input_i)
            for fwd_model_input_i in fwd_model_input)

        synth_angles = np.vstack(synth_angles_MP_output)

        self.synth_angles = synth_angles
        return synth_angles