Exemple #1
0
def objFuncSX(pFit, pFull, pFlag, dFunc, dFlag,
              xyo_det, hkls_idx, bMat, vInv, wavelength,
              bVec, eVec, omePeriod,
              simOnly=False, returnScalarValue=returnScalarValue):
    """
    """
    npts   = len(xyo_det)

    refineFlag = np.hstack([pFlag, dFlag])

    # pFull[refineFlag] = pFit/scl[refineFlag]
    pFull[refineFlag] = pFit

    dParams = pFull[-len(dFlag):]
    xy_unwarped = dFunc(xyo_det[:, :2], dParams)

    # detector quantities
    rMat_d = xf.makeDetectorRotMat(pFull[:3])
    tVec_d = pFull[3:6].reshape(3, 1)

    # sample quantities
    chi    = pFull[6]
    tVec_s = pFull[7:10].reshape(3, 1)

    # crystal quantities
    rMat_c = xf.makeRotMatOfExpMap(pFull[10:13])
    tVec_c = pFull[13:16].reshape(3, 1)

    gVec_c = np.dot(bMat, hkls_idx)
    vMat_s = mutil.vecMVToSymm(vInv)                # stretch tensor comp matrix from MV notation in SAMPLE frame
    gVec_s = np.dot(vMat_s, np.dot(rMat_c, gVec_c)) # reciprocal lattice vectors in SAMPLE frame
    gHat_s = mutil.unitVector(gVec_s)               # unit reciprocal lattice vectors in SAMPLE frame
    gHat_c = np.dot(rMat_c.T, gHat_s)               # unit reciprocal lattice vectors in CRYSTAL frame

    match_omes, calc_omes = matchOmegas(xyo_det, hkls_idx, chi, rMat_c, bMat, wavelength,
                                        vInv=vInv, beamVec=bVec, etaVec=eVec, omePeriod=omePeriod)

    calc_xy = np.zeros((npts, 2))
    for i in range(npts):
        rMat_s = xfcapi.makeOscillRotMat([chi, calc_omes[i]])
        calc_xy[i, :] = xfcapi.gvecToDetectorXY(gHat_c[:, i],
                                                rMat_d, rMat_s, rMat_c,
                                                tVec_d, tVec_s, tVec_c,
                                                beamVec=bVec).flatten()
        pass
    if np.any(np.isnan(calc_xy)):
        print "infeasible pFull: may want to scale back finite difference step size"

    # return values
    if simOnly:
        retval = np.hstack([calc_xy, calc_omes.reshape(npts, 1)])
    else:
        diff_vecs_xy = calc_xy - xy_unwarped[:, :2]
        diff_ome     = xf.angularDifference( calc_omes, xyo_det[:, 2] )
        retval = np.hstack([diff_vecs_xy,
                            diff_ome.reshape(npts, 1)
                            ]).flatten()
        if returnScalarValue:
            retval = sum( retval )
    return retval
Exemple #2
0
def objFuncSX(pFit, pFull, pFlag, dFunc, dFlag,
              xyo_det, hkls_idx, bMat, vInv, wavelength,
              bVec, eVec, omePeriod,
              simOnly=False, returnScalarValue=returnScalarValue):
    """
    """
    npts   = len(xyo_det)

    refineFlag = np.hstack([pFlag, dFlag])

    # pFull[refineFlag] = pFit/scl[refineFlag]
    pFull[refineFlag] = pFit

    dParams = pFull[-len(dFlag):]
    xy_unwarped = dFunc(xyo_det[:, :2], dParams)

    # detector quantities
    rMat_d = xf.makeDetectorRotMat(pFull[:3])
    tVec_d = pFull[3:6].reshape(3, 1)

    # sample quantities
    chi    = pFull[6]
    tVec_s = pFull[7:10].reshape(3, 1)

    # crystal quantities
    rMat_c = xf.makeRotMatOfExpMap(pFull[10:13])
    tVec_c = pFull[13:16].reshape(3, 1)

    gVec_c = np.dot(bMat, hkls_idx)
    vMat_s = mutil.vecMVToSymm(vInv)                # stretch tensor comp matrix from MV notation in SAMPLE frame
    gVec_s = np.dot(vMat_s, np.dot(rMat_c, gVec_c)) # reciprocal lattice vectors in SAMPLE frame
    gHat_s = mutil.unitVector(gVec_s)               # unit reciprocal lattice vectors in SAMPLE frame
    gHat_c = np.dot(rMat_c.T, gHat_s)               # unit reciprocal lattice vectors in CRYSTAL frame

    match_omes, calc_omes = matchOmegas(xyo_det, hkls_idx, chi, rMat_c, bMat, wavelength,
                                        vInv=vInv, beamVec=bVec, etaVec=eVec, omePeriod=omePeriod)

    calc_xy = np.zeros((npts, 2))
    for i in range(npts):
        rMat_s = xfcapi.makeOscillRotMat([chi, calc_omes[i]])
        calc_xy[i, :] = xfcapi.gvecToDetectorXY(gHat_c[:, i],
                                                rMat_d, rMat_s, rMat_c,
                                                tVec_d, tVec_s, tVec_c,
                                                beamVec=bVec).flatten()
        pass
    if np.any(np.isnan(calc_xy)):
        print "infeasible pFull: may want to scale back finite difference step size"

    # return values
    if simOnly:
        retval = np.hstack([calc_xy, calc_omes.reshape(npts, 1)])
    else:
        diff_vecs_xy = calc_xy - xy_unwarped[:, :2]
        diff_ome     = xf.angularDifference( calc_omes, xyo_det[:, 2] )
        retval = np.hstack([diff_vecs_xy,
                            diff_ome.reshape(npts, 1)
                            ]).flatten()
        if returnScalarValue:
            retval = sum( retval )
    return retval
Exemple #3
0
    def angs_of_xy(self, xy_det, *args):
        """
        vstacked (tth, eta) pairs of cartesian coordinates
        *) wrapper for transforms.detectorXYtoGvec
        
        args: ome, chi
        """
        xy_det = np.atleast_2d(
            xy_det)  # so len() gives right number even if one point
        npts = len(xy_det)
        if len(args) > 0:
            ome = np.atleast_1d(args[0]).flatten()
            assert len(ome) == npts, "ome must be the same length as xy_det!"
            chi = args[1]
            angles = np.zeros((npts, 2))
            gVecs = np.zeros((npts, 3))
            for i in range(npts):
                rMat_s = xf.makeOscillRotMat([chi, ome[i]])
                tmp = xf.detectorXYToGvec(xy_det,
                                          self.rMat,
                                          rMat_s,
                                          self.tVec,
                                          self.tVec_s,
                                          self.tVec_c,
                                          distortion=self.distortion,
                                          beamVec=self.bVec,
                                          etaVec=self.eVec)
                angles[i, :] = tmp[0]
                gVecs[i, :] = tmp[1]
                pass
        else:
            angles, gVecs = xf.detectorXYToGvec(xy_det,
                                                self.rMat,
                                                self.rMat_s,
                                                self.tVec,
                                                self.tVec_s,
                                                self.tVec_c,
                                                distortion=self.distortion,
                                                beamVec=self.bVec,
                                                etaVec=self.eVec)
            pass

        # filter out NaNs
        not_there = np.isnan(angles[:, 0])
        tTh = angles[-not_there, 0]
        eta = angles[-not_there, 1]

        return tTh, eta
Exemple #4
0
 def angs_of_xy(self, xy_det, *args):
     """
     vstacked (tth, eta) pairs of cartesian coordinates
     *) wrapper for transforms.detectorXYtoGvec
     
     args: ome, chi
     """
     xy_det = np.atleast_2d(xy_det) # so len() gives right number even if one point
     npts   = len(xy_det)
     if len(args) > 0:
         ome = np.atleast_1d(args[0]).flatten()
         assert len(ome) == npts, "ome must be the same length as xy_det!"
         chi = args[1]
         angles = np.zeros((npts, 2))
         gVecs  = np.zeros((npts, 3))
         for i in range(npts):
             rMat_s = xf.makeOscillRotMat([chi, ome[i]]) 
             tmp = xf.detectorXYToGvec(xy_det,
                                       self.rMat, rMat_s,
                                       self.tVec, self.tVec_s, self.tVec_c,
                                       distortion=self.distortion,
                                       beamVec=self.bVec,
                                       etaVec=self.eVec)
             angles[i, :] = tmp[0]
             gVecs[i, :]  = tmp[1]
             pass
     else:
         angles, gVecs = xf.detectorXYToGvec(xy_det,
                                             self.rMat, self.rMat_s,
                                             self.tVec, self.tVec_s, self.tVec_c,
                                             distortion=self.distortion,
                                             beamVec=self.bVec,
                                             etaVec=self.eVec)
         pass
     
     # filter out NaNs
     not_there = np.isnan(angles[:, 0])
     tTh = angles[-not_there, 0]
     eta = angles[-not_there, 1]
     
     return tTh, eta
Exemple #5
0
def objFuncFitGrain(gFit, gFull, gFlag,
                    detectorParams,
                    xyo_det, hkls_idx, bMat, wavelength,
                    bVec, eVec,
                    dFunc, dParams,
                    omePeriod,
                    simOnly=False, returnScalarValue=returnScalarValue):
    """
    gFull[0]  = expMap_c[0]
    gFull[1]  = expMap_c[1]
    gFull[2]  = expMap_c[2]
    gFull[3]  = tVec_c[0]
    gFull[4]  = tVec_c[1]
    gFull[5]  = tVec_c[2]
    gFull[6]  = vInv_MV[0]
    gFull[7]  = vInv_MV[1]
    gFull[8]  = vInv_MV[2]
    gFull[9]  = vInv_MV[3]
    gFull[10] = vInv_MV[4]
    gFull[11] = vInv_MV[5]

    detectorParams[0]  = tiltAngles[0]
    detectorParams[1]  = tiltAngles[1]
    detectorParams[2]  = tiltAngles[2]
    detectorParams[3]  = tVec_d[0]
    detectorParams[4]  = tVec_d[1]
    detectorParams[5]  = tVec_d[2]
    detectorParams[6]  = chi
    detectorParams[7]  = tVec_s[0]
    detectorParams[8]  = tVec_s[1]
    detectorParams[9]  = tVec_s[2]
    """
    npts   = len(xyo_det)

    gFull[gFlag] = gFit

    xy_unwarped = dFunc(xyo_det[:, :2], dParams)

    rMat_d = xfcapi.makeDetectorRotMat(detectorParams[:3])
    tVec_d = detectorParams[3:6].reshape(3, 1)
    chi    = detectorParams[6]
    tVec_s = detectorParams[7:10].reshape(3, 1)

    rMat_c = xfcapi.makeRotMatOfExpMap(gFull[:3])
    tVec_c = gFull[3:6].reshape(3, 1)
    vInv_s = gFull[6:]
    vMat_s = mutil.vecMVToSymm(vInv_s)              # NOTE: Inverse of V from F = V * R

    gVec_c = np.dot(bMat, hkls_idx)                 # gVecs with magnitudes in CRYSTAL frame
    gVec_s = np.dot(vMat_s, np.dot(rMat_c, gVec_c)) # stretched gVecs in SAMPLE frame
    gHat_c = mutil.unitVector(
        np.dot(rMat_c.T, gVec_s)) # unit reciprocal lattice vectors in CRYSTAL frame

    match_omes, calc_omes = matchOmegas(xyo_det, hkls_idx, chi, rMat_c, bMat, wavelength,
                                        vInv=vInv_s, beamVec=bVec, etaVec=eVec,
                                        omePeriod=omePeriod)

    calc_xy = np.zeros((npts, 2))
    for i in range(npts):
        rMat_s = xfcapi.makeOscillRotMat([chi, calc_omes[i]])
        calc_xy[i, :] = xfcapi.gvecToDetectorXY(gHat_c[:, i],
                                                rMat_d, rMat_s, rMat_c,
                                                tVec_d, tVec_s, tVec_c,
                                                beamVec=bVec).flatten()
        pass
    if np.any(np.isnan(calc_xy)):
        print "infeasible pFull"

    # return values
    if simOnly:
        retval = np.hstack([calc_xy, calc_omes.reshape(npts, 1)])
    else:
        diff_vecs_xy = calc_xy - xy_unwarped[:, :2]
        diff_ome     = xf.angularDifference( calc_omes, xyo_det[:, 2] )
        retval = mutil.rowNorm(
            np.hstack([diff_vecs_xy,
                       diff_ome.reshape(npts, 1)
                       ]) ).flatten()
        if returnScalarValue:
            retval = sum( retval )
    return retval
Exemple #6
0
def mockup_experiment():
    # user options
    # each grain is provided in the form of a quaternion.

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

    quats = np.array([[ 0.91836393,  0.90869942],
                      [ 0.33952917,  0.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
]])
vHat1 = xf.unitVector(vec.T)
vHat2 = xfcapi.unitRowVector(vec)
print "unitVector results match:             ", np.linalg.norm(
    vHat1.T - vHat2) / np.linalg.norm(vHat1) < epsf

tAng = np.array(
    [0.0011546340766314521, -0.0040527538387122993, -0.0026221336905160211])
rMat1 = xf.makeDetectorRotMat(tAng)
rMat2 = xfcapi.makeDetectorRotMat(tAng)
print "makeDetectorRotMat results match:     ", np.linalg.norm(
    rMat1 - rMat2) / np.linalg.norm(rMat1) < epsf

oAng = np.array([-0.0011591608938627839, 0.0011546340766314521])
rMat1 = xf.makeOscillRotMat(oAng)
rMat2 = xfcapi.makeOscillRotMat(oAng)
print "makeOscillRotMat results match:       ", np.linalg.norm(
    rMat1 - rMat2) / np.linalg.norm(rMat1) < epsf

eMap = np.array([0.66931818, -0.98578066, 0.73593251])
rMat1 = xf.makeRotMatOfExpMap(eMap)
rMat2 = xfcapi.makeRotMatOfExpMap(eMap)
print "makeRotMatOfExpMap results match:     ", np.linalg.norm(
    rMat1 - rMat2) / np.linalg.norm(rMat1) < epsf

axis = np.array([0.66931818, -0.98578066, 0.73593251])
rMat1 = xf.makeBinaryRotMat(axis)
rMat2 = xfcapi.makeBinaryRotMat(axis)
print "makeBinaryRotMat results match:       ", np.linalg.norm(
    rMat1 - rMat2) / np.linalg.norm(rMat1) < epsf
Exemple #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
Exemple #9
0
    def pull_spots(self,
                   plane_data,
                   grain_params,
                   imgser_dict,
                   tth_tol=0.25,
                   eta_tol=1.,
                   ome_tol=1.,
                   npdiv=2,
                   threshold=10,
                   eta_ranges=[
                       (-np.pi, np.pi),
                   ],
                   ome_period=(-np.pi, np.pi),
                   dirname='results',
                   filename=None,
                   output_format='text',
                   save_spot_list=False,
                   quiet=True,
                   check_only=False,
                   interp='nearest'):
        """
        Exctract reflection info from a rotation series encoded as an
        OmegaImageseries object
        """

        # grain parameters
        rMat_c = makeRotMatOfExpMap(grain_params[:3])
        tVec_c = grain_params[3:6]

        # grab omega ranges from first imageseries
        #
        # WARNING: all imageseries AND all wedges within are assumed to have
        # the same omega values; put in a check that they are all the same???
        oims0 = imgser_dict[imgser_dict.keys()[0]]
        ome_ranges = [
            np.radians([i['ostart'], i['ostop']])
            for i in oims0.omegawedges.wedges
        ]

        # delta omega in DEGREES grabbed from first imageseries in the dict
        delta_ome = oims0.omega[0, 1] - oims0.omega[0, 0]

        # make omega grid for frame expansion around reference frame
        # in DEGREES
        ndiv_ome, ome_del = make_tolerance_grid(
            delta_ome,
            ome_tol,
            1,
            adjust_window=True,
        )

        # generate structuring element for connected component labeling
        if ndiv_ome == 1:
            label_struct = ndimage.generate_binary_structure(2, 2)
        else:
            label_struct = ndimage.generate_binary_structure(3, 3)

        # simulate rotation series
        sim_results = self.simulate_rotation_series(plane_data, [
            grain_params,
        ],
                                                    eta_ranges=eta_ranges,
                                                    ome_ranges=ome_ranges,
                                                    ome_period=ome_period)

        # patch vertex generator (global for instrument)
        tol_vec = 0.5 * np.radians([
            -tth_tol, -eta_tol, -tth_tol, eta_tol, tth_tol, eta_tol, tth_tol,
            -eta_tol
        ])

        # prepare output if requested
        if filename is not None and output_format.lower() == 'hdf5':
            this_filename = os.path.join(dirname, filename)
            writer = io.GrainDataWriter_h5(os.path.join(dirname, filename),
                                           self.write_config(), grain_params)

        # =====================================================================
        # LOOP OVER PANELS
        # =====================================================================
        iRefl = 0
        compl = []
        output = dict.fromkeys(self.detectors)
        for detector_id in self.detectors:
            # initialize text-based output writer
            if filename is not None and output_format.lower() == 'text':
                output_dir = os.path.join(dirname, detector_id)
                if not os.path.exists(output_dir):
                    os.makedirs(output_dir)
                this_filename = os.path.join(output_dir, filename)
                writer = io.PatchDataWriter(this_filename)

            # grab panel
            panel = self.detectors[detector_id]
            instr_cfg = panel.config_dict(self.chi, self.tvec)
            native_area = panel.pixel_area  # pixel ref area

            # pull out the OmegaImageSeries for this panel from input dict
            ome_imgser = imgser_dict[detector_id]

            # extract simulation results
            sim_results_p = sim_results[detector_id]
            hkl_ids = sim_results_p[0][0]
            hkls_p = sim_results_p[1][0]
            ang_centers = sim_results_p[2][0]
            xy_centers = sim_results_p[3][0]
            ang_pixel_size = sim_results_p[4][0]

            # now verify that full patch falls on detector...
            # ???: strictly necessary?
            #
            # patch vertex array from sim
            nangs = len(ang_centers)
            patch_vertices = (np.tile(ang_centers[:, :2],
                                      (1, 4)) + np.tile(tol_vec,
                                                        (nangs, 1))).reshape(
                                                            4 * nangs, 2)
            ome_dupl = np.tile(ang_centers[:, 2],
                               (4, 1)).T.reshape(len(patch_vertices), 1)

            # find vertices that all fall on the panel
            det_xy, _ = xrdutil._project_on_detector_plane(
                np.hstack([patch_vertices, ome_dupl]), panel.rmat, rMat_c,
                self.chi, panel.tvec, tVec_c, self.tvec, panel.distortion)
            _, on_panel = panel.clip_to_panel(det_xy, buffer_edges=True)

            # all vertices must be on...
            patch_is_on = np.all(on_panel.reshape(nangs, 4), axis=1)
            patch_xys = det_xy.reshape(nangs, 4, 2)[patch_is_on]

            # re-filter...
            hkl_ids = hkl_ids[patch_is_on]
            hkls_p = hkls_p[patch_is_on, :]
            ang_centers = ang_centers[patch_is_on, :]
            xy_centers = xy_centers[patch_is_on, :]
            ang_pixel_size = ang_pixel_size[patch_is_on, :]

            # TODO: add polygon testing right here!
            # done <JVB 06/21/16>
            if check_only:
                patch_output = []
                for i_pt, angs in enumerate(ang_centers):
                    # the evaluation omegas;
                    # expand about the central value using tol vector
                    ome_eval = np.degrees(angs[2]) + ome_del

                    # ...vectorize the omega_to_frame function to avoid loop?
                    frame_indices = [
                        ome_imgser.omega_to_frame(ome)[0] for ome in ome_eval
                    ]
                    if -1 in frame_indices:
                        if not quiet:
                            msg = """
                            window for (%d%d%d) falls outside omega range
                            """ % tuple(hkls_p[i_pt, :])
                            print(msg)
                        continue
                    else:
                        these_vertices = patch_xys[i_pt]
                        ijs = panel.cartToPixel(these_vertices)
                        ii, jj = polygon(ijs[:, 0], ijs[:, 1])
                        contains_signal = False
                        for i_frame in frame_indices:
                            contains_signal = contains_signal or np.any(
                                ome_imgser[i_frame][ii, jj] > threshold)
                        compl.append(contains_signal)
                        patch_output.append((ii, jj, frame_indices))
            else:
                # make the tth,eta patches for interpolation
                patches = xrdutil.make_reflection_patches(
                    instr_cfg,
                    ang_centers[:, :2],
                    ang_pixel_size,
                    omega=ang_centers[:, 2],
                    tth_tol=tth_tol,
                    eta_tol=eta_tol,
                    rMat_c=rMat_c,
                    tVec_c=tVec_c,
                    distortion=panel.distortion,
                    npdiv=npdiv,
                    quiet=True,
                    beamVec=self.beam_vector)

                # GRAND LOOP over reflections for this panel
                patch_output = []
                for i_pt, patch in enumerate(patches):

                    # strip relevant objects out of current patch
                    vtx_angs, vtx_xy, conn, areas, xy_eval, ijs = patch

                    prows, pcols = areas.shape
                    nrm_fac = areas / float(native_area)
                    nrm_fac = nrm_fac / np.min(nrm_fac)

                    # grab hkl info
                    hkl = hkls_p[i_pt, :]
                    hkl_id = hkl_ids[i_pt]

                    # edge arrays
                    tth_edges = vtx_angs[0][0, :]
                    delta_tth = tth_edges[1] - tth_edges[0]
                    eta_edges = vtx_angs[1][:, 0]
                    delta_eta = eta_edges[1] - eta_edges[0]

                    # need to reshape eval pts for interpolation
                    xy_eval = np.vstack(
                        [xy_eval[0].flatten(), xy_eval[1].flatten()]).T

                    # the evaluation omegas;
                    # expand about the central value using tol vector
                    ome_eval = np.degrees(ang_centers[i_pt, 2]) + ome_del

                    # ???: vectorize the omega_to_frame function to avoid loop?
                    frame_indices = [
                        ome_imgser.omega_to_frame(ome)[0] for ome in ome_eval
                    ]

                    if -1 in frame_indices:
                        if not quiet:
                            msg = """
                            window for (%d%d%d) falls outside omega range
                            """ % tuple(hkl)
                            print(msg)
                        continue
                    else:
                        # initialize spot data parameters
                        # !!! maybe change these to nan to not f**k up writer
                        peak_id = -999
                        sum_int = None
                        max_int = None
                        meas_angs = None
                        meas_xy = None

                        # quick check for intensity
                        contains_signal = False
                        patch_data_raw = []
                        for i_frame in frame_indices:
                            tmp = ome_imgser[i_frame][ijs[0], ijs[1]]
                            contains_signal = contains_signal or np.any(
                                tmp > threshold)
                            patch_data_raw.append(tmp)
                            pass
                        patch_data_raw = np.stack(patch_data_raw, axis=0)
                        compl.append(contains_signal)

                        if contains_signal:
                            # initialize patch data array for intensities
                            if interp.lower() == 'bilinear':
                                patch_data = np.zeros(
                                    (len(frame_indices), prows, pcols))
                                for i, i_frame in enumerate(frame_indices):
                                    patch_data[i] = \
                                        panel.interpolate_bilinear(
                                            xy_eval,
                                            ome_imgser[i_frame],
                                            pad_with_nans=False
                                        ).reshape(prows, pcols)  # * nrm_fac
                            elif interp.lower() == 'nearest':
                                patch_data = patch_data_raw  # * nrm_fac
                            else:
                                msg = "interpolation option " + \
                                    "'%s' not understood"
                                raise (RuntimeError, msg % interp)

                            # now have interpolated patch data...
                            labels, num_peaks = ndimage.label(
                                patch_data > threshold, structure=label_struct)
                            slabels = np.arange(1, num_peaks + 1)

                            if num_peaks > 0:
                                peak_id = iRefl
                                coms = np.array(
                                    ndimage.center_of_mass(patch_data,
                                                           labels=labels,
                                                           index=slabels))
                                if num_peaks > 1:
                                    center = np.r_[patch_data.shape] * 0.5
                                    center_t = np.tile(center, (num_peaks, 1))
                                    com_diff = coms - center_t
                                    closest_peak_idx = np.argmin(
                                        np.sum(com_diff**2, axis=1))
                                else:
                                    closest_peak_idx = 0
                                    pass  # end multipeak conditional
                                coms = coms[closest_peak_idx]
                                # meas_omes = \
                                #     ome_edges[0] + (0.5 + coms[0])*delta_ome
                                meas_omes = \
                                    ome_eval[0] + coms[0]*delta_ome
                                meas_angs = np.hstack([
                                    tth_edges[0] + (0.5 + coms[2]) * delta_tth,
                                    eta_edges[0] + (0.5 + coms[1]) * delta_eta,
                                    mapAngle(np.radians(meas_omes), ome_period)
                                ])

                                # intensities
                                #   - summed is 'integrated' over interpolated
                                #     data
                                #   - max is max of raw input data
                                sum_int = np.sum(patch_data[
                                    labels == slabels[closest_peak_idx]])
                                max_int = np.max(patch_data_raw[
                                    labels == slabels[closest_peak_idx]])
                                # ???: Should this only use labeled pixels?
                                # Those are segmented from interpolated data,
                                # not raw; likely ok in most cases.

                                # need MEASURED xy coords
                                gvec_c = anglesToGVec(meas_angs,
                                                      chi=self.chi,
                                                      rMat_c=rMat_c,
                                                      bHat_l=self.beam_vector)
                                rMat_s = makeOscillRotMat(
                                    [self.chi, meas_angs[2]])
                                meas_xy = gvecToDetectorXY(
                                    gvec_c,
                                    panel.rmat,
                                    rMat_s,
                                    rMat_c,
                                    panel.tvec,
                                    self.tvec,
                                    tVec_c,
                                    beamVec=self.beam_vector)
                                if panel.distortion is not None:
                                    # FIXME: distortion handling
                                    meas_xy = panel.distortion[0](
                                        np.atleast_2d(meas_xy),
                                        panel.distortion[1],
                                        invert=True).flatten()
                                    pass
                                # FIXME: why is this suddenly necessary???
                                meas_xy = meas_xy.squeeze()
                                pass  # end num_peaks > 0
                        else:
                            patch_data = patch_data_raw
                            pass  # end contains_signal
                        # write output
                        if filename is not None:
                            if output_format.lower() == 'text':
                                writer.dump_patch(peak_id, hkl_id, hkl,
                                                  sum_int, max_int,
                                                  ang_centers[i_pt], meas_angs,
                                                  xy_centers[i_pt], meas_xy)
                            elif output_format.lower() == 'hdf5':
                                xyc_arr = xy_eval.reshape(prows, pcols,
                                                          2).transpose(
                                                              2, 0, 1)
                                writer.dump_patch(
                                    detector_id, iRefl, peak_id, hkl_id,
                                    hkl, tth_edges, eta_edges,
                                    np.radians(ome_eval), xyc_arr, ijs,
                                    frame_indices, patch_data,
                                    ang_centers[i_pt], xy_centers[i_pt],
                                    meas_angs, meas_xy)
                            pass  # end conditional on write output
                        pass  # end conditional on check only
                        patch_output.append([
                            peak_id,
                            hkl_id,
                            hkl,
                            sum_int,
                            max_int,
                            ang_centers[i_pt],
                            meas_angs,
                            meas_xy,
                        ])
                        iRefl += 1
                    pass  # end patch conditional
                pass  # end patch loop
            output[detector_id] = patch_output
            if filename is not None and output_format.lower() == 'text':
                writer.close()
            pass  # end detector loop
        if filename is not None and output_format.lower() == 'hdf5':
            writer.close()
        return compl, output
Exemple #10
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.
    
    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
Exemple #11
0
    pass
ome_edges = np.arange(nframes + 1) * ome_step

#==============================================================================
# %% INSTRUMENT
#==============================================================================
# load config
instr_cfg = yaml.load(open('./retiga.yml', 'r'))

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 = 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])]
Exemple #12
0
def objFuncSX(pFit,
              pFull,
              pFlag,
              dFunc,
              dFlag,
              xyo_det,
              hkls_idx,
              bMat,
              vInv,
              bVec,
              eVec,
              omePeriod,
              simOnly=False,
              return_value_flag=return_value_flag):
    """
    """
    npts = len(xyo_det)

    refineFlag = np.array(np.hstack([pFlag, dFlag]), dtype=bool)
    print refineFlag

    # pFull[refineFlag] = pFit/scl[refineFlag]
    pFull[refineFlag] = pFit

    if dFunc is not None:
        dParams = pFull[-len(dFlag):]
        xys = dFunc(xyo_det[:, :2], dParams)
    else:
        xys = xyo_det[:, :2]

    # detector quantities
    wavelength = pFull[0]

    rMat_d = xf.makeDetectorRotMat(pFull[1:4])
    tVec_d = pFull[4:7].reshape(3, 1)

    # sample quantities
    chi = pFull[7]
    tVec_s = pFull[8:11].reshape(3, 1)

    # crystal quantities
    rMat_c = xf.makeRotMatOfExpMap(pFull[11:14])
    tVec_c = pFull[14:17].reshape(3, 1)

    # stretch tensor comp matrix from MV notation in SAMPLE frame
    vMat_s = mutil.vecMVToSymm(vInv)

    # g-vectors:
    #   1. calculate full g-vector components in CRYSTAL frame from B
    #   2. rotate into SAMPLE frame and apply stretch
    #   3. rotate back into CRYSTAL frame and normalize to unit magnitude
    # IDEA: make a function for this sequence of operations with option for
    # choosing ouput frame (i.e. CRYSTAL vs SAMPLE vs LAB)
    gVec_c = np.dot(bMat, hkls_idx)
    gVec_s = np.dot(vMat_s, np.dot(rMat_c, gVec_c))
    gHat_c = mutil.unitVector(np.dot(rMat_c.T, gVec_s))

    match_omes, calc_omes = matchOmegas(xyo_det,
                                        hkls_idx,
                                        chi,
                                        rMat_c,
                                        bMat,
                                        wavelength,
                                        vInv=vInv,
                                        beamVec=bVec,
                                        etaVec=eVec,
                                        omePeriod=omePeriod)

    calc_xy = np.zeros((npts, 2))
    for i in range(npts):
        rMat_s = xfcapi.makeOscillRotMat([chi, calc_omes[i]])
        calc_xy[i, :] = xfcapi.gvecToDetectorXY(gHat_c[:, i],
                                                rMat_d,
                                                rMat_s,
                                                rMat_c,
                                                tVec_d,
                                                tVec_s,
                                                tVec_c,
                                                beamVec=bVec).flatten()
        pass
    if np.any(np.isnan(calc_xy)):
        raise RuntimeError("infeasible pFull: may want to scale" +
                           "back finite difference step size")

    # return values
    if simOnly:
        # return simulated values
        retval = np.hstack([calc_xy, calc_omes.reshape(npts, 1)])
    else:
        # return residual vector
        # IDEA: try angles instead of xys?
        diff_vecs_xy = calc_xy - xys[:, :2]
        diff_ome = xf.angularDifference(calc_omes, xyo_det[:, 2])
        retval = np.hstack([diff_vecs_xy, diff_ome.reshape(npts, 1)]).flatten()
        if return_value_flag == 1:
            # return scalar sum of squared residuals
            retval = sum(abs(retval))
        elif return_value_flag == 2:
            # return DOF-normalized chisq
            # TODO: check this calculation
            denom = npts - len(pFit) - 1.
            if denom != 0:
                nu_fac = 1. / denom
            else:
                nu_fac = 1.
            nu_fac = 1 / (npts - len(pFit) - 1.)
            retval = nu_fac * sum(retval**2)
    return retval
def make_reflection_patches(
    instr_cfg,
    tth_eta,
    ang_pixel_size,
    omega=None,
    tth_tol=0.2,
    eta_tol=1.0,
    rMat_c=np.eye(3),
    tVec_c=np.c_[0.0, 0.0, 0.0].T,
    distortion=distortion,
    npdiv=1,
    quiet=False,
    compute_areas_func=compute_areas,
):
    """
    prototype function for making angular patches on a detector

    panel_dims are [(xmin, ymin), (xmax, ymax)] in mm

    pixel_pitch is [row_size, column_size] in mm

    DISTORTION HANDING IS STILL A KLUDGE

    patches are:

                 delta tth
   d  ------------- ... -------------
   e  | x | x | x | ... | x | x | x |
   l  ------------- ... -------------
   t                 .
   a                 .
                     .
   e  ------------- ... -------------
   t  | x | x | x | ... | x | x | x |
   a  ------------- ... -------------

    """
    npts = len(tth_eta)

    # detector frame
    rMat_d = xfcapi.makeDetectorRotMat(instr_cfg["detector"]["transform"]["tilt_angles"])
    tVec_d = np.r_[instr_cfg["detector"]["transform"]["t_vec_d"]]
    pixel_size = instr_cfg["detector"]["pixels"]["size"]

    frame_nrows = instr_cfg["detector"]["pixels"]["rows"]
    frame_ncols = instr_cfg["detector"]["pixels"]["columns"]

    panel_dims = (
        -0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]],
        0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]],
    )
    row_edges = np.arange(frame_nrows + 1)[::-1] * pixel_size[1] + panel_dims[0][1]
    col_edges = np.arange(frame_ncols + 1) * pixel_size[0] + panel_dims[0][0]

    # sample frame
    chi = instr_cfg["oscillation_stage"]["chi"]
    tVec_s = np.r_[instr_cfg["oscillation_stage"]["t_vec_s"]]

    # data to loop
    # ...WOULD IT BE CHEAPER TO CARRY ZEROS OR USE CONDITIONAL?
    if omega is None:
        full_angs = np.hstack([tth_eta, np.zeros((npts, 1))])
    else:
        full_angs = np.hstack([tth_eta, omega.reshape(npts, 1)])
    patches = []
    for angs, pix in zip(full_angs, ang_pixel_size):
        # need to get angular pixel size
        rMat_s = xfcapi.makeOscillRotMat([chi, angs[2]])

        ndiv_tth = npdiv * np.ceil(tth_tol / np.degrees(pix[0]))
        ndiv_eta = npdiv * np.ceil(eta_tol / np.degrees(pix[1]))

        tth_del = np.arange(0, ndiv_tth + 1) * tth_tol / float(ndiv_tth) - 0.5 * tth_tol
        eta_del = np.arange(0, ndiv_eta + 1) * eta_tol / float(ndiv_eta) - 0.5 * eta_tol

        # store dimensions for convenience
        #   * etas and tths are bin vertices, ome is already centers
        sdims = [len(eta_del) - 1, len(tth_del) - 1]

        # meshgrid args are (cols, rows), a.k.a (fast, slow)
        m_tth, m_eta = np.meshgrid(tth_del, eta_del)
        npts_patch = m_tth.size

        # calculate the patch XY coords from the (tth, eta) angles
        # * will CHEAT and ignore the small perturbation the different
        #   omega angle values causes and simply use the central value
        gVec_angs_vtx = np.tile(angs, (npts_patch, 1)) + np.radians(
            np.vstack([m_tth.flatten(), m_eta.flatten(), np.zeros(npts_patch)]).T
        )

        # will need this later
        rMat_s = xfcapi.makeOscillRotMat([chi, angs[2]])

        # FOR ANGULAR MESH
        conn = gutil.cellConnectivity(sdims[0], sdims[1], origin="ll")
        gVec_c = xf.anglesToGVec(gVec_angs_vtx, xf.bVec_ref, xf.eta_ref, rMat_s=rMat_s, rMat_c=rMat_c)

        xy_eval_vtx = xfcapi.gvecToDetectorXY(gVec_c.T, rMat_d, rMat_s, rMat_c, tVec_d, tVec_s, tVec_c)
        if distortion is not None and len(distortion) == 2:
            xy_eval_vtx = distortion[0](xy_eval_vtx, distortion[1], invert=True)
            pass

        areas = compute_areas_func(xy_eval_vtx, conn)

        # EVALUATION POINTS
        #   * for lack of a better option will use centroids
        tth_eta_cen = gutil.cellCentroids(np.atleast_2d(gVec_angs_vtx[:, :2]), conn)
        gVec_angs = np.hstack([tth_eta_cen, np.tile(angs[2], (len(tth_eta_cen), 1))])
        gVec_c = xf.anglesToGVec(gVec_angs, xf.bVec_ref, xf.eta_ref, rMat_s=rMat_s, rMat_c=rMat_c)

        xy_eval = xfcapi.gvecToDetectorXY(gVec_c.T, rMat_d, rMat_s, rMat_c, tVec_d, tVec_s, tVec_c)
        if distortion is not None and len(distortion) == 2:
            xy_eval = distortion[0](xy_eval, distortion[1], invert=True)
            pass
        row_indices = gutil.cellIndices(row_edges, xy_eval[:, 1])
        col_indices = gutil.cellIndices(col_edges, xy_eval[:, 0])

        patches.append(
            (
                (gVec_angs_vtx[:, 0].reshape(m_tth.shape), gVec_angs_vtx[:, 1].reshape(m_tth.shape)),
                (xy_eval_vtx[:, 0].reshape(m_tth.shape), xy_eval_vtx[:, 1].reshape(m_tth.shape)),
                conn,
                areas.reshape(sdims[0], sdims[1]),
                (row_indices.reshape(sdims[0], sdims[1]), col_indices.reshape(sdims[0], sdims[1])),
            )
        )
        pass
    return patches
Exemple #14
0
def objFuncFitGrain(gFit,
                    gFull,
                    gFlag,
                    detectorParams,
                    xyo_det,
                    hkls_idx,
                    bMat,
                    wavelength,
                    bVec,
                    eVec,
                    dFunc,
                    dParams,
                    omePeriod,
                    simOnly=False,
                    returnScalarValue=returnScalarValue):
    """
    gFull[0]  = expMap_c[0]
    gFull[1]  = expMap_c[1]
    gFull[2]  = expMap_c[2]
    gFull[3]  = tVec_c[0]
    gFull[4]  = tVec_c[1]
    gFull[5]  = tVec_c[2]
    gFull[6]  = vInv_MV[0]
    gFull[7]  = vInv_MV[1]
    gFull[8]  = vInv_MV[2]
    gFull[9]  = vInv_MV[3]
    gFull[10] = vInv_MV[4]
    gFull[11] = vInv_MV[5]

    detectorParams[0]  = tiltAngles[0]
    detectorParams[1]  = tiltAngles[1]
    detectorParams[2]  = tiltAngles[2]
    detectorParams[3]  = tVec_d[0]
    detectorParams[4]  = tVec_d[1]
    detectorParams[5]  = tVec_d[2]
    detectorParams[6]  = chi
    detectorParams[7]  = tVec_s[0]
    detectorParams[8]  = tVec_s[1]
    detectorParams[9]  = tVec_s[2]
    """
    npts = len(xyo_det)

    gFull[gFlag] = gFit

    xy_unwarped = dFunc(xyo_det[:, :2], dParams)

    rMat_d = xfcapi.makeDetectorRotMat(detectorParams[:3])
    tVec_d = detectorParams[3:6].reshape(3, 1)
    chi = detectorParams[6]
    tVec_s = detectorParams[7:10].reshape(3, 1)

    rMat_c = xfcapi.makeRotMatOfExpMap(gFull[:3])
    tVec_c = gFull[3:6].reshape(3, 1)
    vInv_s = gFull[6:]
    vMat_s = mutil.vecMVToSymm(vInv_s)  # NOTE: Inverse of V from F = V * R

    gVec_c = np.dot(bMat, hkls_idx)  # gVecs with magnitudes in CRYSTAL frame
    gVec_s = np.dot(vMat_s, np.dot(rMat_c,
                                   gVec_c))  # stretched gVecs in SAMPLE frame
    gHat_c = mutil.unitVector(np.dot(
        rMat_c.T, gVec_s))  # unit reciprocal lattice vectors in CRYSTAL frame

    match_omes, calc_omes = matchOmegas(xyo_det,
                                        hkls_idx,
                                        chi,
                                        rMat_c,
                                        bMat,
                                        wavelength,
                                        vInv=vInv_s,
                                        beamVec=bVec,
                                        etaVec=eVec,
                                        omePeriod=omePeriod)

    calc_xy = np.zeros((npts, 2))
    for i in range(npts):
        rMat_s = xfcapi.makeOscillRotMat([chi, calc_omes[i]])
        calc_xy[i, :] = xfcapi.gvecToDetectorXY(gHat_c[:, i],
                                                rMat_d,
                                                rMat_s,
                                                rMat_c,
                                                tVec_d,
                                                tVec_s,
                                                tVec_c,
                                                beamVec=bVec).flatten()
        pass
    if np.any(np.isnan(calc_xy)):
        print "infeasible pFull"

    # return values
    if simOnly:
        retval = np.hstack([calc_xy, calc_omes.reshape(npts, 1)])
    else:
        diff_vecs_xy = calc_xy - xy_unwarped[:, :2]
        diff_ome = xf.angularDifference(calc_omes, xyo_det[:, 2])
        retval = np.hstack([diff_vecs_xy, diff_ome.reshape(npts, 1)]).flatten()
        if returnScalarValue:
            retval = sum(retval)
    return retval
Exemple #15
0
    pass
ome_edges = np.arange(nframes+1)*ome_step

#==============================================================================
# %% INSTRUMENT
#==============================================================================
# load config
instr_cfg = yaml.load(open('./retiga.yml', 'r'))

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 = 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],
Exemple #16
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
Exemple #17
0
epsf = 2.2e-16

vec = np.array([[random.uniform(-np.pi,np.pi),random.uniform(-np.pi,np.pi),random.uniform(-np.pi,np.pi)]])
vHat1 = xf.unitVector(vec.T)
vHat2 = xfcapi.unitRowVector(vec)
print "unitVector results match:             ",np.linalg.norm(vHat1.T-vHat2)/np.linalg.norm(vHat1) < epsf

tAng = np.array([0.0011546340766314521,-0.0040527538387122993,-0.0026221336905160211])
rMat1 = xf.makeDetectorRotMat(tAng)
rMat2 = xfcapi.makeDetectorRotMat(tAng)
print "makeDetectorRotMat results match:     ",np.linalg.norm(rMat1-rMat2)/np.linalg.norm(rMat1) < epsf

oAng = np.array([-0.0011591608938627839,0.0011546340766314521])
rMat1 = xf.makeOscillRotMat(oAng)
rMat2 = xfcapi.makeOscillRotMat(oAng)
print "makeOscillRotMat results match:       ",np.linalg.norm(rMat1-rMat2)/np.linalg.norm(rMat1) < epsf

eMap = np.array([ 0.66931818,-0.98578066,0.73593251])
rMat1 = xf.makeRotMatOfExpMap(eMap)
rMat2 = xfcapi.makeRotMatOfExpMap(eMap)
print "makeRotMatOfExpMap results match:     ",np.linalg.norm(rMat1-rMat2)/np.linalg.norm(rMat1) < epsf

axis = np.array([ 0.66931818,-0.98578066,0.73593251])
rMat1 = xf.makeBinaryRotMat(axis)
rMat2 = xfcapi.makeBinaryRotMat(axis)
print "makeBinaryRotMat results match:       ",np.linalg.norm(rMat1-rMat2)/np.linalg.norm(rMat1) < epsf

bHat = np.array([0.0,0.0,-1.0])
eta  = np.array([1.0,0.0,0.0])
rMat1 = xf.makeEtaFrameRotMat(bHat,eta)
Exemple #18
0
def objFuncSX(pFit, pFull, pFlag, dFunc, dFlag,
              xyo_det, hkls_idx, bMat, vInv,
              bVec, eVec, omePeriod,
              simOnly=False, return_value_flag=return_value_flag):
    """
    """
    npts = len(xyo_det)

    refineFlag = np.array(np.hstack([pFlag, dFlag]), dtype=bool)
    print refineFlag

    # pFull[refineFlag] = pFit/scl[refineFlag]
    pFull[refineFlag] = pFit

    if dFunc is not None:
        dParams = pFull[-len(dFlag):]
        xys = dFunc(xyo_det[:, :2], dParams)
    else:
        xys = xyo_det[:, :2]

    # detector quantities
    wavelength = pFull[0]

    rMat_d = xf.makeDetectorRotMat(pFull[1:4])
    tVec_d = pFull[4:7].reshape(3, 1)

    # sample quantities
    chi = pFull[7]
    tVec_s = pFull[8:11].reshape(3, 1)

    # crystal quantities
    rMat_c = xf.makeRotMatOfExpMap(pFull[11:14])
    tVec_c = pFull[14:17].reshape(3, 1)

    # stretch tensor comp matrix from MV notation in SAMPLE frame
    vMat_s = mutil.vecMVToSymm(vInv)

    # g-vectors:
    #   1. calculate full g-vector components in CRYSTAL frame from B
    #   2. rotate into SAMPLE frame and apply stretch
    #   3. rotate back into CRYSTAL frame and normalize to unit magnitude
    # IDEA: make a function for this sequence of operations with option for
    # choosing ouput frame (i.e. CRYSTAL vs SAMPLE vs LAB)
    gVec_c = np.dot(bMat, hkls_idx)
    gVec_s = np.dot(vMat_s, np.dot(rMat_c, gVec_c))
    gHat_c = mutil.unitVector(np.dot(rMat_c.T, gVec_s))

    match_omes, calc_omes = matchOmegas(
            xyo_det, hkls_idx, chi, rMat_c, bMat, wavelength,
            vInv=vInv, beamVec=bVec, etaVec=eVec, omePeriod=omePeriod)

    calc_xy = np.zeros((npts, 2))
    for i in range(npts):
        rMat_s = xfcapi.makeOscillRotMat([chi, calc_omes[i]])
        calc_xy[i, :] = xfcapi.gvecToDetectorXY(gHat_c[:, i],
                                                rMat_d, rMat_s, rMat_c,
                                                tVec_d, tVec_s, tVec_c,
                                                beamVec=bVec).flatten()
        pass
    if np.any(np.isnan(calc_xy)):
        raise RuntimeError(
            "infeasible pFull: may want to scale" +
            "back finite difference step size")

    # return values
    if simOnly:
        # return simulated values
        retval = np.hstack([calc_xy, calc_omes.reshape(npts, 1)])
    else:
        # return residual vector
        # IDEA: try angles instead of xys?
        diff_vecs_xy = calc_xy - xys[:, :2]
        diff_ome = xf.angularDifference(calc_omes, xyo_det[:, 2])
        retval = np.hstack([diff_vecs_xy,
                            diff_ome.reshape(npts, 1)
                            ]).flatten()
        if return_value_flag == 1:
            # return scalar sum of squared residuals
            retval = sum(abs(retval))
        elif return_value_flag == 2:
            # return DOF-normalized chisq
            # TODO: check this calculation
            denom = npts - len(pFit) - 1.
            if denom != 0:
                nu_fac = 1. / denom
            else:
                nu_fac = 1.
            nu_fac = 1 / (npts - len(pFit) - 1.)
            retval = nu_fac * sum(retval**2)
    return retval
Exemple #19
0
def make_reflection_patches(instr_cfg,
                            tth_eta,
                            ang_pixel_size,
                            omega=None,
                            tth_tol=0.2,
                            eta_tol=1.0,
                            rMat_c=np.eye(3),
                            tVec_c=np.c_[0., 0., 0.].T,
                            distortion=distortion,
                            npdiv=1,
                            quiet=False,
                            compute_areas_func=compute_areas):
    """
    prototype function for making angular patches on a detector

    panel_dims are [(xmin, ymin), (xmax, ymax)] in mm

    pixel_pitch is [row_size, column_size] in mm

    DISTORTION HANDING IS STILL A KLUDGE

    patches are:

                 delta tth
   d  ------------- ... -------------
   e  | x | x | x | ... | x | x | x |
   l  ------------- ... -------------
   t                 .
   a                 .
                     .
   e  ------------- ... -------------
   t  | x | x | x | ... | x | x | x |
   a  ------------- ... -------------

    """
    npts = len(tth_eta)

    # detector frame
    rMat_d = xfcapi.makeDetectorRotMat(
        instr_cfg['detector']['transform']['tilt_angles'])
    tVec_d = np.r_[instr_cfg['detector']['transform']['t_vec_d']]
    pixel_size = instr_cfg['detector']['pixels']['size']

    frame_nrows = instr_cfg['detector']['pixels']['rows']
    frame_ncols = instr_cfg['detector']['pixels']['columns']

    panel_dims = (
        -0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]],
        0.5 * np.r_[frame_ncols * pixel_size[1], frame_nrows * pixel_size[0]])
    row_edges = np.arange(frame_nrows +
                          1)[::-1] * pixel_size[1] + panel_dims[0][1]
    col_edges = np.arange(frame_ncols + 1) * pixel_size[0] + panel_dims[0][0]

    # sample frame
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.r_[instr_cfg['oscillation_stage']['t_vec_s']]

    # data to loop
    # ...WOULD IT BE CHEAPER TO CARRY ZEROS OR USE CONDITIONAL?
    if omega is None:
        full_angs = np.hstack([tth_eta, np.zeros((npts, 1))])
    else:
        full_angs = np.hstack([tth_eta, omega.reshape(npts, 1)])
    patches = []
    for angs, pix in zip(full_angs, ang_pixel_size):
        # need to get angular pixel size
        rMat_s = xfcapi.makeOscillRotMat([chi, angs[2]])

        ndiv_tth = npdiv * np.ceil(tth_tol / np.degrees(pix[0]))
        ndiv_eta = npdiv * np.ceil(eta_tol / np.degrees(pix[1]))

        tth_del = np.arange(
            0, ndiv_tth + 1) * tth_tol / float(ndiv_tth) - 0.5 * tth_tol
        eta_del = np.arange(
            0, ndiv_eta + 1) * eta_tol / float(ndiv_eta) - 0.5 * eta_tol

        # store dimensions for convenience
        #   * etas and tths are bin vertices, ome is already centers
        sdims = [len(eta_del) - 1, len(tth_del) - 1]

        # meshgrid args are (cols, rows), a.k.a (fast, slow)
        m_tth, m_eta = np.meshgrid(tth_del, eta_del)
        npts_patch = m_tth.size

        # calculate the patch XY coords from the (tth, eta) angles
        # * will CHEAT and ignore the small perturbation the different
        #   omega angle values causes and simply use the central value
        gVec_angs_vtx = np.tile(angs, (npts_patch, 1)) \
                        + np.radians(
                            np.vstack([m_tth.flatten(),
                                       m_eta.flatten(),
                                       np.zeros(npts_patch)
                                       ]).T
                                     )

        # will need this later
        rMat_s = xfcapi.makeOscillRotMat([chi, angs[2]])

        # FOR ANGULAR MESH
        conn = gutil.cellConnectivity(sdims[0], sdims[1], origin='ll')
        gVec_c = xf.anglesToGVec(gVec_angs_vtx,
                                 xf.bVec_ref,
                                 xf.eta_ref,
                                 rMat_s=rMat_s,
                                 rMat_c=rMat_c)

        xy_eval_vtx = xfcapi.gvecToDetectorXY(gVec_c.T, rMat_d, rMat_s, rMat_c,
                                              tVec_d, tVec_s, tVec_c)
        if distortion is not None and len(distortion) == 2:
            xy_eval_vtx = distortion[0](xy_eval_vtx,
                                        distortion[1],
                                        invert=True)
            pass

        areas = compute_areas_func(xy_eval_vtx, conn)

        # EVALUATION POINTS
        #   * for lack of a better option will use centroids
        tth_eta_cen = gutil.cellCentroids(np.atleast_2d(gVec_angs_vtx[:, :2]),
                                          conn)
        gVec_angs = np.hstack(
            [tth_eta_cen, np.tile(angs[2], (len(tth_eta_cen), 1))])
        gVec_c = xf.anglesToGVec(gVec_angs,
                                 xf.bVec_ref,
                                 xf.eta_ref,
                                 rMat_s=rMat_s,
                                 rMat_c=rMat_c)

        xy_eval = xfcapi.gvecToDetectorXY(gVec_c.T, rMat_d, rMat_s, rMat_c,
                                          tVec_d, tVec_s, tVec_c)
        if distortion is not None and len(distortion) == 2:
            xy_eval = distortion[0](xy_eval, distortion[1], invert=True)
            pass
        row_indices = gutil.cellIndices(row_edges, xy_eval[:, 1])
        col_indices = gutil.cellIndices(col_edges, xy_eval[:, 0])

        patches.append(
            ((gVec_angs_vtx[:, 0].reshape(m_tth.shape),
              gVec_angs_vtx[:, 1].reshape(m_tth.shape)),
             (xy_eval_vtx[:, 0].reshape(m_tth.shape),
              xy_eval_vtx[:, 1].reshape(m_tth.shape)), conn,
             areas.reshape(sdims[0],
                           sdims[1]), (row_indices.reshape(sdims[0], sdims[1]),
                                       col_indices.reshape(sdims[0],
                                                           sdims[1]))))
        pass
    return patches
Exemple #20
0
    def pull_spots(self, plane_data, grain_params,
                   imgser_dict,
                   tth_tol=0.25, eta_tol=1., ome_tol=1.,
                   npdiv=2, threshold=10,
                   eta_ranges=[(-np.pi, np.pi), ],
                   ome_period=(-np.pi, np.pi),
                   dirname='results', filename=None, output_format='text',
                   save_spot_list=False,
                   quiet=True, check_only=False,
                   interp='nearest'):
        """
        Exctract reflection info from a rotation series encoded as an
        OmegaImageseries object
        """

        # grain parameters
        rMat_c = makeRotMatOfExpMap(grain_params[:3])
        tVec_c = grain_params[3:6]

        # grab omega ranges from first imageseries
        #
        # WARNING: all imageseries AND all wedges within are assumed to have
        # the same omega values; put in a check that they are all the same???
        oims0 = imgser_dict[imgser_dict.keys()[0]]
        ome_ranges = [np.radians([i['ostart'], i['ostop']])
                      for i in oims0.omegawedges.wedges]

        # delta omega in DEGREES grabbed from first imageseries in the dict
        delta_ome = oims0.omega[0, 1] - oims0.omega[0, 0]

        # make omega grid for frame expansion around reference frame
        # in DEGREES
        ndiv_ome, ome_del = make_tolerance_grid(
            delta_ome, ome_tol, 1, adjust_window=True,
        )

        # generate structuring element for connected component labeling
        if ndiv_ome == 1:
            label_struct = ndimage.generate_binary_structure(2, 2)
        else:
            label_struct = ndimage.generate_binary_structure(3, 3)

        # simulate rotation series
        sim_results = self.simulate_rotation_series(
            plane_data, [grain_params, ],
            eta_ranges=eta_ranges,
            ome_ranges=ome_ranges,
            ome_period=ome_period)

        # patch vertex generator (global for instrument)
        tol_vec = 0.5*np.radians(
            [-tth_tol, -eta_tol,
             -tth_tol,  eta_tol,
             tth_tol,  eta_tol,
             tth_tol, -eta_tol])

        # prepare output if requested
        if filename is not None and output_format.lower() == 'hdf5':
            this_filename = os.path.join(dirname, filename)
            writer = io.GrainDataWriter_h5(
                os.path.join(dirname, filename),
                self.write_config(), grain_params)

        # =====================================================================
        # LOOP OVER PANELS
        # =====================================================================
        iRefl = 0
        compl = []
        output = dict.fromkeys(self.detectors)
        for detector_id in self.detectors:
            # initialize text-based output writer
            if filename is not None and output_format.lower() == 'text':
                output_dir = os.path.join(
                    dirname, detector_id
                    )
                if not os.path.exists(output_dir):
                    os.makedirs(output_dir)
                this_filename = os.path.join(
                    output_dir, filename
                )
                writer = io.PatchDataWriter(this_filename)

            # grab panel
            panel = self.detectors[detector_id]
            instr_cfg = panel.config_dict(self.chi, self.tvec)
            native_area = panel.pixel_area  # pixel ref area

            # pull out the OmegaImageSeries for this panel from input dict
            ome_imgser = imgser_dict[detector_id]

            # extract simulation results
            sim_results_p = sim_results[detector_id]
            hkl_ids = sim_results_p[0][0]
            hkls_p = sim_results_p[1][0]
            ang_centers = sim_results_p[2][0]
            xy_centers = sim_results_p[3][0]
            ang_pixel_size = sim_results_p[4][0]

            # now verify that full patch falls on detector...
            # ???: strictly necessary?
            #
            # patch vertex array from sim
            nangs = len(ang_centers)
            patch_vertices = (
                np.tile(ang_centers[:, :2], (1, 4)) +
                np.tile(tol_vec, (nangs, 1))
            ).reshape(4*nangs, 2)
            ome_dupl = np.tile(
                ang_centers[:, 2], (4, 1)
            ).T.reshape(len(patch_vertices), 1)

            # find vertices that all fall on the panel
            det_xy, _ = xrdutil._project_on_detector_plane(
                np.hstack([patch_vertices, ome_dupl]),
                panel.rmat, rMat_c, self.chi,
                panel.tvec, tVec_c, self.tvec,
                panel.distortion)
            _, on_panel = panel.clip_to_panel(det_xy, buffer_edges=True)

            # all vertices must be on...
            patch_is_on = np.all(on_panel.reshape(nangs, 4), axis=1)
            patch_xys = det_xy.reshape(nangs, 4, 2)[patch_is_on]

            # re-filter...
            hkl_ids = hkl_ids[patch_is_on]
            hkls_p = hkls_p[patch_is_on, :]
            ang_centers = ang_centers[patch_is_on, :]
            xy_centers = xy_centers[patch_is_on, :]
            ang_pixel_size = ang_pixel_size[patch_is_on, :]

            # TODO: add polygon testing right here!
            # done <JVB 06/21/16>
            if check_only:
                patch_output = []
                for i_pt, angs in enumerate(ang_centers):
                    # the evaluation omegas;
                    # expand about the central value using tol vector
                    ome_eval = np.degrees(angs[2]) + ome_del

                    # ...vectorize the omega_to_frame function to avoid loop?
                    frame_indices = [
                        ome_imgser.omega_to_frame(ome)[0] for ome in ome_eval
                    ]
                    if -1 in frame_indices:
                        if not quiet:
                            msg = """
                            window for (%d%d%d) falls outside omega range
                            """ % tuple(hkls_p[i_pt, :])
                            print(msg)
                        continue
                    else:
                        these_vertices = patch_xys[i_pt]
                        ijs = panel.cartToPixel(these_vertices)
                        ii, jj = polygon(ijs[:, 0], ijs[:, 1])
                        contains_signal = False
                        for i_frame in frame_indices:
                            contains_signal = contains_signal or np.any(
                                ome_imgser[i_frame][ii, jj] > threshold
                            )
                        compl.append(contains_signal)
                        patch_output.append((ii, jj, frame_indices))
            else:
                # make the tth,eta patches for interpolation
                patches = xrdutil.make_reflection_patches(
                    instr_cfg, ang_centers[:, :2], ang_pixel_size,
                    omega=ang_centers[:, 2],
                    tth_tol=tth_tol, eta_tol=eta_tol,
                    rMat_c=rMat_c, tVec_c=tVec_c,
                    distortion=panel.distortion,
                    npdiv=npdiv, quiet=True,
                    beamVec=self.beam_vector)

                # GRAND LOOP over reflections for this panel
                patch_output = []
                for i_pt, patch in enumerate(patches):

                    # strip relevant objects out of current patch
                    vtx_angs, vtx_xy, conn, areas, xy_eval, ijs = patch

                    prows, pcols = areas.shape
                    nrm_fac = areas/float(native_area)
                    nrm_fac = nrm_fac / np.min(nrm_fac)

                    # grab hkl info
                    hkl = hkls_p[i_pt, :]
                    hkl_id = hkl_ids[i_pt]

                    # edge arrays
                    tth_edges = vtx_angs[0][0, :]
                    delta_tth = tth_edges[1] - tth_edges[0]
                    eta_edges = vtx_angs[1][:, 0]
                    delta_eta = eta_edges[1] - eta_edges[0]

                    # need to reshape eval pts for interpolation
                    xy_eval = np.vstack([xy_eval[0].flatten(),
                                         xy_eval[1].flatten()]).T

                    # the evaluation omegas;
                    # expand about the central value using tol vector
                    ome_eval = np.degrees(ang_centers[i_pt, 2]) + ome_del

                    # ???: vectorize the omega_to_frame function to avoid loop?
                    frame_indices = [
                        ome_imgser.omega_to_frame(ome)[0] for ome in ome_eval
                    ]

                    if -1 in frame_indices:
                        if not quiet:
                            msg = """
                            window for (%d%d%d) falls outside omega range
                            """ % tuple(hkl)
                            print(msg)
                        continue
                    else:
                        # initialize spot data parameters
                        # !!! maybe change these to nan to not f**k up writer
                        peak_id = -999
                        sum_int = None
                        max_int = None
                        meas_angs = None
                        meas_xy = None

                        # quick check for intensity
                        contains_signal = False
                        patch_data_raw = []
                        for i_frame in frame_indices:
                            tmp = ome_imgser[i_frame][ijs[0], ijs[1]]
                            contains_signal = contains_signal or np.any(
                                tmp > threshold
                            )
                            patch_data_raw.append(tmp)
                            pass
                        patch_data_raw = np.stack(patch_data_raw, axis=0)
                        compl.append(contains_signal)

                        if contains_signal:
                            # initialize patch data array for intensities
                            if interp.lower() == 'bilinear':
                                patch_data = np.zeros(
                                    (len(frame_indices), prows, pcols))
                                for i, i_frame in enumerate(frame_indices):
                                    patch_data[i] = \
                                        panel.interpolate_bilinear(
                                            xy_eval,
                                            ome_imgser[i_frame],
                                            pad_with_nans=False
                                        ).reshape(prows, pcols)  # * nrm_fac
                            elif interp.lower() == 'nearest':
                                patch_data = patch_data_raw  # * nrm_fac
                            else:
                                msg = "interpolation option " + \
                                    "'%s' not understood"
                                raise(RuntimeError, msg % interp)

                            # now have interpolated patch data...
                            labels, num_peaks = ndimage.label(
                                patch_data > threshold, structure=label_struct
                            )
                            slabels = np.arange(1, num_peaks + 1)

                            if num_peaks > 0:
                                peak_id = iRefl
                                coms = np.array(
                                    ndimage.center_of_mass(
                                        patch_data,
                                        labels=labels,
                                        index=slabels
                                    )
                                )
                                if num_peaks > 1:
                                    center = np.r_[patch_data.shape]*0.5
                                    center_t = np.tile(center, (num_peaks, 1))
                                    com_diff = coms - center_t
                                    closest_peak_idx = np.argmin(
                                        np.sum(com_diff**2, axis=1)
                                    )
                                else:
                                    closest_peak_idx = 0
                                    pass  # end multipeak conditional
                                coms = coms[closest_peak_idx]
                                # meas_omes = \
                                #     ome_edges[0] + (0.5 + coms[0])*delta_ome
                                meas_omes = \
                                    ome_eval[0] + coms[0]*delta_ome
                                meas_angs = np.hstack(
                                    [tth_edges[0] + (0.5 + coms[2])*delta_tth,
                                     eta_edges[0] + (0.5 + coms[1])*delta_eta,
                                     mapAngle(
                                         np.radians(meas_omes), ome_period
                                         )
                                     ]
                                )

                                # intensities
                                #   - summed is 'integrated' over interpolated
                                #     data
                                #   - max is max of raw input data
                                sum_int = np.sum(
                                    patch_data[
                                        labels == slabels[closest_peak_idx]
                                    ]
                                )
                                max_int = np.max(
                                    patch_data_raw[
                                        labels == slabels[closest_peak_idx]
                                    ]
                                )
                                # ???: Should this only use labeled pixels?
                                # Those are segmented from interpolated data,
                                # not raw; likely ok in most cases.

                                # need MEASURED xy coords
                                gvec_c = anglesToGVec(
                                    meas_angs,
                                    chi=self.chi,
                                    rMat_c=rMat_c,
                                    bHat_l=self.beam_vector)
                                rMat_s = makeOscillRotMat(
                                    [self.chi, meas_angs[2]]
                                )
                                meas_xy = gvecToDetectorXY(
                                    gvec_c,
                                    panel.rmat, rMat_s, rMat_c,
                                    panel.tvec, self.tvec, tVec_c,
                                    beamVec=self.beam_vector)
                                if panel.distortion is not None:
                                    # FIXME: distortion handling
                                    meas_xy = panel.distortion[0](
                                        np.atleast_2d(meas_xy),
                                        panel.distortion[1],
                                        invert=True).flatten()
                                    pass
                                # FIXME: why is this suddenly necessary???
                                meas_xy = meas_xy.squeeze()
                                pass  # end num_peaks > 0
                        else:
                            patch_data = patch_data_raw
                            pass  # end contains_signal
                        # write output
                        if filename is not None:
                            if output_format.lower() == 'text':
                                writer.dump_patch(
                                    peak_id, hkl_id, hkl, sum_int, max_int,
                                    ang_centers[i_pt], meas_angs,
                                    xy_centers[i_pt], meas_xy)
                            elif output_format.lower() == 'hdf5':
                                xyc_arr = xy_eval.reshape(
                                    prows, pcols, 2
                                ).transpose(2, 0, 1)
                                writer.dump_patch(
                                    detector_id, iRefl, peak_id, hkl_id, hkl,
                                    tth_edges, eta_edges, np.radians(ome_eval),
                                    xyc_arr, ijs, frame_indices, patch_data,
                                    ang_centers[i_pt], xy_centers[i_pt],
                                    meas_angs, meas_xy)
                            pass  # end conditional on write output
                        pass  # end conditional on check only
                        patch_output.append([
                                peak_id, hkl_id, hkl, sum_int, max_int,
                                ang_centers[i_pt], meas_angs, meas_xy,
                                ])
                        iRefl += 1
                    pass  # end patch conditional
                pass  # end patch loop
            output[detector_id] = patch_output
            if filename is not None and output_format.lower() == 'text':
                writer.close()
            pass  # end detector loop
        if filename is not None and output_format.lower() == 'hdf5':
            writer.close()
        return compl, output