-
Notifications
You must be signed in to change notification settings - Fork 38
Description
Comparing the source code of setSampleProfile() and set_HAP_refinements() I found discrepancies between the list indices used for values and refine flags for size, mustrain, and their LG_mix parameters.
After some manual flipping of size parameter values and refine flags in the GUI followed by checking the size list returned (e.g., by calling proj.data['Phases'][phase_name]['Histograms'][proj.histograms()[0].name]['Size']) I believe this is the correct list structure:
['isotropic', # [0]: str for broadening type. 'isotropic', 'uniaxial', or 'ellipsoidal'
[1.0, 1.0, 1.0], # [1][0]: iso size or equatorial size, [1][1]: axial size (if uniaxial used, else ignored), [1][2]: LG_mix (eta parameter, 1 = Lorentzian, 0 = Gaussian)
[False, False, False], # boolean refinement flags. [2][0]: isotropic or uniaxial equatorial refine, [2][1]: uniaxial axial refine, [2][2]: LG_mix refine
[0, 0, 1], # hkl direction for uniaxial broadening. [3][0]: h, [3][1]: k, [3][2]: l
[1.0, 1.0, 1.0, 0.0, 0.0, 0.0], # ellipsoidal sizes. S11, S22, S33, S12, S13, S23 for [4][0:6]
[False, False, False, False, False, False]] # ellipsoidal size refine flags. S11, S22, S33, S12, S13, S23 for [5][0:6]
If the above is correct, then setSampleProfile() uses the correct indices, and set_HAP_refinements() should be updated as provided in the code block below. It looks like the mustrain parameterization has a similar error which I've corrected. I am happy to open a pull request with these changes, but wanted to check if these changes will impact other methods in G2sc first.
For convenience in finding the changes within the function, here are the lines changed:
#mustrain[2][1] = types
#mustrain[2][2] = types
mustrain[2][0] = types
mustrain[2][1] = types
#size[2][1] = bool(refine)
#size[2][2] = bool(refine)
size[2][0] = bool(refine)
size[2][1] = bool(refine)
Updated function:
def set_HAP_refinements(self, refs, histograms='all'):
"""Sets the given HAP refinement parameters between the current phase and
the specified histograms.
:param dict refs: A dictionary of the parameters to be set. See
the :ref:`HAP_parameters_table` table for a description of this
dictionary.
:param histograms: Either 'all' (default) or a list of the histograms by index, name
or object. The index number is relative to all histograms in the tree, not to
those in the phase.
Histograms not associated with the current phase will be ignored.
whose HAP parameters will be set with this phase. Histogram and phase
must already be associated.
:returns: None
"""
if not self.data.get('Histograms',[]):
G2fil.G2Print("Error likely: Phase {} has no linked histograms".format(self.name))
return
if histograms == 'all':
histograms = self.data['Histograms'].keys()
else:
histograms = [self._decodeHist(h) for h in histograms
if self._decodeHist(h) in self.data['Histograms']]
if not histograms:
G2fil.G2Print("Warning: Skipping HAP set for phase {}, no selected histograms".format(self.name))
return
# remove non-PWDR (HKLF) histograms
histograms = [i for i in histograms if self.proj.histType(i) == 'PWDR']
if not histograms: return
for key, val in refs.items():
if key == 'Babinet':
try:
sets = list(val)
except ValueError:
sets = ['BabA', 'BabU']
for param in sets:
if param not in ['BabA', 'BabU']:
raise ValueError("Not sure what to do with" + param)
for h in histograms:
self.data['Histograms'][h]['Babinet'][param][1] = True
elif key == 'Extinction':
for h in histograms:
self.data['Histograms'][h]['Extinction'][1] = bool(val)
elif key == 'HStrain':
if isinstance(val,list) or isinstance(val,tuple):
for h in histograms:
if len(self.data['Histograms'][h]['HStrain'][1]) != len(val):
raise Exception('Need {} HStrain terms for phase {} hist {}'
.format(len(self.data['Histograms'][h]['HStrain'][1]),self.name,h))
for i,v in enumerate(val):
self.data['Histograms'][h]['HStrain'][1][i] = bool(v)
else:
for h in histograms:
self.data['Histograms'][h]['HStrain'][1] = [bool(val) for p in self.data['Histograms'][h]['HStrain'][1]]
elif key == 'Mustrain':
for h in histograms:
mustrain = self.data['Histograms'][h]['Mustrain']
newType = mustrain[0]
direction = None
if isinstance(val, (str,bytes)):
if val in ['isotropic', 'uniaxial', 'generalized']:
newType = val
else:
raise ValueError("Not a Mustrain type: " + val)
elif isinstance(val, dict):
newType = val.get('type', newType)
direction = val.get('direction', None)
if newType:
mustrain[0] = newType
if newType == 'isotropic':
mustrain[2][0] = True == val.get('refine',False)
mustrain[5] = [False for p in mustrain[4]]
elif newType == 'uniaxial':
if 'refine' in val:
mustrain[2][0] = False
types = val['refine']
if isinstance(types, (str,bytes)):
types = [types]
elif isinstance(types, bool):
#mustrain[2][1] = types
#mustrain[2][2] = types
mustrain[2][0] = types
mustrain[2][1] = types
types = []
else:
raise ValueError("Not sure what to do with: "
+ str(types))
else:
types = []
for unitype in types:
if unitype == 'equatorial':
mustrain[2][0] = True
elif unitype == 'axial':
mustrain[2][1] = True
else:
msg = 'Invalid uniaxial mustrain type'
raise ValueError(msg + ': ' + unitype)
else: # newtype == 'generalized'
mustrain[2] = [False for p in mustrain[1]]
if 'refine' in val:
mustrain[5] = [True == val['refine']]*len(mustrain[5])
if direction:
if len(direction) != 3:
raise ValueError("Expected hkl, found", direction)
direction = [int(n) for n in direction]
mustrain[3] = direction
elif key == 'Size':
newSize = None
if 'value' in val:
newSize = float(val['value'])
for h in histograms:
size = self.data['Histograms'][h]['Size']
newType = size[0]
direction = None
if isinstance(val, (str,bytes)):
if val in ['isotropic', 'uniaxial', 'ellipsoidal']:
newType = val
else:
raise ValueError("Not a valid Size type: " + val)
elif isinstance(val, dict):
newType = val.get('type', size[0])
direction = val.get('direction', None)
if newType:
size[0] = newType
refine = bool(val.get('refine'))
if newType == 'isotropic' and refine is not None:
size[2][0] = bool(refine)
if newSize: size[1][0] = newSize
elif newType == 'uniaxial' and refine is not None:
#size[2][1] = bool(refine)
#size[2][2] = bool(refine)
size[2][0] = bool(refine)
size[2][1] = bool(refine)
if newSize: size[1][0] = size[1][1] =newSize
elif newType == 'ellipsoidal' and refine is not None:
size[5] = [bool(refine) for p in size[5]]
if newSize: size[4] = [newSize for p in size[4]]
if direction:
if len(direction) != 3:
raise ValueError("Expected hkl, found", direction)
direction = [int(n) for n in direction]
size[3] = direction
elif key == 'Pref.Ori.':
for h in histograms:
self.data['Histograms'][h]['Pref.Ori.'][2] = bool(val)
elif key == 'Show':
for h in histograms:
self.data['Histograms'][h]['Show'] = bool(val)
elif key == 'Use':
for h in histograms:
self.data['Histograms'][h]['Use'] = bool(val)
elif key == 'Scale' or key == 'PhaseFraction':
for h in histograms:
self.data['Histograms'][h]['Scale'][1] = bool(val)
else:
G2fil.G2Print('Warning: Unknown HAP key: '+key)