def runtest(self): g = transform.compute_g_vectors(self.tth, self.eta, self.omega, self.wvln, wedge=self.w, chi=self.c) tth, eta, omega = transform.uncompute_g_vectors(g, self.wvln, wedge=self.w, chi=self.c) # print tth # print eta # print omega print "# w c i tth tth etao etaC omegao omegaC etaC2 omegaC2" for i in range(len(tth)): print self.w, self.c, i, best = np.argmin( np.abs(angmod(np.array(omega)[:, i] - self.omega[i]))) deta = angmod(np.array(eta)[best, i] - self.eta[i]) domega = angmod(np.array(omega)[best, i] - self.omega[i]) print ("%8.2f "*8)%(self.tth[i], tth[i],self.eta[i], eta[best][i],\ self.omega[i], omega[best][i],eta[1-best][i],omega[1-best][i]) self.assertAlmostEqual(self.tth[i], tth[i], 5) self.assertAlmostEqual(deta, 0.0, 5) self.assertAlmostEqual(domega, 0.0, 5)
def forwards_project( gr, pars, detector_size, spatial, dsmax, gid): latt = "P" for k in pars.parameters.keys(): if k.startswith("cell_lattice"): latt = pars.get(k) cell = unitcell.unitcell( indexing.ubitocellpars( gr.ubi ), latt ) ds_hkl = cell.gethkls( dsmax ) hkls = np.array( [ x[1] for x in ds_hkl] ) gvecs = np.dot( gr.ub, hkls.T ) wvln, wedge, chi = [ pars.get(x) for x in "wavelength", "wedge", "chi" ] tth, (eta1, eta2), (omega1, omega2) = transform.uncompute_g_vectors( gvecs, wvln, wedge=wedge, chi=chi) osign = float(pars.get("omegasign")) if osign != 1: print("# Flipping omegasign %f"%(osign)) np.multiply( omega1, osign, omega1 ) np.multiply( omega2, osign, omega2 ) pars.set( "t_x", gr.translation[0] ) pars.set( "t_y", gr.translation[1] ) pars.set( "t_z", gr.translation[2] ) fc1, sc1 = transform.compute_xyz_from_tth_eta(tth, eta1, omega1, **pars.parameters) fc2, sc2 = transform.compute_xyz_from_tth_eta(tth, eta2, omega2, **pars.parameters) # Now make a single list of output stuff: alltth = np.concatenate( (tth, tth)) alleta = np.concatenate( (eta1, eta2) ) allsc = np.concatenate( (sc1, sc2) ) allfc = np.concatenate( (fc1, fc2) ) sraw = np.zeros(allsc.shape) fraw = np.zeros(allsc.shape) for i,(s,f) in enumerate(zip( allsc, allfc )): sraw[i], fraw[i] = spatial.distort( s, f ) allomega = np.concatenate( (omega1, omega2) ) allhkls = np.concatenate( (hkls, hkls) ) order = np.argsort( allomega ) # output ? # omega in range # peak in detector # etc fmt = " % -4d % -3d % -3d % -3d % 8.4f % 7.2f % 8.2f % 8.2f % 8.2f % 8.2f % 8.2f" strs = [] for i in order: s, f, o = sraw[i], fraw[i], allomega[i] if alltth[i] == 0: continue if inscan( s, f, o, detector_size): line = fmt%(gid,allhkls[i][0],allhkls[i][1],allhkls[i][2], alltth[i], alleta[i], allomega[i], allsc[i], allfc[i], sraw[i], fraw[i] ) strs.append( (allomega[i], line) ) # to be omega sortable return strs
def makedata(): global wavelength global dsmax global dsmin u = unitcell.unitcell(*rcell(gen)) o = omat(gen) #print dot(o,o.T) ub = dot(o, u.B) print(u.tostring()) meancell = pow(u.B[0, 0] * u.B[1, 1] * u.B[2, 2], -1. / 3.) if dsmax is None: dsmax = 20. / meancell dsmin = 5. / meancell hkls = u.gethkls(dsmax) # print "DSMAX",dsmax, meancell,len(hkls) myh = [] for ds, h in hkls: if ds > dsmin: g = dot(ub, h) # print h,ds, g, sqrt(dot( g,g)) myh.append(h) myh = array(myh) gve = dot(ub, myh.T) # set wavelength to make the largest angle be 45 degrees if wavelength is None: print("set wavelength") wavelength = 2 * sin(pi / 8.0) / dsmax tth, eta, omega = transform.uncompute_g_vectors(gve, wavelength) e0, e1 = eta o0, o1 = omega gfinal = [] omax = 5 for i in range(len(tth)): if o0[i] > 0 and o0[i] < omax: gfinal.append(gve.T[i]) if o1[i] > 0 and o1[i] < omax: gfinal.append(gve.T[i]) f = open("ideal.ubi", "a") f.write("cell = '" + u.tostring() + "'\n") f.write('ub = ' + repr(ub)) f.write("\nnpks = %d\n" % (len(gfinal))) f.close() return gfinal
def calccolumns(p, c, g, pks=None): """ p = parameters c = columnfile g = grain pks = selection of which peaks to use for the grain. If none we do all. """ t = g.translation p.set('t_x', t[0]) p.set('t_y', t[1]) p.set('t_z', t[2]) # tth, eta of the spots given this origin position if pks is None: pks = ~np.isnan(c.sc) tth, eta = transform.compute_tth_eta([c.sc[pks], c.fc[pks]], omega=c.omega[pks], **p.parameters) # g-vectors given this origin gve = transform.compute_g_vectors(tth, eta, c.omega[pks], p.get("wavelength"), p.get("wedge"), p.get("chi")) # Find hkl indices hklo = np.dot(g.ubi, gve) hkli = np.round(hklo) diff = hklo - hkli # Now uncompute to get ideal spot positions in each case: gcalc = np.dot(g.ub, hkli) tthcalc, etacalc, omegacalc = transform.uncompute_g_vectors( gcalc, p.get("wavelength"), p.get("wedge"), p.get("chi")) # which eta to choose - there are two possibilities # ... eta should always be in -180, 180 as it is arctan2 smatch = np.sign(eta) == np.sign(etacalc[0]) etachosen = np.where(smatch, etacalc[0], etacalc[1]) omegachosen = np.where(smatch, omegacalc[0], omegacalc[1]) # deal with the mod360 for omega omegachosen = mod360(omegachosen, c.omega[pks]) fcc, scc = transform.compute_xyz_from_tth_eta(tthcalc, etachosen, omegachosen, **p.parameters) # how close to reciprocal lattice point (could throw out some peaks here...) drlv = np.sqrt((diff * diff).sum(axis=0)) # save arrays to colfile: c.drlv[pks] = drlv c.tth_per_grain[pks] = tth c.eta_per_grain[pks] = eta c.tthcalc[pks] = tthcalc c.etacalc[pks] = etachosen c.omegacalc[pks] = omegachosen c.sccalc[pks] = scc c.fccalc[pks] = fcc return c
def doplot(ubi, col): g = np.dot(np.linalg.inv(ubi), hkls) tth, (eta0, eta1), (omega0, omega1) = transform.uncompute_g_vectors( g, pars.get('wavelength')) ax1.plot(tth, eta0, col) ax1.plot(tth, eta1, col) sc, fc = transform.compute_xyz_from_tth_eta(tth, eta0, omega0, **pars.parameters) ax2.plot(sc, fc, col) sc, fc = transform.compute_xyz_from_tth_eta(tth, eta1, omega1, **pars.parameters) ax2.plot(sc, fc, col) ax3.plot(g[0], g[1], g[2], col) ax4.scatter(eta0, omega0, c=tth) cax = ax4.scatter(eta1, omega1, c=tth) global XX if XX: plt.colorbar(cax) XX = False
def calc_tth_eta_omega(ub, hkls, pars, etasigns): """ Predict the tth, eta, omega for each grain ub = ub matrix (inverse ubi) hkls = peaks to predict pars = diffractometer info (wavelength, rotation axis) etasigns = which solution for omega/eta to choose (+y or -y) """ g = np.dot(ub, hkls) tthcalc, eta2, omega2 = transform.uncompute_g_vectors( g, pars.get('wavelength'), wedge=pars.get('wedge'), chi=pars.get('chi')) # choose which solution (eta+ or eta-) e0 = np.sign(eta2[0]) == etasigns etacalc = np.where(e0, eta2[0], eta2[1]) omegacalc = np.where(e0, omega2[0], omega2[1]) return tthcalc, etacalc, omegacalc
def saveindexing(self, filename, tol=None): """ Save orientation matrices FIXME : refactor this into something to do grain by grain } peak by peak } """ f = open(filename, "w") i = 0 from ImageD11 import transform # grain assignment self.fight_over_peaks() # Printing per grain uinverses = [] allind = np.array(range(len(self.ra))) tthcalc = np.zeros(len(self.ra), np.float) etacalc = np.zeros(len(self.ra), np.float) omegacalc = np.zeros(len(self.ra), np.float) i = -1 for ubi in self.ubis: i += 1 # Each ubi has peaks in self.ga uinverses.append(np.linalg.inv(ubi)) npk, mdrlv = closest.refine_assigned(ubi.copy(), self.gv, self.ga, i, -1) assert npk == self.gas[i] f.write("Grain: %d Npeaks=%d <drlv>=%f\n" % (i, self.gas[i], np.sqrt(mdrlv))) f.write("UBI:\n" + str(ubi) + "\n") cellpars = ubitocellpars(ubi) f.write("Cell pars: ") for abc in cellpars[:3]: f.write("%10.6f " % (abc)) for abc in cellpars[3:]: f.write("%10.3f " % (abc)) f.write("\n") # Grainspotter U f.write("U:\n" + str(ubitoU(ubi)) + "\n") f.write("B:\n" + str(ubitoB(ubi)) + "\n") # Compute hkls h = np.dot(ubi, self.gv.T) hint = np.floor(h + 0.5) gint = np.dot(uinverses[-1], hint) dr = h - hint f.write( "Peak ( h k l ) drlv x y " ) if self.wavelength < 0: f.write("\n") else: f.write( " Omega_obs Omega_calc Eta_obs Eta_calc tth_obs tth_calc\n" ) tc, ec, oc = transform.uncompute_g_vectors(gint, self.wavelength, wedge=self.wedge) ind = np.compress(self.ga == i, allind) for j in ind: f.write("%-6d ( % 6.4f % 6.4f % 6.4f ) % 12.8f " % (j, h[0, j], h[1, j], h[2, j], np.sqrt(self.drlv2[j]))) f.write(" % 7.1f % 7.1f " % (self.xp[j], self.yp[j])) if self.wavelength < 0: f.write("\n") else: # # # These should be equal to to = math.asin( self.wavelength * self.ds[j] / 2) * 360 / math.pi # tth observed eo = mod_360(self.eta[j], 0) oo = self.omega[j] tc1 = tc[j] # Choose which is closest in eta/omega, # there are two choices, {eta,omega}, {-eta,omega+180} w = np.argmin([abs(ec[0][j] - eo), abs(ec[1][j] - eo)]) ec1 = ec[w][j] oc1 = oc[w][j] # Now find best omega within 360 degree intervals oc1 = mod_360(oc1, oo) f.write( " % 9.4f % 9.4f % 9.4f % 9.4f % 9.4f % 9.4f" % (oo, oc1, eo, ec1, to, tc1)) etacalc[j] = ec1 omegacalc[j] = oc1 tthcalc[j] = tc1 if self.ra[j] == -1: f.write(" *** was not assigned to ring\n") else: f.write("\n") f.write("\n\n") # peaks assigned to rings in_rings = np.compress(np.greater(self.ra, -1), np.arange(self.gv.shape[0])) f.write("\n\nAnd now listing via peaks which were assigned to rings\n") nleft = 0 nfitted = 0 npk = 0 for peak in in_rings: # Compute hkl for each grain h = self.gv[peak, :] f.write( "\nPeak= %-5d Ring= %-5d gv=[ % -6.4f % -6.4f % -6.4f ] omega= % 9.4f eta= % 9.4f tth= % 9.4f\n" % (peak, self.ra[peak], h[0], h[1], h[2], self.omega[peak], self.eta[peak], self.tth[peak])) if self.ga[peak] != -1: m = self.ga[peak] hi = np.dot(self.ubis[m], h) hint = np.floor(hi + 0.5).astype(np.int) gint = np.dot(uinverses[m], hint) f.write("Grain %-5d (%3d,%3d,%3d)" % (m, hint[0], hint[1], hint[2])) f.write(" ( % -6.4f % -6.4f % -6.4f ) " % (hi[0], hi[1], hi[2])) # Now find best omega within 360 degree intervals f.write(" omega= % 9.4f eta= %9.4f tth= %9.4f\n" % (omegacalc[peak], etacalc[peak], tthcalc[peak])) npk = npk + 1 else: if len(self.ubis) > 0: f.write("Peak not assigned\m") # , closest=[ % -6.4f % -6.4f % -6.4f ] for grain %d\n"%(hi[0],hi[1],hi[2],m)) else: f.write("Peak not assigned, no grains found\n") nleft = nleft + 1 f.write("\n\nTotal number of peaks was %d\n" % (self.gv.shape[0])) f.write("Peaks assigned to grains %d\n" % (npk)) f.write("Peaks assigned to rings but remaining unindexed %d\n" % (nleft)) f.write("Peaks not assigned to rings at all %d\n" % (np.sum(np.where(self.ra == -1, 1, 0)))) f.close()
def compute_gv(self, thisgrain, update_columns=False): """ Makes self.gv refer be g-vectors computed for this grain in this scan """ peaks_xyz = thisgrain.peaks_xyz om = thisgrain.om try: sign = self.parameterobj.parameters['omegasign'] except: sign = 1.0 # translation should match grain translation here... self.tth, self.eta = transform.compute_tth_eta_from_xyz( peaks_xyz.T, omega=om * sign, **self.parameterobj.parameters) gv = transform.compute_g_vectors( self.tth, self.eta, om * sign, float(self.parameterobj.parameters['wavelength']), self.parameterobj.parameters['wedge'], self.parameterobj.parameters['chi']) if self.OMEGA_FLOAT: mat = thisgrain.ubi.copy() gvT = numpy.ascontiguousarray(gv.T) junk = cImageD11.score_and_refine(mat, gvT, self.tolerance) hklf = numpy.dot(mat, gv) hkli = numpy.round(hklf) gcalc = numpy.dot(numpy.linalg.inv(mat), hkli) tth, [eta1, eta2], [omega1, omega2] = transform.uncompute_g_vectors( gcalc, float(self.parameterobj.parameters['wavelength']), self.parameterobj.parameters['wedge'], self.parameterobj.parameters['chi']) e1e = numpy.abs(eta1 - self.eta) e2e = numpy.abs(eta2 - self.eta) try: eta_err = numpy.array([e1e, e2e]) except: print(e1e.shape, e2e.shape, e1e) raise best_fitting = numpy.argmin(eta_err, axis=0) # These are always 1 or zero # pick the right omega (confuddled by take here) omega_calc = best_fitting * omega2 + (1 - best_fitting) * omega1 # Take a weighted average within the omega error of the observed omerr = (om * sign - omega_calc) # Clip to 360 degree range omerr = omerr - (360 * numpy.round(omerr / 360.0)) # print omerr[0:5] omega_calc = om * sign - numpy.clip(omerr, -self.slop, self.slop) # print omega_calc[0], om[0] thisgrain.omega_calc = omega_calc # Now recompute with improved omegas... (tth, eta do not change much) #self.tth, self.eta = transform.compute_tth_eta( # numpy.array([x, y]), # omega = omega_calc, # **self.parameterobj.parameters) self.tth, self.eta = transform.compute_tth_eta_from_xyz( peaks_xyz.T, omega=om * sign, **self.parameterobj.parameters) gv = transform.compute_g_vectors( self.tth, self.eta, omega_calc, float(self.parameterobj.parameters['wavelength']), self.parameterobj.parameters['wedge'], self.parameterobj.parameters['chi']) else: thisgrain.omega_calc[:] = 0 # update tth_per_grain and eta_per_grain if update_columns: name = thisgrain.name.split(":")[1] numpy.put(self.scandata[name].tth_per_grain, thisgrain.ind, self.tth) numpy.put(self.scandata[name].eta_per_grain, thisgrain.ind, self.eta) if self.OMEGA_FLOAT: numpy.put(self.scandata[name].omegacalc_per_grain, thisgrain.ind, omega_calc) self.gv = numpy.ascontiguousarray(gv.T) return
ui = [ np.linalg.inv(ubi) for ubi in ul ] r = range(-4,5) hkls = np.array([ (h,k,l) for h in r for k in r for l in r ]) gcalc = [ np.dot( ub, hkls.T).T for ub in ui] # 30 keV energy = 30 wvln = 12.3985 / energy ng = 0 for g, ubi in zip(gcalc, ul): ng +=1 print ("# Grain",ng, "\n# Energy",energy,"keV, wavelength %.5f"%(wvln)) tth, eta, omega = uncompute_g_vectors( g.T, wvln ) order = np.argsort(tth) # hkls = np.dot( ubi, g.T).T print ("# h k l tth eta omega") for j in range(len(order)): i = order[j] for s in (0,1): h,k,l = [int(v) for v in hkls[i]] if tth[i]>0 and tth[i] < 20 and \ abs(eta[s][i])< 45 and not unitcell.F(h,k,l): print ((" %4d"*3 + " %7.2f"*3) % tuple([h,k,l, tth[i], eta[s][i], omega[s][i]])) print()
from scipy.spatial.transform import Rotation # Generate some peaks h,k,l = [x.ravel() for x in np.mgrid[-4:5,-4:5,-4:5]] uc = unitcell.unitcell( [7.89, 8.910, 9.1011, 92, 97, 99], "P") orient = Rotation.from_euler("XYZ",(10,20,31)).as_dcm() ub = np.dot( orient, uc.B ) ubi = np.linalg.inv( ub ) gcalc = np.dot( ub, (h,k,l) ) modg = np.sqrt(gcalc*gcalc).sum(axis=0) tth, eta, omega = transform.uncompute_g_vectors( gcalc, 0.3 ) pl.plot(tth, eta[0],".") pl.plot(tth, eta[1],".") selected_peak = sp = np.argmin(abs(tth - 4.17)) print(tth[sp], eta[0][sp], omega[0][sp], eta[1][sp], omega[1][sp], gcalc[:,sp], h[sp], k[sp], l[sp]) # Now we get to the interesting part. We have simulated some data for a triclinic crystal and picked out some specific peak that we want to work with. The idea is to come up with a "new" way of doing indexing. It is mostly based on Joel Berniers fibre texture thing. # - We assume that we have assigned this peak h,k,l indices based on the two theta. # - We find a rotation which takes unitcell B matrix to put the gvector parallel to this gvector. # - We then apply rotations around this g-vector to generate new orientations. gx,gy,gz = gobs = gcalc[:,sp].copy() h0,k0,l0 = -1,2,0 g0 = np.dot( uc.B, (h0,k0,l0))