diffpy.srfit 3.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- diffpy/__init__.py +15 -0
- diffpy/srfit/__init__.py +41 -0
- diffpy/srfit/equation/__init__.py +31 -0
- diffpy/srfit/equation/builder.py +702 -0
- diffpy/srfit/equation/equationmod.py +213 -0
- diffpy/srfit/equation/literals/__init__.py +71 -0
- diffpy/srfit/equation/literals/abcs.py +81 -0
- diffpy/srfit/equation/literals/argument.py +76 -0
- diffpy/srfit/equation/literals/literal.py +69 -0
- diffpy/srfit/equation/literals/operators.py +380 -0
- diffpy/srfit/equation/visitors/__init__.py +94 -0
- diffpy/srfit/equation/visitors/argfinder.py +62 -0
- diffpy/srfit/equation/visitors/printer.py +120 -0
- diffpy/srfit/equation/visitors/swapper.py +142 -0
- diffpy/srfit/equation/visitors/validator.py +113 -0
- diffpy/srfit/equation/visitors/visitor.py +62 -0
- diffpy/srfit/exceptions.py +29 -0
- diffpy/srfit/fitbase/__init__.py +53 -0
- diffpy/srfit/fitbase/calculator.py +110 -0
- diffpy/srfit/fitbase/configurable.py +57 -0
- diffpy/srfit/fitbase/constraint.py +117 -0
- diffpy/srfit/fitbase/fitcontribution.py +351 -0
- diffpy/srfit/fitbase/fithook.py +227 -0
- diffpy/srfit/fitbase/fitrecipe.py +826 -0
- diffpy/srfit/fitbase/fitresults.py +674 -0
- diffpy/srfit/fitbase/parameter.py +314 -0
- diffpy/srfit/fitbase/parameterset.py +110 -0
- diffpy/srfit/fitbase/profile.py +405 -0
- diffpy/srfit/fitbase/profilegenerator.py +168 -0
- diffpy/srfit/fitbase/profileparser.py +179 -0
- diffpy/srfit/fitbase/recipeorganizer.py +1074 -0
- diffpy/srfit/fitbase/restraint.py +117 -0
- diffpy/srfit/fitbase/simplerecipe.py +230 -0
- diffpy/srfit/fitbase/validatable.py +59 -0
- diffpy/srfit/interface/__init__.py +33 -0
- diffpy/srfit/interface/interface.py +180 -0
- diffpy/srfit/pdf/__init__.py +24 -0
- diffpy/srfit/pdf/basepdfgenerator.py +296 -0
- diffpy/srfit/pdf/characteristicfunctions.py +432 -0
- diffpy/srfit/pdf/debyepdfgenerator.py +115 -0
- diffpy/srfit/pdf/pdfcontribution.py +311 -0
- diffpy/srfit/pdf/pdfgenerator.py +77 -0
- diffpy/srfit/pdf/pdfparser.py +226 -0
- diffpy/srfit/sas/__init__.py +30 -0
- diffpy/srfit/sas/prcalculator.py +139 -0
- diffpy/srfit/sas/sasgenerator.py +70 -0
- diffpy/srfit/sas/sasimport.py +66 -0
- diffpy/srfit/sas/sasparameter.py +70 -0
- diffpy/srfit/sas/sasparser.py +133 -0
- diffpy/srfit/sas/sasprofile.py +94 -0
- diffpy/srfit/structure/__init__.py +60 -0
- diffpy/srfit/structure/basestructureparset.py +62 -0
- diffpy/srfit/structure/bvsrestraint.py +101 -0
- diffpy/srfit/structure/cctbxparset.py +292 -0
- diffpy/srfit/structure/diffpyparset.py +303 -0
- diffpy/srfit/structure/objcrystparset.py +1552 -0
- diffpy/srfit/structure/sgconstraints.py +761 -0
- diffpy/srfit/structure/srrealparset.py +92 -0
- diffpy/srfit/util/__init__.py +50 -0
- diffpy/srfit/util/argbinders.py +29 -0
- diffpy/srfit/util/inpututils.py +50 -0
- diffpy/srfit/util/nameutils.py +45 -0
- diffpy/srfit/util/observable.py +93 -0
- diffpy/srfit/util/tagmanager.py +150 -0
- diffpy/srfit/util/weakrefcallable.py +170 -0
- diffpy/srfit/version.py +26 -0
- diffpy_srfit-3.1.0.dist-info/METADATA +216 -0
- diffpy_srfit-3.1.0.dist-info/RECORD +73 -0
- diffpy_srfit-3.1.0.dist-info/WHEEL +5 -0
- diffpy_srfit-3.1.0.dist-info/licenses/AUTHORS.rst +10 -0
- diffpy_srfit-3.1.0.dist-info/licenses/LICENSE.rst +138 -0
- diffpy_srfit-3.1.0.dist-info/licenses/LICENSE_DANSE.rst +34 -0
- diffpy_srfit-3.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
##############################################################################
|
|
3
|
+
#
|
|
4
|
+
# diffpy.srfit by DANSE Diffraction group
|
|
5
|
+
# Simon J. L. Billinge
|
|
6
|
+
# (c) 2010 The Trustees of Columbia University
|
|
7
|
+
# in the City of New York. All rights reserved.
|
|
8
|
+
#
|
|
9
|
+
# File coded by: Chris Farrow
|
|
10
|
+
#
|
|
11
|
+
# See AUTHORS.txt for a list of people who contributed.
|
|
12
|
+
# See LICENSE_DANSE.txt for license information.
|
|
13
|
+
#
|
|
14
|
+
##############################################################################
|
|
15
|
+
"""Bond-valence sum calculator from SrReal wrapped as a Restraint.
|
|
16
|
+
|
|
17
|
+
This can be used as an addition to a cost function during a structure
|
|
18
|
+
refinement to keep the bond-valence sum within tolerable limits.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
__all__ = ["BVSRestraint"]
|
|
22
|
+
|
|
23
|
+
from diffpy.srfit.exceptions import SrFitError
|
|
24
|
+
from diffpy.srfit.fitbase.restraint import Restraint
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class BVSRestraint(Restraint):
|
|
28
|
+
"""Wrapping of BVSCalculator.bvmsdiff as a Restraint.
|
|
29
|
+
|
|
30
|
+
The restraint penalty is the root-mean-square deviation of the theoretical
|
|
31
|
+
and calculated bond-valence sum of a structure.
|
|
32
|
+
|
|
33
|
+
Attributes:
|
|
34
|
+
_calc -- The SrReal BVSCalculator instance.
|
|
35
|
+
_parset -- The SrRealParSet that created this BVSRestraint.
|
|
36
|
+
sig -- The uncertainty on the BVS (default 1).
|
|
37
|
+
scaled -- A flag indicating if the restraint is scaled (multiplied)
|
|
38
|
+
by the unrestrained point-average chi^2 (chi^2/numpoints)
|
|
39
|
+
(default False).
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self, parset, sig=1, scaled=False):
|
|
43
|
+
"""Initialize the Restraint.
|
|
44
|
+
|
|
45
|
+
parset -- SrRealParSet that creates this BVSRestraint.
|
|
46
|
+
sig -- The uncertainty on the BVS (default 1).
|
|
47
|
+
scaled -- A flag indicating if the restraint is scaled
|
|
48
|
+
(multiplied) by the unrestrained point-average chi^2
|
|
49
|
+
(chi^2/numpoints) (bool, default False).
|
|
50
|
+
"""
|
|
51
|
+
from diffpy.srreal.bvscalculator import BVSCalculator
|
|
52
|
+
|
|
53
|
+
self._calc = BVSCalculator()
|
|
54
|
+
self._parset = parset
|
|
55
|
+
self.sig = float(sig)
|
|
56
|
+
self.scaled = bool(scaled)
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
def penalty(self, w=1.0):
|
|
60
|
+
"""Calculate the penalty of the restraint.
|
|
61
|
+
|
|
62
|
+
w -- The point-average chi^2 which is optionally used to scale the
|
|
63
|
+
penalty (float, default 1.0).
|
|
64
|
+
"""
|
|
65
|
+
# Get the bvms from the BVSCalculator
|
|
66
|
+
stru = self._parset._getSrRealStructure()
|
|
67
|
+
self._calc.eval(stru)
|
|
68
|
+
penalty = self._calc.bvmsdiff
|
|
69
|
+
|
|
70
|
+
# Scale by the prefactor
|
|
71
|
+
penalty /= self.sig**2
|
|
72
|
+
|
|
73
|
+
# Optionally scale by w
|
|
74
|
+
if self.scaled:
|
|
75
|
+
penalty *= w
|
|
76
|
+
|
|
77
|
+
return penalty
|
|
78
|
+
|
|
79
|
+
def _validate(self):
|
|
80
|
+
"""This evaluates the calculator.
|
|
81
|
+
|
|
82
|
+
Raises SrFitError if validation fails.
|
|
83
|
+
"""
|
|
84
|
+
from numpy import nan
|
|
85
|
+
|
|
86
|
+
p = self.penalty()
|
|
87
|
+
if p is None or p is nan:
|
|
88
|
+
raise SrFitError("Cannot evaluate penalty")
|
|
89
|
+
v = self._calc.value
|
|
90
|
+
if len(v) > 1 and not v.any():
|
|
91
|
+
emsg = (
|
|
92
|
+
"Bond valence sums are all zero. Check atom symbols in "
|
|
93
|
+
"the structure or define custom bond-valence parameters."
|
|
94
|
+
)
|
|
95
|
+
raise SrFitError(emsg)
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
# End of class BVSRestraint
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# End of file
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
##############################################################################
|
|
3
|
+
#
|
|
4
|
+
# diffpy.srfit by DANSE Diffraction group
|
|
5
|
+
# Simon J. L. Billinge
|
|
6
|
+
# (c) 2009 The Trustees of Columbia University
|
|
7
|
+
# in the City of New York. All rights reserved.
|
|
8
|
+
#
|
|
9
|
+
# File coded by: Chris Farrow
|
|
10
|
+
#
|
|
11
|
+
# See AUTHORS.txt for a list of people who contributed.
|
|
12
|
+
# See LICENSE_DANSE.txt for license information.
|
|
13
|
+
#
|
|
14
|
+
##############################################################################
|
|
15
|
+
"""Wrappers for interfacing cctbx crystal with SrFit.
|
|
16
|
+
|
|
17
|
+
This wraps a cctbx.crystal as a ParameterSet with a similar hierarchy, which
|
|
18
|
+
can then be used within a FitRecipe. Note that all manipulations to the
|
|
19
|
+
cctbx.crystal should be done before wrapping. Changes made to the cctbx.crystal
|
|
20
|
+
object after wrapping may not be reflected within the wrapper, which can have
|
|
21
|
+
unpredictable results during a structure refinement.
|
|
22
|
+
|
|
23
|
+
Classes:
|
|
24
|
+
|
|
25
|
+
CCTBXCrystalParSet -- Wrapper for cctbx.crystal
|
|
26
|
+
CCTBXUnitCellParSet -- Wrapper for the unit cell of cctbx.crystal
|
|
27
|
+
CCTBXScattererParSet -- Wrapper for cctbx.xray.scatterer
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from diffpy.srfit.fitbase.parameter import ParameterAdapter
|
|
31
|
+
from diffpy.srfit.fitbase.parameterset import ParameterSet
|
|
32
|
+
from diffpy.srfit.structure.basestructureparset import BaseStructureParSet
|
|
33
|
+
|
|
34
|
+
__all__ = ["CCTBXScattererParSet", "CCTBXUnitCellParSet", "CCTBXCrystalParSet"]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class CCTBXScattererParSet(ParameterSet):
|
|
38
|
+
"""A wrapper for cctbx.xray.scatterer.
|
|
39
|
+
|
|
40
|
+
This class derives from ParameterSet.
|
|
41
|
+
|
|
42
|
+
Attributes:
|
|
43
|
+
name -- Name of the scatterer. The name is always of the form
|
|
44
|
+
"%s%i" % (element, number), where the number is the running
|
|
45
|
+
index of that element type (starting at 0).
|
|
46
|
+
x (y, z) -- Atom position in crystal coordinates (ParameterAdapter)
|
|
47
|
+
occupancy -- Occupancy of the atom on its crystal location
|
|
48
|
+
(ParameterAdapter)
|
|
49
|
+
Uiso -- Isotropic scattering factor (ParameterAdapter).
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(self, name, strups, idx):
|
|
53
|
+
"""Initialize.
|
|
54
|
+
|
|
55
|
+
name -- The name of this scatterer.
|
|
56
|
+
strups -- The CCTBXCrystalParSet that contains the cctbx structure
|
|
57
|
+
idx -- The index of the scatterer in the structure.
|
|
58
|
+
"""
|
|
59
|
+
ParameterSet.__init__(self, name)
|
|
60
|
+
self.strups = strups
|
|
61
|
+
self.idx = idx
|
|
62
|
+
|
|
63
|
+
# x, y, z, occupancy
|
|
64
|
+
self.addParameter(
|
|
65
|
+
ParameterAdapter("x", None, self._xyzgetter(0), self._xyzsetter(0))
|
|
66
|
+
)
|
|
67
|
+
self.addParameter(
|
|
68
|
+
ParameterAdapter("y", None, self._xyzgetter(1), self._xyzsetter(1))
|
|
69
|
+
)
|
|
70
|
+
self.addParameter(
|
|
71
|
+
ParameterAdapter("z", None, self._xyzgetter(2), self._xyzsetter(2))
|
|
72
|
+
)
|
|
73
|
+
self.addParameter(
|
|
74
|
+
ParameterAdapter("occupancy", None, self._getocc, self._setocc)
|
|
75
|
+
)
|
|
76
|
+
self.addParameter(
|
|
77
|
+
ParameterAdapter("Uiso", None, self._getuiso, self._setuiso)
|
|
78
|
+
)
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
# Getters and setters
|
|
82
|
+
|
|
83
|
+
def _xyzgetter(self, i):
|
|
84
|
+
|
|
85
|
+
def f(dummy):
|
|
86
|
+
return self.strups.stru.scatterers()[self.idx].site[i]
|
|
87
|
+
|
|
88
|
+
return f
|
|
89
|
+
|
|
90
|
+
def _xyzsetter(self, i):
|
|
91
|
+
|
|
92
|
+
def f(dummy, value):
|
|
93
|
+
xyz = list(self.strups.stru.scatterers()[self.idx].site)
|
|
94
|
+
xyz[i] = value
|
|
95
|
+
self.strups.stru.scatterers()[self.idx].site = tuple(xyz)
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
return f
|
|
99
|
+
|
|
100
|
+
def _getocc(self, dummy):
|
|
101
|
+
return self.strups.stru.scatterers()[self.idx].occupancy
|
|
102
|
+
|
|
103
|
+
def _setocc(self, dummy, value):
|
|
104
|
+
self.strups.stru.scatterers()[self.idx].occupancy = value
|
|
105
|
+
return
|
|
106
|
+
|
|
107
|
+
def _getuiso(self, dummy):
|
|
108
|
+
return self.strups.stru.scatterers()[self.idx].u_iso
|
|
109
|
+
|
|
110
|
+
def _setuiso(self, dummy, value):
|
|
111
|
+
self.strups.stru.scatterers()[self.idx].u_iso = value
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
def _getElem(self):
|
|
115
|
+
return self.stru.element_symbol()
|
|
116
|
+
|
|
117
|
+
element = property(_getElem)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# End class CCTBXScattererParSet
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class CCTBXUnitCellParSet(ParameterSet):
|
|
124
|
+
"""A wrapper for cctbx unit_cell object.
|
|
125
|
+
|
|
126
|
+
Attributes:
|
|
127
|
+
name -- Always "unitcell".
|
|
128
|
+
a, b, c, alpha, beta, gamma -- Unit cell parameters (ParameterAdapter).
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
def __init__(self, strups):
|
|
132
|
+
"""Initialize.
|
|
133
|
+
|
|
134
|
+
strups -- The CCTBXCrystalParSet that contains the cctbx structure
|
|
135
|
+
and the unit cell we're wrapper.
|
|
136
|
+
"""
|
|
137
|
+
ParameterSet.__init__(self, "unitcell")
|
|
138
|
+
self.strups = strups
|
|
139
|
+
self._latpars = list(self.strups.stru.unit_cell().parameters())
|
|
140
|
+
|
|
141
|
+
self.addParameter(
|
|
142
|
+
ParameterAdapter("a", None, self._latgetter(0), self._latsetter(0))
|
|
143
|
+
)
|
|
144
|
+
self.addParameter(
|
|
145
|
+
ParameterAdapter("b", None, self._latgetter(1), self._latsetter(1))
|
|
146
|
+
)
|
|
147
|
+
self.addParameter(
|
|
148
|
+
ParameterAdapter("c", None, self._latgetter(2), self._latsetter(2))
|
|
149
|
+
)
|
|
150
|
+
self.addParameter(
|
|
151
|
+
ParameterAdapter(
|
|
152
|
+
"alpha", None, self._latgetter(3), self._latsetter(3)
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
self.addParameter(
|
|
156
|
+
ParameterAdapter(
|
|
157
|
+
"beta", None, self._latgetter(4), self._latsetter(4)
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
self.addParameter(
|
|
161
|
+
ParameterAdapter(
|
|
162
|
+
"gamma", None, self._latgetter(5), self._latsetter(5)
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
def _latgetter(self, i):
|
|
169
|
+
|
|
170
|
+
def f(dummy):
|
|
171
|
+
return self._latpars[i]
|
|
172
|
+
|
|
173
|
+
return f
|
|
174
|
+
|
|
175
|
+
def _latsetter(self, i):
|
|
176
|
+
|
|
177
|
+
def f(dummy, value):
|
|
178
|
+
self._latpars[i] = value
|
|
179
|
+
self.strups._update = True
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
return f
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# End class CCTBXUnitCellParSet
|
|
186
|
+
|
|
187
|
+
# FIXME - Special positions should be constant.
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class CCTBXCrystalParSet(BaseStructureParSet):
|
|
191
|
+
"""A wrapper for CCTBX structure.
|
|
192
|
+
|
|
193
|
+
Attributes:
|
|
194
|
+
stru -- The adapted cctbx structure object.
|
|
195
|
+
scatterers -- The list of ScattererParSets.
|
|
196
|
+
unitcell -- The CCTBXUnitCellParSet for the structure.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
def __init__(self, name, stru):
|
|
200
|
+
"""Initialize.
|
|
201
|
+
|
|
202
|
+
name -- A name for this
|
|
203
|
+
stru -- A CCTBX structure instance.
|
|
204
|
+
"""
|
|
205
|
+
ParameterSet.__init__(self, name)
|
|
206
|
+
self.stru = stru
|
|
207
|
+
self.addParameterSet(CCTBXUnitCellParSet(self))
|
|
208
|
+
self.scatterers = []
|
|
209
|
+
|
|
210
|
+
self._update = False
|
|
211
|
+
|
|
212
|
+
cdict = {}
|
|
213
|
+
for s in stru.scatterers():
|
|
214
|
+
el = s.element_symbol()
|
|
215
|
+
i = cdict.get(el, 0)
|
|
216
|
+
sname = "%s%i" % (el, i)
|
|
217
|
+
cdict[el] = i + 1
|
|
218
|
+
scatterer = CCTBXScattererParSet(sname, self, i)
|
|
219
|
+
self.addParameterSet(scatterer)
|
|
220
|
+
self.scatterers.append(scatterer)
|
|
221
|
+
|
|
222
|
+
# Constrain the lattice
|
|
223
|
+
from diffpy.srfit.structure.sgconstraints import _constrainSpaceGroup
|
|
224
|
+
|
|
225
|
+
symbol = self.getSpaceGroup()
|
|
226
|
+
_constrainSpaceGroup(self, symbol)
|
|
227
|
+
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
def update(self):
|
|
231
|
+
"""Update the unit_cell to a change in lattice parameters.
|
|
232
|
+
|
|
233
|
+
This remakes the unit cell according to a change in the lattice
|
|
234
|
+
parameters. Call this function before using the
|
|
235
|
+
CCTBXCrystalParSet. The unit_cell will only be remade if
|
|
236
|
+
necessary.
|
|
237
|
+
"""
|
|
238
|
+
if not self._update:
|
|
239
|
+
return
|
|
240
|
+
|
|
241
|
+
self._update = False
|
|
242
|
+
stru = self.stru
|
|
243
|
+
sgn = stru.space_group().match_tabulated_settings().number()
|
|
244
|
+
|
|
245
|
+
# Create the symmetry object
|
|
246
|
+
from cctbx.crystal import symmetry
|
|
247
|
+
|
|
248
|
+
symm = symmetry(
|
|
249
|
+
unit_cell=self.unitcell._latpars, space_group_symbol=sgn
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# Now the new structure
|
|
253
|
+
newstru = stru.__class__(
|
|
254
|
+
crystal_symmetry=symm, scatterers=stru.scatterers()
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
self.unitcell._latpars = list(newstru.unit_cell().parameters())
|
|
258
|
+
|
|
259
|
+
self.stru = newstru
|
|
260
|
+
return
|
|
261
|
+
|
|
262
|
+
@classmethod
|
|
263
|
+
def canAdapt(self, stru):
|
|
264
|
+
"""Return whether the structure can be adapted by this class."""
|
|
265
|
+
try:
|
|
266
|
+
from cctbx.crystal import special_position_settings
|
|
267
|
+
except ImportError:
|
|
268
|
+
return False
|
|
269
|
+
return isinstance(stru, special_position_settings)
|
|
270
|
+
|
|
271
|
+
def getLattice(self):
|
|
272
|
+
"""Get the ParameterSet containing the lattice Parameters."""
|
|
273
|
+
return self.unitcell
|
|
274
|
+
|
|
275
|
+
def getScatterers(self):
|
|
276
|
+
"""Get a list of ParameterSets that represents the scatterers.
|
|
277
|
+
|
|
278
|
+
The site positions must be accessible from the list entries via
|
|
279
|
+
the names "x", "y", and "z". The ADPs must be accessible as
|
|
280
|
+
well, but the name and nature of the ADPs (U-factors, B-factors,
|
|
281
|
+
isotropic, anisotropic) depends on the adapted structure.
|
|
282
|
+
"""
|
|
283
|
+
return self.scatterers
|
|
284
|
+
|
|
285
|
+
def getSpaceGroup(self):
|
|
286
|
+
"""Get the HM space group symbol for the structure."""
|
|
287
|
+
sg = self.stru.space_group()
|
|
288
|
+
t = sg.type()
|
|
289
|
+
return t.lookup_symbol()
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
# End class CCTBXCrystalParSet
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
##############################################################################
|
|
3
|
+
#
|
|
4
|
+
# diffpy.srfit by DANSE Diffraction group
|
|
5
|
+
# Simon J. L. Billinge
|
|
6
|
+
# (c) 2009 The Trustees of Columbia University
|
|
7
|
+
# in the City of New York. All rights reserved.
|
|
8
|
+
#
|
|
9
|
+
# File coded by: Chris Farrow
|
|
10
|
+
#
|
|
11
|
+
# See AUTHORS.txt for a list of people who contributed.
|
|
12
|
+
# See LICENSE_DANSE.txt for license information.
|
|
13
|
+
#
|
|
14
|
+
##############################################################################
|
|
15
|
+
"""Adapters for interfacing a diffpy.structure.Structure with SrFit.
|
|
16
|
+
|
|
17
|
+
A diffpy.structure.Structure object is meant to be passed to a
|
|
18
|
+
DiffpyStructureParSet object from this module, which can then be used as a
|
|
19
|
+
ParameterSet. (It has other methods for interfacing with SrReal calculator
|
|
20
|
+
adapters.) Any change to the lattice or existing atoms will be registered with
|
|
21
|
+
the Structure. Changes in the number of atoms will not be recognized. Thus,
|
|
22
|
+
the diffpy.structure.Structure object should be fully configured before passing
|
|
23
|
+
it to DiffpyStructureParSet.
|
|
24
|
+
|
|
25
|
+
DiffpyStructureParSet -- Adapter for diffpy.structure.Structure
|
|
26
|
+
DiffpyLatticeParSet -- Adapter for diffpy.structure.Lattice
|
|
27
|
+
DiffpyAtomParSet -- Adapter for diffpy.structure.Atom
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
__all__ = ["DiffpyStructureParSet"]
|
|
31
|
+
|
|
32
|
+
from diffpy.srfit.fitbase.parameter import ParameterAdapter, ParameterProxy
|
|
33
|
+
from diffpy.srfit.fitbase.parameterset import ParameterSet
|
|
34
|
+
from diffpy.srfit.structure.srrealparset import SrRealParSet
|
|
35
|
+
from diffpy.srfit.util.argbinders import bind2nd
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Accessor for xyz of atoms
|
|
39
|
+
class _xyzgetter(object):
|
|
40
|
+
|
|
41
|
+
def __init__(self, i):
|
|
42
|
+
self.i = i
|
|
43
|
+
|
|
44
|
+
def __call__(self, atom):
|
|
45
|
+
return atom.xyz[self.i]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class _xyzsetter(object):
|
|
49
|
+
|
|
50
|
+
def __init__(self, i):
|
|
51
|
+
self.i = i
|
|
52
|
+
|
|
53
|
+
def __call__(self, atom, value):
|
|
54
|
+
atom.xyz[self.i] = value
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class DiffpyAtomParSet(ParameterSet):
|
|
58
|
+
"""A wrapper for diffpy.structure.Atom.
|
|
59
|
+
|
|
60
|
+
This class derives from diffpy.srfit.fitbase.parameterset.ParameterSet. See
|
|
61
|
+
this class for base attributes.
|
|
62
|
+
|
|
63
|
+
Attributes:
|
|
64
|
+
atom -- The diffpy.structure.Atom this is adapting
|
|
65
|
+
element -- The element name (property).
|
|
66
|
+
|
|
67
|
+
Managed Parameters:
|
|
68
|
+
x (y, z) -- Atom position in crystal coordinates (ParameterAdapter)
|
|
69
|
+
occupancy -- Occupancy of the atom on its crystal location
|
|
70
|
+
(ParameterAdapter)
|
|
71
|
+
occ -- Proxy for occupancy (ParameterProxy).
|
|
72
|
+
U11, U22, U33, U12, U21, U23, U32, U13, U31
|
|
73
|
+
-- Anisotropic displacement factor for atom (ParameterAdapter
|
|
74
|
+
or ParameterProxy). Note that the Uij and Uji parameters
|
|
75
|
+
are the same.
|
|
76
|
+
Uiso -- Isotropic ADP (ParameterAdapter).
|
|
77
|
+
B11, B22, B33, B12, B21, B23, B32, B13, B31
|
|
78
|
+
-- Anisotropic displacement factor for atom (ParameterAdapter
|
|
79
|
+
or ParameterProxy). Note that the Bij and Bji parameters
|
|
80
|
+
are the same. (Bij = 8*pi**2*Uij)
|
|
81
|
+
Biso -- Isotropic ADP (ParameterAdapter).
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(self, name, atom):
|
|
85
|
+
"""Initialize.
|
|
86
|
+
|
|
87
|
+
atom -- A diffpy.structure.Atom instance
|
|
88
|
+
"""
|
|
89
|
+
ParameterSet.__init__(self, name)
|
|
90
|
+
self.atom = atom
|
|
91
|
+
a = atom
|
|
92
|
+
# x, y, z, occupancy
|
|
93
|
+
self.addParameter(
|
|
94
|
+
ParameterAdapter("x", a, _xyzgetter(0), _xyzsetter(0))
|
|
95
|
+
)
|
|
96
|
+
self.addParameter(
|
|
97
|
+
ParameterAdapter("y", a, _xyzgetter(1), _xyzsetter(1))
|
|
98
|
+
)
|
|
99
|
+
self.addParameter(
|
|
100
|
+
ParameterAdapter("z", a, _xyzgetter(2), _xyzsetter(2))
|
|
101
|
+
)
|
|
102
|
+
occupancy = ParameterAdapter("occupancy", a, attr="occupancy")
|
|
103
|
+
self.addParameter(occupancy)
|
|
104
|
+
self.addParameter(ParameterProxy("occ", occupancy))
|
|
105
|
+
# U
|
|
106
|
+
self.addParameter(ParameterAdapter("U11", a, attr="U11"))
|
|
107
|
+
self.addParameter(ParameterAdapter("U22", a, attr="U22"))
|
|
108
|
+
self.addParameter(ParameterAdapter("U33", a, attr="U33"))
|
|
109
|
+
U12 = ParameterAdapter("U12", a, attr="U12")
|
|
110
|
+
U21 = ParameterProxy("U21", U12)
|
|
111
|
+
U13 = ParameterAdapter("U13", a, attr="U13")
|
|
112
|
+
U31 = ParameterProxy("U31", U13)
|
|
113
|
+
U23 = ParameterAdapter("U23", a, attr="U23")
|
|
114
|
+
U32 = ParameterProxy("U32", U23)
|
|
115
|
+
self.addParameter(U12)
|
|
116
|
+
self.addParameter(U21)
|
|
117
|
+
self.addParameter(U13)
|
|
118
|
+
self.addParameter(U31)
|
|
119
|
+
self.addParameter(U23)
|
|
120
|
+
self.addParameter(U32)
|
|
121
|
+
self.addParameter(ParameterAdapter("Uiso", a, attr="Uisoequiv"))
|
|
122
|
+
# B
|
|
123
|
+
self.addParameter(ParameterAdapter("B11", a, attr="B11"))
|
|
124
|
+
self.addParameter(ParameterAdapter("B22", a, attr="B22"))
|
|
125
|
+
self.addParameter(ParameterAdapter("B33", a, attr="B33"))
|
|
126
|
+
B12 = ParameterAdapter("B12", a, attr="B12")
|
|
127
|
+
B21 = ParameterProxy("B21", B12)
|
|
128
|
+
B13 = ParameterAdapter("B13", a, attr="B13")
|
|
129
|
+
B31 = ParameterProxy("B31", B13)
|
|
130
|
+
B23 = ParameterAdapter("B23", a, attr="B23")
|
|
131
|
+
B32 = ParameterProxy("B32", B23)
|
|
132
|
+
self.addParameter(B12)
|
|
133
|
+
self.addParameter(B21)
|
|
134
|
+
self.addParameter(B13)
|
|
135
|
+
self.addParameter(B31)
|
|
136
|
+
self.addParameter(B23)
|
|
137
|
+
self.addParameter(B32)
|
|
138
|
+
self.addParameter(ParameterAdapter("Biso", a, attr="Bisoequiv"))
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
def __repr__(self):
|
|
142
|
+
return repr(self.atom)
|
|
143
|
+
|
|
144
|
+
def _getElem(self):
|
|
145
|
+
return self.atom.element
|
|
146
|
+
|
|
147
|
+
def _setElem(self, el):
|
|
148
|
+
self.atom.element = el
|
|
149
|
+
|
|
150
|
+
element = property(_getElem, _setElem, "type of atom")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# End class DiffpyAtomParSet
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _latgetter(par):
|
|
157
|
+
return bind2nd(getattr, par)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _latsetter(par):
|
|
161
|
+
return bind2nd(setattr, par)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class DiffpyLatticeParSet(ParameterSet):
|
|
165
|
+
"""A wrapper for diffpy.structure.Lattice.
|
|
166
|
+
|
|
167
|
+
This class derives from diffpy.srfit.fitbase.parameterset.ParameterSet. See
|
|
168
|
+
this class for base attributes.
|
|
169
|
+
|
|
170
|
+
Attributes
|
|
171
|
+
lattice -- The diffpy.structure.Lattice this is adapting
|
|
172
|
+
name -- Always "lattice"
|
|
173
|
+
angunits -- "deg", the units of angle
|
|
174
|
+
|
|
175
|
+
Managed Parameters:
|
|
176
|
+
a, b, c, alpha, beta, gamma -- The lattice parameters (ParameterAdapter).
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
def __init__(self, lattice):
|
|
180
|
+
"""Initialize.
|
|
181
|
+
|
|
182
|
+
lattice -- A diffpy.structure.Lattice instance
|
|
183
|
+
"""
|
|
184
|
+
ParameterSet.__init__(self, "lattice")
|
|
185
|
+
self.angunits = "deg"
|
|
186
|
+
self.lattice = lattice
|
|
187
|
+
lat = lattice
|
|
188
|
+
self.addParameter(
|
|
189
|
+
ParameterAdapter("a", lat, _latgetter("a"), _latsetter("a"))
|
|
190
|
+
)
|
|
191
|
+
self.addParameter(
|
|
192
|
+
ParameterAdapter("b", lat, _latgetter("b"), _latsetter("b"))
|
|
193
|
+
)
|
|
194
|
+
self.addParameter(
|
|
195
|
+
ParameterAdapter("c", lat, _latgetter("c"), _latsetter("c"))
|
|
196
|
+
)
|
|
197
|
+
self.addParameter(
|
|
198
|
+
ParameterAdapter(
|
|
199
|
+
"alpha", lat, _latgetter("alpha"), _latsetter("alpha")
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
self.addParameter(
|
|
203
|
+
ParameterAdapter(
|
|
204
|
+
"beta", lat, _latgetter("beta"), _latsetter("beta")
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
self.addParameter(
|
|
208
|
+
ParameterAdapter(
|
|
209
|
+
"gamma", lat, _latgetter("gamma"), _latsetter("gamma")
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
return
|
|
213
|
+
|
|
214
|
+
def __repr__(self):
|
|
215
|
+
return repr(self.lattice)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# End class DiffpyLatticeParSet
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class DiffpyStructureParSet(SrRealParSet):
|
|
222
|
+
"""A wrapper for diffpy.structure.Structure.
|
|
223
|
+
|
|
224
|
+
This class derives from diffpy.srfit.fitbase.parameterset.ParameterSet. See
|
|
225
|
+
this class for base attributes.
|
|
226
|
+
|
|
227
|
+
Attributes:
|
|
228
|
+
atoms -- The list of DiffpyAtomParSets, provided for convenience.
|
|
229
|
+
stru -- The diffpy.structure.Structure this is adapting
|
|
230
|
+
|
|
231
|
+
Managed ParameterSets:
|
|
232
|
+
lattice -- The managed DiffpyLatticeParSet
|
|
233
|
+
<el><idx> -- A managed DiffpyAtomParSets. <el> is the atomic element and
|
|
234
|
+
<idx> is the index of that element in the structure,
|
|
235
|
+
starting from zero. Thus, for nickel in P1 symmetry, the
|
|
236
|
+
managed DiffpyAtomParSets will be named "Ni0", "Ni1", "Ni2"
|
|
237
|
+
and "Ni3".
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
def __init__(self, name, stru):
|
|
241
|
+
"""Initialize.
|
|
242
|
+
|
|
243
|
+
name -- A name for the structure
|
|
244
|
+
stru -- A diffpy.structure.Structure instance
|
|
245
|
+
"""
|
|
246
|
+
SrRealParSet.__init__(self, name)
|
|
247
|
+
self.stru = stru
|
|
248
|
+
self.addParameterSet(DiffpyLatticeParSet(stru.lattice))
|
|
249
|
+
self.atoms = []
|
|
250
|
+
|
|
251
|
+
cdict = {}
|
|
252
|
+
for a in stru:
|
|
253
|
+
el = a.element.title()
|
|
254
|
+
# Try to sanitize the name.
|
|
255
|
+
el = el.replace("+", "p")
|
|
256
|
+
el = el.replace("-", "m")
|
|
257
|
+
i = cdict.get(el, 0)
|
|
258
|
+
aname = "%s%i" % (el, i)
|
|
259
|
+
cdict[el] = i + 1
|
|
260
|
+
atom = DiffpyAtomParSet(aname, a)
|
|
261
|
+
self.addParameterSet(atom)
|
|
262
|
+
self.atoms.append(atom)
|
|
263
|
+
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
def __repr__(self):
|
|
267
|
+
return repr(self.stru)
|
|
268
|
+
|
|
269
|
+
def getLattice(self):
|
|
270
|
+
"""Get the ParameterSet containing the lattice Parameters."""
|
|
271
|
+
return self.lattice
|
|
272
|
+
|
|
273
|
+
@classmethod
|
|
274
|
+
def canAdapt(self, stru):
|
|
275
|
+
"""Return whether the structure can be adapted by this class."""
|
|
276
|
+
from diffpy.structure import Structure
|
|
277
|
+
|
|
278
|
+
return isinstance(stru, Structure)
|
|
279
|
+
|
|
280
|
+
def getScatterers(self):
|
|
281
|
+
"""Get a list of ParameterSets that represents the scatterers.
|
|
282
|
+
|
|
283
|
+
The site positions must be accessible from the list entries via
|
|
284
|
+
the names "x", "y", and "z". The ADPs must be accessible as
|
|
285
|
+
well, but the name and nature of the ADPs (U-factors, B-factors,
|
|
286
|
+
isotropic, anisotropic) depends on the adapted structure.
|
|
287
|
+
"""
|
|
288
|
+
return self.atoms
|
|
289
|
+
|
|
290
|
+
def _getSrRealStructure(self):
|
|
291
|
+
"""Get the structure object for use with SrReal calculators.
|
|
292
|
+
|
|
293
|
+
If this is periodic, then return the structure, otherwise, pass
|
|
294
|
+
it inside of a nosymmetry wrapper. This takes the extra step of
|
|
295
|
+
wrapping the structure in a nometa wrapper.
|
|
296
|
+
"""
|
|
297
|
+
from diffpy.srreal.structureadapter import nometa
|
|
298
|
+
|
|
299
|
+
stru = SrRealParSet._getSrRealStructure(self)
|
|
300
|
+
return nometa(stru)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# End class DiffpyStructureParSet
|