forked from mtex-toolbox/mtex
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathphaseList.m
292 lines (218 loc) · 8.05 KB
/
phaseList.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
classdef phaseList
% handles a list of phases
properties
phaseId = [] % index to a phase map - 1,2,3,4,....
CSList = {} % list of crystal symmetries
phaseMap = [] % phase numbers as used in the data - 0,5,10,11,...
end
properties (Dependent = true)
phase % phase
isIndexed % indexed measurements
CS % crystal symmetry of one specific phase
mineral % mineral name of one specific phase
mineralList % list of mineral names
indexedPhasesId % id's of all non empty indexed phase
color % color of one specific phase
end
methods
function pL = phaseList(phases,CSList)
if nargin == 2, pL = pL.init(phases,CSList); end
end
% --------------------------------------------------------------
function pL = init(pL,phases,CSList)
% extract phases
[pL.phaseMap,~,pL.phaseId] = unique(phases);
pL.phaseMap(isnan(pL.phaseMap)) = 0;
pL.CSList = ensurecell(CSList);
% check number of symmetries and phases coincides
if numel(pL.phaseMap)>1 && length(pL.CSList) == 1
% if only one symmetry was specified
% apply this symmetry to all phases except a zero phase
pL.CSList = repmat(pL.CSList,numel(pL.phaseMap),1);
if pL.phaseMap(1) <= 0, pL.CSList{1} = 'notIndexed'; end
elseif numel(pL.phaseMap) > length(pL.CSList)
% if to few symmetries have been specified
% prepend as many not indexed phases as required
pL.CSList = [repcell('notIndexed',1,numel(pL.phaseMap)-length(pL.CSList)),pL.CSList];
elseif numel(pL.phaseMap) < length(pL.CSList)
% if more symmetries have been specified then phases are present in
% the data
first = isa(pL.CSList{1},'symmetry');
% if everything is indexed but phase is 0
if (max(pL.phaseMap) == 0) && ~first
pL.phaseMap = [-1;pL.phaseMap(:)];
pL.phaseId = 1 + pL.phaseId;
% the normal case: there are simply some phases missing
% all we have to do is to extend the phaseMap
elseif ~first + max(pL.phaseMap) <= numel(pL.CSList)
%
pL.phaseId = ~first + pL.phaseMap(pL.phaseId);
% extend phaseMap
pL.phaseMap = first + (0:numel(pL.CSList)-1);
else
% no zero phase - maybe everything was indexed
if pL.phaseMap(1) > 0 && isa(pL.CSList{1},'symmetry')
pL.phaseId = pL.phaseId + 1;
pL.phaseMap = [0;pL.phaseMap];
end
% append some phase numbers for the not existing phases
pL.phaseMap = [pL.phaseMap;max(pL.phaseMap) + (1:length(pL.CSList)-numel(pL.phaseMap))];
end
end
% ensure that there is at least one notIndexed phase
% by prepending it !! TODO
% this probably requires to specify phaseMap as an option
if all(cellfun(@(x) isa(x,'symmetry'),pL.CSList))
pL.CSList = [{'notIndexed'};pL.CSList(:)];
pL.phaseId = pL.phaseId + 1;
if ismember(0,pL.phaseMap)
pL.phaseMap = [-1;pL.phaseMap(:)];
else
pL.phaseMap = [0;pL.phaseMap(:)];
end
end
% apply colors
colorOrder = getMTEXpref('EBSDColorNames');
nc = numel(colorOrder);
c = 1;
for ph = 1:numel(pL.phaseMap)
if isa(pL.CSList{ph},'symmetry') && isempty(pL.CSList{ph}.color)
pL.CSList{ph}.color = colorOrder{mod(c-1,nc)+1};
c = c+1;
end
end
end
function phase = get.phase(pL)
phase = zeros(size(pL));
isIndex = pL.phaseId>0;
phase(isIndex) = pL.phaseMap(pL.phaseId(isIndex));
end
function pL = set.phase(pL,phase)
if numel(phase) == 1
phase = repmat(phase,size(pL.phaseId));
elseif numel(phase) == numel(pL.phaseId)
phase = reshape(phase,size(pL.phaseId));
else
error('List of phases has wrong size.')
end
phId = zeros(size(phase));
for i = 1:numel(pL.phaseMap)
phId(phase==pL.phaseMap(i)) = i;
end
pL.phaseId = phId;
end
function id = get.indexedPhasesId(pL)
id = intersect(...
find(~cellfun('isclass',pL.CSList,'char')),...
unique(pL.phaseId));
id = id(:).';
end
function cs = get.CS(pL)
% ensure single phase
id = checkSinglePhase(pL);
if numel(id) > 1
cs = pL.CSList(id);
else
cs = pL.CSList{id};
end
end
function pL = set.CS(pL,cs)
if isa(cs,'symmetry')
% ensure single phase
id = unique(pL.phaseId);
if numel(id) == 1
pL.CSList{id} = cs;
else
% TODO
end
elseif iscell(cs)
if length(cs) == numel(pL.phaseMap)
pL.CSList = cs;
elseif length(cs) == numel(pL.indexedPhasesId)
pL.CSList = repcell('notIndexed',1,numel(pL.phaseMap));
pL.CSList(pL.indexedPhasesId) = cs;
else
error('The number of symmetries specified is less than the largest phase id.')
end
else
error('Assignment should be of type symmetry');
end
% set CSList also to all children
for fn = fieldnames(pL).'
try %#ok<TRYNC>
if isa(pL.(char(fn)),'phaseList')
pL.(char(fn)).CSList = pL.CSList;
end
end
end
end
function mineral = get.mineral(pL)
cs = pL.CS;
if iscell(cs)
mineral = {cs{1}.mineral,cs{2}.mineral};
else
mineral = cs.mineral;
end
end
function pL = set.color(pL,color)
pL.CS.color = color;
end
function c = get.color(pL)
% notindexed phase should be white by default
if ~any(pL.isIndexed)
c = ones(1,3);
return
end
% ensure single phase and extract symmetry
cs = pL.CS;
% extract colormaps
cmap = getMTEXpref('EBSDColors');
colorNames = getMTEXpref('EBSDColorNames');
if isempty(cs.color)
c = cmap{pL.phaseId};
elseif ischar(cs.color)
c = cmap{strcmpi(cs.color,colorNames)};
else
c = cs.color;
end
end
function minerals = get.mineralList(pL)
isCS = cellfun('isclass',pL.CSList,'crystalSymmetry');
minerals(isCS) = cellfun(@(x) x.mineral,pL.CSList(isCS),'uniformoutput',false);
minerals(~isCS) = pL.CSList(~isCS);
end
function isInd = get.isIndexed(pL)
notIndexedPhase = [0,find(cellfun('isclass',pL.CSList,'char'))];
isInd = ~any(ismember(pL.phaseId,notIndexedPhase),2);
end
function out = isempty(pL)
out = isempty(pL.phaseId);
end
function varargout = size(pL,varargin)
[varargout{1:nargout}] = size(pL.phaseId(:,1),varargin{:});
end
function out = length(pL)
out = size(pL.phaseId,1);
end
function e = end(pL,i,n)
if n==1
e = size(pL.phaseId,1);
else
e = size(pL.phaseId,i);
end
end
function id = checkSinglePhase(pL)
% ensure single phase
phaseId = pL.phaseId; %#ok<*PROP>
phaseId = phaseId(~any(isnan(pL.phaseId),2),:);
id = unique(phaseId,'rows');
if numel(id)>size(pL.phaseId,2)
error('MTEX:MultiplePhases',['This operatorion is only permitted for a single phase! ' ...
'Please see ' doclink('EBSDModifyData','modify EBSD data') ...
' for how to restrict EBSD data to a single phase.']);
elseif isempty(id) || ~all(any(bsxfun(@eq,id,pL.indexedPhasesId(:)),1))
error('MTEX:NoPhase','There are no indexed data in this variable!');
end
end
end
end