Skip to content

Commit 191f367

Browse files
authored
Merge pull request #1 from ando-lab/dev-spm
Dev spm
2 parents 9e92dcd + 77f1d8f commit 191f367

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+32442
-62
lines changed

+geom/@Profile/Profile.m

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
classdef Profile
2+
%PROFILE a collection of methods for spot profile calculations
3+
% <Detailed explanation goes here>
4+
5+
methods(Static)
6+
7+
function [idx,hkl_refl] = hkl2idx(h,k,l)
8+
% assign each pixel an index to its nearest reflection
9+
h = round(h);
10+
k = round(k);
11+
l = round(l);
12+
[hkl_refl,~,ic] = unique([h(:),k(:),l(:)],'rows');
13+
idx = reshape(ic,size(h));
14+
end
15+
16+
function [e1,e2,e3] = s2e(s_refl,Source)
17+
% calculate local coordinate system for each reflection
18+
s0 = Source.wavevector;
19+
20+
e1 = zeros(size(s_refl));
21+
e2 = zeros(size(s_refl));
22+
e3 = zeros(size(s_refl));
23+
24+
for j=1:size(s_refl,1)
25+
k1 = s0 + s_refl(j,:);
26+
e1(j,:) = quickcross(k1,s0);
27+
e1(j,:) = e1(j,:)/sqrt(quickdot(e1(j,:),e1(j,:)));
28+
29+
e2(j,:) = quickcross(k1,e1(j,:));
30+
e2(j,:) = e2(j,:)/sqrt(quickdot(e2(j,:),e2(j,:)));
31+
32+
e3(j,:) = (k1 + s0);
33+
e3(j,:) = e3(j,:)/sqrt(quickdot(e3(j,:),e3(j,:)));
34+
end
35+
end
36+
37+
function [phixy1,phixy2] = s2phi(s_refl,Source,Spindle,Detector)
38+
% I changed how this works on 3/25/2019. It used to return:
39+
% [phi, x, y] for whichever solution had the lowest value of
40+
% |phi|.
41+
42+
s0 = Source.wavevector;
43+
m2 = Spindle.rotationAxis;
44+
f = Detector.f;
45+
ed = Detector.ed;
46+
[phixy1, phixy2] = calc_reflection_center(s0, m2, f, ed, s_refl);
47+
48+
% [c1,c2] = calc_reflection_center(s0, m2, f, ed, s_refl);
49+
% all_phi = [c1(:,1),c2(:,1)];
50+
% [~,ix] = min(abs(all_phi),[],2);
51+
%
52+
% c = c1;
53+
% for j=1:size(all_phi,1)
54+
% if ix(j)==2
55+
% c(j,:) = c2(j,:);
56+
% end
57+
% end
58+
%
59+
% x = c(:,2);
60+
% y = c(:,3);
61+
% phi = c(:,1);
62+
end
63+
64+
function [eps1,eps2] = s2eps(sx,sy,sz,idx,s,e1,e2,Source,Detector)
65+
66+
nrefl = size(s,1);
67+
68+
s0 = Source.wavevector;
69+
ed = Detector.ed;
70+
71+
d1 = ed(:,1)';
72+
d2 = ed(:,2)';
73+
d3 = ed(:,3)';
74+
75+
krefl = s + repmat(s0,nrefl,1);
76+
krefl_mag = sqrt(sum(krefl.*krefl,2));
77+
78+
d1_dot_e1 = sum(repmat(d1,nrefl,1).*e1,2);
79+
d1_dot_e2 = sum(repmat(d1,nrefl,1).*e2,2);
80+
81+
d2_dot_e1 = sum(repmat(d2,nrefl,1).*e1,2);
82+
d2_dot_e2 = sum(repmat(d2,nrefl,1).*e2,2);
83+
84+
d3_dot_e1 = sum(repmat(d3,nrefl,1).*e1,2);
85+
d3_dot_e2 = sum(repmat(d3,nrefl,1).*e2,2);
86+
87+
sx_refl = s(:,1);
88+
sy_refl = s(:,2);
89+
sz_refl = s(:,3);
90+
91+
eps1 = (180/pi)*((sx - sx_refl(idx)).*d1_dot_e1(idx) + ...
92+
(sy - sy_refl(idx)).*d2_dot_e1(idx) + ...
93+
(sz - sz_refl(idx)).*d3_dot_e1(idx))./krefl_mag(idx);
94+
95+
eps2 =(180/pi)* ((sx - sx_refl(idx)).*d1_dot_e2(idx) + ...
96+
(sy - sy_refl(idx)).*d2_dot_e2(idx) + ...
97+
(sz - sz_refl(idx)).*d3_dot_e2(idx))./krefl_mag(idx);
98+
99+
end
100+
101+
function Rj = partiality(phi,e1,sigmaM,Spindle,frame)
102+
% added frame argument on March 25, 2019
103+
m2 = Spindle.rotationAxis;
104+
dPhi = Spindle.oscillationRange;
105+
phiMid = Spindle.frame2phi(frame);
106+
phi1 = phiMid - dPhi/2;
107+
phi2 = phiMid + dPhi/2; % before, assumed phimid = 0
108+
%disp([phi1,phi2])
109+
Rj = calc_partiality(phi,e1,phi1,phi2,sigmaM,m2);
110+
111+
end
112+
113+
end
114+
end
115+
116+
function c = quickdot(a,b)
117+
c = a(1)*b(1) + a(2)*b(2) + a(3)*b(3);
118+
end
119+
120+
function c = quickcross(a,b)
121+
c = zeros(1,3);
122+
c(1) = a(2)*b(3) - a(3)*b(2);
123+
c(2) = a(3)*b(1) - a(1)*b(3);
124+
c(3) = a(1)*b(2) - a(2)*b(1);
125+
end
126+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function R = calc_partiality(phi,e1,phi1,phi2,sigmaM,m2)
2+
% Feb 16, 2017: modified to use m2 as input rather than xds_parm
3+
4+
%m2 = xds_parm.rotation_axis;
5+
nrefl = size(phi,1);
6+
7+
% xi = m2 dot e1
8+
xi = sum(repmat(m2,nrefl,1).*e1,2);
9+
10+
a = abs(xi)/(sqrt(2)*sigmaM);
11+
12+
R = 0.5 * (erf(a.*(phi2-phi)) - erf(a.*(phi1-phi)));
13+
14+
end
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
function [c1,c2] = calc_reflection_center(s0, m2, f, ed, p0star)
2+
%
3+
% columns of c1, c2: phi,x,y,p1,p2,p3
4+
%
5+
% where p1,p2,p3 are the reciprocal space coordinates once rotated into the
6+
% diffraction condition
7+
%
8+
% xparm = structure containing xds parameters
9+
%
10+
% p0star = some arbitrary point of interest in reciprocal space of the
11+
% unrotated crystal (inverse angstrom)
12+
%
13+
% c1 = [phi,x,y]; <- first set of solutions
14+
% c2 = [phi,x,y]; <- second set of solutions
15+
%
16+
% partly vectorized on May 18, 2015
17+
% (several operations could be more succinctly written as matrix
18+
% multiplications)
19+
%
20+
% removed x0, and y0 (x and y are now relative to detector origin)
21+
%
22+
% moved to scatterbrain project: Feb 17, 2017
23+
%
24+
% removed xparm. now s0, m2, f, ed are passed as arguments
25+
26+
%s0 = xparm.incident_wavevector;
27+
%m2 = xparm.rotation_axis;
28+
m1 = cross(m2,s0); m1 = m1/sqrt(dot(m1,m1));
29+
m3 = cross(m1,m2);
30+
31+
%f = xparm.detector.f;
32+
%d1 = xparm.detector.ed(:,1)';
33+
%d2 = xparm.detector.ed(:,2)';
34+
%d3 = xparm.detector.ed(:,3)';
35+
36+
d1 = ed(:,1)';
37+
d2 = ed(:,2)';
38+
d3 = ed(:,3)';
39+
40+
p0star_dot_p0star = ...
41+
p0star(:,1).*p0star(:,1) + ...
42+
p0star(:,2).*p0star(:,2) + ...
43+
p0star(:,3).*p0star(:,3);
44+
45+
p0star_dot_m2 = ...
46+
p0star(:,1)*m2(1) + ...
47+
p0star(:,2)*m2(2) + ...
48+
p0star(:,3)*m2(3);
49+
50+
p0star_dot_m1 = ...
51+
p0star(:,1)*m1(1) + ...
52+
p0star(:,2)*m1(2) + ...
53+
p0star(:,3)*m1(3);
54+
55+
p0star_dot_m3 = ...
56+
p0star(:,1)*m3(1) + ...
57+
p0star(:,2)*m3(2) + ...
58+
p0star(:,3)*m3(3);
59+
60+
rho_squared = p0star_dot_p0star - p0star_dot_m2.*p0star_dot_m2;
61+
%rho = sqrt(rho_squared); % distance to rot. axis
62+
63+
pstar_dot_m3 = (-0.5*p0star_dot_p0star - p0star_dot_m2*dot(s0,m2))/dot(s0,m3);
64+
pstar_dot_m2 = p0star_dot_m2;
65+
66+
% check not in blind region
67+
68+
isoutside = rho_squared < (pstar_dot_m3.*pstar_dot_m3) | ...
69+
p0star_dot_p0star > 4*dot(s0,s0);
70+
pstar_dot_m1 = sqrt(rho_squared - pstar_dot_m3.*pstar_dot_m3);
71+
pstar_dot_m1(isoutside) = NaN;
72+
cos_phi = (pstar_dot_m1.*p0star_dot_m1 + ...
73+
pstar_dot_m3.*p0star_dot_m3)./rho_squared;
74+
sin_phi = (pstar_dot_m1.*p0star_dot_m3 - ...
75+
pstar_dot_m3.*p0star_dot_m1)./rho_squared;
76+
phi = atan2(sin_phi,cos_phi)*180/pi;
77+
pstar = [m1(1)*pstar_dot_m1 + m2(1)*pstar_dot_m2 + m3(1)*pstar_dot_m3,...
78+
m1(2)*pstar_dot_m1 + m2(2)*pstar_dot_m2 + m3(2)*pstar_dot_m3,...
79+
m1(3)*pstar_dot_m1 + m2(3)*pstar_dot_m2 + m3(3)*pstar_dot_m3];
80+
S_dot_d1 = (pstar(:,1) + s0(1))*d1(1) + ...
81+
(pstar(:,2) + s0(2))*d1(2) + ...
82+
(pstar(:,3) + s0(3))*d1(3);
83+
S_dot_d2 = (pstar(:,1) + s0(1))*d2(1) + ...
84+
(pstar(:,2) + s0(2))*d2(2) + ...
85+
(pstar(:,3) + s0(3))*d2(3);
86+
S_dot_d3 = (pstar(:,1) + s0(1))*d3(1) + ...
87+
(pstar(:,2) + s0(2))*d3(2) + ...
88+
(pstar(:,3) + s0(3))*d3(3);
89+
90+
x = f*S_dot_d1./S_dot_d3;
91+
y = f*S_dot_d2./S_dot_d3;
92+
c1 = [phi,x,y,pstar];
93+
94+
pstar_dot_m1 = -1*sqrt(rho_squared - pstar_dot_m3.*pstar_dot_m3);
95+
pstar_dot_m1(isoutside) = NaN;
96+
cos_phi = (pstar_dot_m1.*p0star_dot_m1 + ...
97+
pstar_dot_m3.*p0star_dot_m3)./rho_squared;
98+
sin_phi = (pstar_dot_m1.*p0star_dot_m3 - ...
99+
pstar_dot_m3.*p0star_dot_m1)./rho_squared;
100+
phi = atan2(sin_phi,cos_phi)*180/pi;
101+
pstar = [m1(1)*pstar_dot_m1 + m2(1)*pstar_dot_m2 + m3(1)*pstar_dot_m3,...
102+
m1(2)*pstar_dot_m1 + m2(2)*pstar_dot_m2 + m3(2)*pstar_dot_m3,...
103+
m1(3)*pstar_dot_m1 + m2(3)*pstar_dot_m2 + m3(3)*pstar_dot_m3];
104+
105+
S_dot_d1 = (pstar(:,1) + s0(1))*d1(1) + ...
106+
(pstar(:,2) + s0(2))*d1(2) + ...
107+
(pstar(:,3) + s0(3))*d1(3);
108+
S_dot_d2 = (pstar(:,1) + s0(1))*d2(1) + ...
109+
(pstar(:,2) + s0(2))*d2(2) + ...
110+
(pstar(:,3) + s0(3))*d2(3);
111+
S_dot_d3 = (pstar(:,1) + s0(1))*d3(1) + ...
112+
(pstar(:,2) + s0(2))*d3(2) + ...
113+
(pstar(:,3) + s0(3))*d3(3);
114+
115+
x = f*S_dot_d1./S_dot_d3;
116+
y = f*S_dot_d2./S_dot_d3;
117+
c2 = [phi,x,y,pstar];
118+
119+
end

+geom/@Scattering/ewald2hkl.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119

120120
% apply symmetry limits
121121
indh = indh(sum((indh*Binv).^2,2) <= smax^2,:);
122-
122+
123123
% unique list of miller indices with edges that intersect the ewald sphere
124124
hkl = unique([indh;indk;indl],'rows');
125125

0 commit comments

Comments
 (0)