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
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
def cart_to_angles(self, xy_data): """ TODO: distortion """ rmat_s = ct.identity_3x3 tvec_s = ct.zeros_3 tvec_c = ct.zeros_3 angs, g_vec = detectorXYToGvec( xy_data, self.rmat, rmat_s, self.tvec, tvec_s, tvec_c, beamVec=self.bvec, etaVec=self.evec) tth_eta = np.vstack([angs[0], angs[1]]).T return tth_eta, g_vec
def pixel_angles(self): pix_i, pix_j = self.pixel_coords xy = np.ascontiguousarray( np.vstack([ pix_j.flatten(), pix_i.flatten() ]).T ) angs, g_vec = detectorXYToGvec( xy, self.rmat, ct.identity_3x3, self.tvec, ct.zeros_3, ct.zeros_3, beamVec=self.bvec, etaVec=self.evec) del(g_vec) tth = angs[0].reshape(self.rows, self.cols) eta = angs[1].reshape(self.rows, self.cols) return tth, eta
def pixel_angles(self): pix_i, pix_j = self.pixel_coords xy = np.ascontiguousarray( np.vstack([pix_j.flatten(), pix_i.flatten()]).T) angs, g_vec = detectorXYToGvec(xy, self.rmat, ct.identity_3x3, self.tvec, ct.zeros_3, ct.zeros_3, beamVec=self.bvec, etaVec=self.evec) del (g_vec) tth = angs[0].reshape(self.rows, self.cols) eta = angs[1].reshape(self.rows, self.cols) return tth, eta
def cart_to_angles(self, xy_data): """ TODO: distortion """ rmat_s = ct.identity_3x3 tvec_s = ct.zeros_3 tvec_c = ct.zeros_3 angs, g_vec = detectorXYToGvec(xy_data, self.rmat, rmat_s, self.tvec, tvec_s, tvec_c, beamVec=self.bvec, etaVec=self.evec) tth_eta = np.vstack([angs[0], angs[1]]).T return tth_eta, g_vec
def simulate_laue_pattern(self, crystal_data, minEnergy=5., maxEnergy=35., rmat_s=None, tvec_s=None, grain_params=None, beam_vec=None): """ """ if isinstance(crystal_data, PlaneData): plane_data = crystal_data # grab the expanded list of hkls from plane_data hkls = np.hstack(plane_data.getSymHKLs()) # and the unit plane normals (G-vectors) in CRYSTAL FRAME gvec_c = np.dot(plane_data.latVecOps['B'], hkls) elif len(crystal_data) == 2: # !!! should clean this up hkls = np.array(crystal_data[0]) bmat = crystal_data[1] gvec_c = np.dot(bmat, hkls) else: raise (RuntimeError, 'argument list not understood') nhkls_tot = hkls.shape[1] # parse energy ranges # TODO: allow for spectrum parsing multipleEnergyRanges = False if hasattr(maxEnergy, '__len__'): assert len(maxEnergy) == len(minEnergy), \ 'energy cutoff ranges must have the same length' multipleEnergyRanges = True lmin = [] lmax = [] for i in range(len(maxEnergy)): lmin.append(ct.keVToAngstrom(maxEnergy[i])) lmax.append(ct.keVToAngstrom(minEnergy[i])) else: lmin = ct.keVToAngstrom(maxEnergy) lmax = ct.keVToAngstrom(minEnergy) # parse grain parameters kwarg if grain_params is None: grain_params = np.atleast_2d( np.hstack([np.zeros(6), ct.identity_6x1])) n_grains = len(grain_params) # sample rotation if rmat_s is None: rmat_s = ct.identity_3x3 # dummy translation vector... make input if tvec_s is None: tvec_s = ct.zeros_3 # beam vector if beam_vec is None: beam_vec = ct.beam_vec # ========================================================================= # LOOP OVER GRAINS # ========================================================================= # pre-allocate output arrays xy_det = np.nan * np.ones((n_grains, nhkls_tot, 2)) hkls_in = np.nan * np.ones((n_grains, 3, nhkls_tot)) angles = np.nan * np.ones((n_grains, nhkls_tot, 2)) dspacing = np.nan * np.ones((n_grains, nhkls_tot)) energy = np.nan * np.ones((n_grains, nhkls_tot)) for iG, gp in enumerate(grain_params): rmat_c = makeRotMatOfExpMap(gp[:3]) tvec_c = gp[3:6].reshape(3, 1) vInv_s = mutil.vecMVToSymm(gp[6:].reshape(6, 1)) # stretch them: V^(-1) * R * Gc gvec_s_str = np.dot(vInv_s, np.dot(rmat_c, gvec_c)) ghat_c_str = mutil.unitVector(np.dot(rmat_c.T, gvec_s_str)) # project dpts = gvecToDetectorXY(ghat_c_str.T, self.rmat, rmat_s, rmat_c, self.tvec, tvec_s, tvec_c, beamVec=beam_vec) # check intersections with detector plane canIntersect = ~np.isnan(dpts[:, 0]) npts_in = sum(canIntersect) if np.any(canIntersect): dpts = dpts[canIntersect, :].reshape(npts_in, 2) dhkl = hkls[:, canIntersect].reshape(3, npts_in) # back to angles tth_eta, gvec_l = detectorXYToGvec(dpts, self.rmat, rmat_s, self.tvec, tvec_s, tvec_c, beamVec=beam_vec) tth_eta = np.vstack(tth_eta).T # warp measured points if self.distortion is not None: if len(self.distortion) == 2: dpts = self.distortion[0](dpts, self.distortion[1], invert=True) else: raise (RuntimeError, "something is wrong with the distortion") # plane spacings and energies dsp = 1. / rowNorm(gvec_s_str[:, canIntersect].T) wlen = 2 * dsp * np.sin(0.5 * tth_eta[:, 0]) # clip to detector panel _, on_panel = self.clip_to_panel(dpts, buffer_edges=True) if multipleEnergyRanges: validEnergy = np.zeros(len(wlen), dtype=bool) for i in range(len(lmin)): in_energy_range = np.logical_and( wlen >= lmin[i], wlen <= lmax[i]) validEnergy = validEnergy | in_energy_range pass else: validEnergy = np.logical_and(wlen >= lmin, wlen <= lmax) pass # index for valid reflections keepers = np.where(np.logical_and(on_panel, validEnergy))[0] # assign output arrays xy_det[iG][keepers, :] = dpts[keepers, :] hkls_in[iG][:, keepers] = dhkl[:, keepers] angles[iG][keepers, :] = tth_eta[keepers, :] dspacing[iG, keepers] = dsp[keepers] energy[iG, keepers] = ct.keVToAngstrom(wlen[keepers]) pass # close conditional on valids pass # close loop on grains return xy_det, hkls_in, angles, dspacing, energy
def 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
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
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
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
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()]) distortion = None #============================================================================== # %% crystallography data #============================================================================== gold = make_matl('gold', 225, [ 4.0782, ], hkl_ssq_max=200)
XY = np.vstack([dcrds[0].flatten(), dcrds[1].flatten()]).T # Check the timings start1 = time.clock() # time this dangs1 = xf.detectorXYToGvec(XY, rMat_d, rMat_s, tVec_d, tVec_s, tVec_c, beamVec=bVec_ref) tTh_d1 = dangs1[0][0] eta_d1 = dangs1[0][1] gVec_l1 = dangs1[1] elapsed1 = (time.clock() - start1) print "Time for Python detectorXYToGvec: %f"%(elapsed1) start2 = time.clock() # time this dangs2 = xfcapi.detectorXYToGvec(XY, rMat_d, rMat_s, tVec_d, tVec_s, tVec_c, beamVec=bVec_ref) tTh_d2 = dangs2[0][0] eta_d2 = dangs2[0][1] gVec_l2 = dangs2[1] elapsed2 = (time.clock() - start2) print "Time for CAPI detectorXYToGvec: %f"%(elapsed2) maxDiff_tTh = np.linalg.norm(tTh_d1-tTh_d2,np.inf) print "Maximum disagreement in tTh: %f"%maxDiff_tTh maxDiff_eta = np.linalg.norm(eta_d1-eta_d2,np.inf) print "Maximum disagreement in eta: %f"%maxDiff_eta maxDiff_gVec = np.linalg.norm(np.sqrt(np.sum(np.asarray(gVec_l1.T-gVec_l2)**2,1)),np.inf) print "Maximum disagreement in gVec: %f"%maxDiff_gVec gVec_c1 = np.dot(rMat_c.T,np.dot(rMat_s.T,gVec_l1))
def simulate_laue_pattern(self, crystal_data, minEnergy=5., maxEnergy=35., rmat_s=None, tvec_s=None, grain_params=None, beam_vec=None): """ """ if isinstance(crystal_data, PlaneData): plane_data = crystal_data # grab the expanded list of hkls from plane_data hkls = np.hstack(plane_data.getSymHKLs()) # and the unit plane normals (G-vectors) in CRYSTAL FRAME gvec_c = np.dot(plane_data.latVecOps['B'], hkls) elif len(crystal_data) == 2: # !!! should clean this up hkls = np.array(crystal_data[0]) bmat = crystal_data[1] gvec_c = np.dot(bmat, hkls) else: raise(RuntimeError, 'argument list not understood') nhkls_tot = hkls.shape[1] # parse energy ranges # TODO: allow for spectrum parsing multipleEnergyRanges = False if hasattr(maxEnergy, '__len__'): assert len(maxEnergy) == len(minEnergy), \ 'energy cutoff ranges must have the same length' multipleEnergyRanges = True lmin = [] lmax = [] for i in range(len(maxEnergy)): lmin.append(ct.keVToAngstrom(maxEnergy[i])) lmax.append(ct.keVToAngstrom(minEnergy[i])) else: lmin = ct.keVToAngstrom(maxEnergy) lmax = ct.keVToAngstrom(minEnergy) # parse grain parameters kwarg if grain_params is None: grain_params = np.atleast_2d( np.hstack([np.zeros(6), ct.identity_6x1]) ) n_grains = len(grain_params) # sample rotation if rmat_s is None: rmat_s = ct.identity_3x3 # dummy translation vector... make input if tvec_s is None: tvec_s = ct.zeros_3 # beam vector if beam_vec is None: beam_vec = ct.beam_vec # ========================================================================= # LOOP OVER GRAINS # ========================================================================= # pre-allocate output arrays xy_det = np.nan*np.ones((n_grains, nhkls_tot, 2)) hkls_in = np.nan*np.ones((n_grains, 3, nhkls_tot)) angles = np.nan*np.ones((n_grains, nhkls_tot, 2)) dspacing = np.nan*np.ones((n_grains, nhkls_tot)) energy = np.nan*np.ones((n_grains, nhkls_tot)) for iG, gp in enumerate(grain_params): rmat_c = makeRotMatOfExpMap(gp[:3]) tvec_c = gp[3:6].reshape(3, 1) vInv_s = mutil.vecMVToSymm(gp[6:].reshape(6, 1)) # stretch them: V^(-1) * R * Gc gvec_s_str = np.dot(vInv_s, np.dot(rmat_c, gvec_c)) ghat_c_str = mutil.unitVector(np.dot(rmat_c.T, gvec_s_str)) # project dpts = gvecToDetectorXY(ghat_c_str.T, self.rmat, rmat_s, rmat_c, self.tvec, tvec_s, tvec_c, beamVec=beam_vec) # check intersections with detector plane canIntersect = ~np.isnan(dpts[:, 0]) npts_in = sum(canIntersect) if np.any(canIntersect): dpts = dpts[canIntersect, :].reshape(npts_in, 2) dhkl = hkls[:, canIntersect].reshape(3, npts_in) # back to angles tth_eta, gvec_l = detectorXYToGvec( dpts, self.rmat, rmat_s, self.tvec, tvec_s, tvec_c, beamVec=beam_vec) tth_eta = np.vstack(tth_eta).T # warp measured points if self.distortion is not None: if len(self.distortion) == 2: dpts = self.distortion[0]( dpts, self.distortion[1], invert=True) else: raise(RuntimeError, "something is wrong with the distortion") # plane spacings and energies dsp = 1. / rowNorm(gvec_s_str[:, canIntersect].T) wlen = 2*dsp*np.sin(0.5*tth_eta[:, 0]) # clip to detector panel _, on_panel = self.clip_to_panel(dpts, buffer_edges=True) if multipleEnergyRanges: validEnergy = np.zeros(len(wlen), dtype=bool) for i in range(len(lmin)): in_energy_range = np.logical_and( wlen >= lmin[i], wlen <= lmax[i]) validEnergy = validEnergy | in_energy_range pass else: validEnergy = np.logical_and(wlen >= lmin, wlen <= lmax) pass # index for valid reflections keepers = np.where(np.logical_and(on_panel, validEnergy))[0] # assign output arrays xy_det[iG][keepers, :] = dpts[keepers, :] hkls_in[iG][:, keepers] = dhkl[:, keepers] angles[iG][keepers, :] = tth_eta[keepers, :] dspacing[iG, keepers] = dsp[keepers] energy[iG, keepers] = ct.keVToAngstrom(wlen[keepers]) pass # close conditional on valids pass # close loop on grains return xy_det, hkls_in, angles, dspacing, energy
XY = np.vstack([dcrds[0].flatten(), dcrds[1].flatten()]).T # Check the timings start1 = timer() # time this dangs1 = xf.detectorXYToGvec(XY, rMat_d, rMat_s, tVec_d, tVec_s, tVec_c, beamVec=bVec_ref) tTh_d1 = dangs1[0][0] eta_d1 = dangs1[0][1] gVec_l1 = dangs1[1] elapsed1 = (timer() - start1) print "Time for Python detectorXYToGvec: %f"%(elapsed1) start2 = timer() # time this dangs2 = xfcapi.detectorXYToGvec(XY, rMat_d, rMat_s, tVec_d, tVec_s, tVec_c, beamVec=bVec_ref) tTh_d2 = dangs2[0][0] eta_d2 = dangs2[0][1] gVec_l2 = dangs2[1] elapsed2 = (timer() - start2) print "Time for CAPI detectorXYToGvec: %f"%(elapsed2) # maxDiff_tTh = np.linalg.norm(tTh_d1-tTh_d2,np.inf) # print "Maximum disagreement in tTh: %f"%maxDiff_tTh # maxDiff_eta = np.linalg.norm(eta_d1-eta_d2,np.inf) ## print "Maximum disagreement in eta: %f"%maxDiff_eta # maxDiff_gVec = np.linalg.norm(np.sqrt(np.sum(np.asarray(gVec_l1.T-gVec_l2)**2,1)),np.inf) # print "Maximum disagreement in gVec: %f"%maxDiff_gVec
rMat_s, tVec_d, tVec_s, tVec_c, beamVec=bVec_ref) tTh_d1 = dangs1[0][0] eta_d1 = dangs1[0][1] gVec1 = dangs1[1] elapsed1 = (time.clock() - start1) print "Time for Python detectorXYToGvec: %f" % (elapsed1) start3 = time.clock() # time this dangs3 = xfcapi.detectorXYToGvec(XY, rMat_d, rMat_s, tVec_d.flatten(), tVec_s.flatten(), tVec_c.flatten(), beamVec=bVec_ref.flatten(), etaVec=np.array([1.0, 0.0, 0.0])) tTh_d3 = dangs3[0][0] eta_d3 = dangs3[0][1] gVec3 = dangs3[1] elapsed3 = (time.clock() - start3) print "Time for CAPI detectorXYToGvec: %f" % (elapsed3) maxDiff_tTh = np.linalg.norm(tTh_d1 - tTh_d3, np.inf) print "Maximum disagreement in tTh: %f" % maxDiff_tTh maxDiff_eta = np.linalg.norm(eta_d1 - eta_d3, np.inf) print "Maximum disagreement in eta: %f" % maxDiff_eta maxDiff_gVec = np.linalg.norm( np.sqrt(np.sum(np.asarray(gVec1.T - gVec3)**2, 1)), np.inf)
# tTh_d2 = dangs2[0][0] # eta_d2 = dangs2[0][1] # gVec2 = dangs2[1] # elapsed2 = (timer() - start2) # print "Time for Cython detectorXYToGvec: %f"%(elapsed2) #maxDiff_tTh = np.linalg.norm(tTh_d1-tTh_d2,np.inf) #print "Maximum disagreement in tTh: %f"%maxDiff_tTh #maxDiff_eta = np.linalg.norm(eta_d1-eta_d2,np.inf) #print "Maximum disagreement in eta: %f"%maxDiff_eta #maxDiff_gVec = np.linalg.norm(np.sqrt(np.sum(np.asarray(gVec1.T-gVec2)**2,1)),np.inf) #print "Maximum disagreement in gVec: %f"%maxDiff_gVec start3 = timer() # time this dangs3 = xfcapi.detectorXYToGvec(XY, rMat_d, rMat_s, tVec_d.flatten(), tVec_s.flatten(), tVec_c.flatten(), beamVec=bVec_ref.flatten(),etaVec=np.array([1.0,0.0,0.0])) tTh_d3 = dangs3[0][0] eta_d3 = dangs3[0][1] gVec3 = dangs3[1] elapsed3 = (timer() - start3) print "Time for CAPI detectorXYToGvec: %f"%(elapsed3) maxDiff_tTh = np.linalg.norm(tTh_d1-tTh_d3,np.inf) print "Maximum disagreement in tTh: %f"%maxDiff_tTh maxDiff_eta = np.linalg.norm(eta_d1-eta_d3,np.inf) print "Maximum disagreement in eta: %f"%maxDiff_eta maxDiff_gVec = np.linalg.norm(np.sqrt(np.sum(np.asarray(gVec1.T-gVec3)**2,1)),np.inf) print "Maximum disagreement in gVec: %f"%maxDiff_gVec print 'cudadevice: ', numba.cuda.get_current_device().name
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()]) distortion = None #============================================================================== # %% crystallography data #============================================================================== gold = make_matl('gold', 225, [4.0782,], hkl_ssq_max=200) gold.beamEnergy = valunits.valWUnit("wavelength","ENERGY",52,"keV") pd = gold.planeData pd.exclusions = np.zeros(len(pd.exclusions), dtype=bool) pd.tThMax = np.amax(pixel_tth)