diffpy.labpdfproc 0.2.0__py3-none-any.whl → 0.3.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 +6 -11
- diffpy/labpdfproc/__init__.py +8 -4
- diffpy/labpdfproc/data/coefficient_list.csv +7 -5
- diffpy/labpdfproc/functions.py +179 -176
- diffpy/labpdfproc/labpdfprocapp.py +272 -124
- diffpy/labpdfproc/tools.py +404 -106
- diffpy/labpdfproc/version.py +11 -7
- {diffpy.labpdfproc-0.2.0.dist-info → diffpy_labpdfproc-0.3.0.dist-info}/METADATA +40 -41
- diffpy_labpdfproc-0.3.0.dist-info/RECORD +15 -0
- {diffpy.labpdfproc-0.2.0.dist-info → diffpy_labpdfproc-0.3.0.dist-info}/WHEEL +1 -1
- {diffpy.labpdfproc-0.2.0.dist-info → diffpy_labpdfproc-0.3.0.dist-info/licenses}/AUTHORS.rst +1 -1
- {diffpy.labpdfproc-0.2.0.dist-info → diffpy_labpdfproc-0.3.0.dist-info/licenses}/LICENSE.rst +4 -2
- diffpy/labpdfproc/mud_calculator.py +0 -100
- diffpy.labpdfproc-0.2.0.dist-info/RECORD +0 -16
- {diffpy.labpdfproc-0.2.0.dist-info → diffpy_labpdfproc-0.3.0.dist-info}/entry_points.txt +0 -0
- {diffpy.labpdfproc-0.2.0.dist-info → diffpy_labpdfproc-0.3.0.dist-info}/top_level.txt +0 -0
diffpy/__init__.py
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
##############################################################################
|
|
3
3
|
#
|
|
4
|
-
# (c) 2024 The Trustees of Columbia University in the City of New York.
|
|
4
|
+
# (c) 2024-2025, The Trustees of Columbia University in the City of New York.
|
|
5
5
|
# All rights reserved.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
7
|
+
# (c) 2026-present, diffpy.labpdfproc developers and contributors.
|
|
8
|
+
# All rights reserved.
|
|
9
|
+
#
|
|
10
|
+
# File coded by: Yucong Chen, Till Schertenleib, Caden Myers,
|
|
11
|
+
# Billinge Group members.
|
|
8
12
|
#
|
|
9
13
|
# See GitHub contributions for a more detailed list of contributors.
|
|
10
14
|
# https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors
|
|
@@ -12,12 +16,3 @@
|
|
|
12
16
|
# See LICENSE.rst for license information.
|
|
13
17
|
#
|
|
14
18
|
##############################################################################
|
|
15
|
-
|
|
16
|
-
"""Blank namespace package for module diffpy."""
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
from pkgutil import extend_path
|
|
20
|
-
|
|
21
|
-
__path__ = extend_path(__path__, __name__)
|
|
22
|
-
|
|
23
|
-
# End of file
|
diffpy/labpdfproc/__init__.py
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
##############################################################################
|
|
3
3
|
#
|
|
4
|
-
# (c) 2024 The Trustees of Columbia University in the City of New York.
|
|
4
|
+
# (c) 2024-2025, The Trustees of Columbia University in the City of New York.
|
|
5
5
|
# All rights reserved.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
7
|
+
# (c) 2026-present, diffpy.labpdfproc developers and contributors.
|
|
8
|
+
# All rights reserved.
|
|
9
|
+
#
|
|
10
|
+
# File coded by: Yucong Chen, Till Schertenleib, Caden Myers,
|
|
11
|
+
# Billinge Group members.
|
|
8
12
|
#
|
|
9
13
|
# See GitHub contributions for a more detailed list of contributors.
|
|
10
14
|
# https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors
|
|
@@ -12,8 +16,8 @@
|
|
|
12
16
|
# See LICENSE.rst for license information.
|
|
13
17
|
#
|
|
14
18
|
##############################################################################
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
"""Tools for processing x-ray powder diffraction data from laboratory
|
|
20
|
+
sources."""
|
|
17
21
|
|
|
18
22
|
# package version
|
|
19
23
|
from diffpy.labpdfproc.version import __version__
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
-
|
|
5
|
-
|
|
1
|
+
-20619.128648244743,2.4364997877410417e-06,26505.585137008606,-337279.3213902739,-1056051.2792994028,-1815539.1160187968,-2372171.980894541,-2642993.4538858426
|
|
2
|
+
56203.20048346139,-6.774323967911372e-06,-51225.01460831775,1005023.6254387972,3051609.2101441943,5201294.212075991,6773264.754466731,7538833.212217793
|
|
3
|
+
-63802.106117440504,7.845612740225726e-06,33089.880661840034,-1242527.9972772636,-3668761.3028854067,-6202335.40819644,-8050708.344579743,-8951452.327576341
|
|
4
|
+
38603.18842240787,-4.844608638276231e-06,-4028.752491140328,816333.2796219026,2349291.871863084,3940828.5623758254,5099123.959731602,5663734.051678175
|
|
5
|
+
-13126.533425725584,1.6822282153058894e-06,-4395.4012467221355,-300757.7094990732,-845218.597424347,-1407243.8630987857,-1815244.4369415767,-2014105.8565458413
|
|
6
|
+
2378.155272695758,0.9999996885549859,1912.0755691304305,58944.34388638723,162014.93660541167,267802.2088119374,344395.5526651557,381710.2334140182
|
|
7
|
+
-178.70587585316136,2.4018054840276848e-08,-234.76082555771987,-4803.1698085743365,-12928.521798999534,-21220.235622246797,-27207.092578054173,-30121.285267280207
|
diffpy/labpdfproc/functions.py
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
import math
|
|
2
|
-
|
|
2
|
+
import warnings
|
|
3
|
+
from importlib.resources import files
|
|
3
4
|
|
|
4
5
|
import numpy as np
|
|
5
6
|
import pandas as pd
|
|
6
7
|
from scipy.interpolate import interp1d
|
|
7
8
|
|
|
8
|
-
from diffpy.utils.
|
|
9
|
+
from diffpy.utils.diffraction_objects import XQUANTITIES, DiffractionObject
|
|
9
10
|
|
|
10
11
|
RADIUS_MM = 1
|
|
11
12
|
N_POINTS_ON_DIAMETER = 300
|
|
12
13
|
TTH_GRID = np.arange(1, 180.1, 0.1)
|
|
14
|
+
# Round down the last element if it's slightly above 180.00
|
|
15
|
+
# due to floating point precision
|
|
16
|
+
TTH_GRID[-1] = 180.00
|
|
13
17
|
CVE_METHODS = ["brute_force", "polynomial_interpolation"]
|
|
14
18
|
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
MULS = np.loadtxt(
|
|
19
|
-
COEFFICIENT_LIST = np.array(
|
|
20
|
-
|
|
19
|
+
# Pre-computed datasets for polynomial interpolation (fast calculation)
|
|
20
|
+
data_dir = files("diffpy.labpdfproc") / "data"
|
|
21
|
+
MUD_LIST = np.array([0.5, 1, 2, 3, 4, 5, 6, 7])
|
|
22
|
+
MULS = np.loadtxt(data_dir / "inverse_cve.xy")
|
|
23
|
+
COEFFICIENT_LIST = np.array(
|
|
24
|
+
pd.read_csv(data_dir / "coefficient_list.csv", header=None)
|
|
25
|
+
)
|
|
26
|
+
INTERPOLATION_FUNCTIONS = [
|
|
27
|
+
interp1d(MUD_LIST, coeffs, kind="quadratic") for coeffs in COEFFICIENT_LIST
|
|
28
|
+
]
|
|
21
29
|
|
|
22
30
|
|
|
23
31
|
class Gridded_circle:
|
|
24
|
-
def __init__(
|
|
32
|
+
def __init__(
|
|
33
|
+
self, radius=1, n_points_on_diameter=N_POINTS_ON_DIAMETER, mu=None
|
|
34
|
+
):
|
|
25
35
|
self.radius = radius
|
|
26
36
|
self.npoints = n_points_on_diameter
|
|
27
37
|
self.mu = mu
|
|
@@ -30,103 +40,63 @@ class Gridded_circle:
|
|
|
30
40
|
self._get_grid_points()
|
|
31
41
|
|
|
32
42
|
def _get_grid_points(self):
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
"""
|
|
43
|
+
"""Given a radius and a grid size, return a grid of points to
|
|
44
|
+
uniformly sample that circle."""
|
|
36
45
|
xs = np.linspace(-self.radius, self.radius, self.npoints)
|
|
37
46
|
ys = np.linspace(-self.radius, self.radius, self.npoints)
|
|
38
|
-
self.grid = {
|
|
47
|
+
self.grid = {
|
|
48
|
+
(x, y) for x in xs for y in ys if x**2 + y**2 <= self.radius**2
|
|
49
|
+
}
|
|
39
50
|
self.total_points_in_grid = len(self.grid)
|
|
40
51
|
|
|
41
|
-
def set_distances_at_angle(self, angle):
|
|
42
|
-
"""
|
|
43
|
-
given an angle, set the distances from the grid points to the entry and exit coordinates
|
|
44
|
-
|
|
45
|
-
Parameters
|
|
46
|
-
----------
|
|
47
|
-
angle float
|
|
48
|
-
the angle in degrees
|
|
49
|
-
|
|
50
|
-
Returns
|
|
51
|
-
-------
|
|
52
|
-
the list of distances containing total distance, primary distance and secondary distance
|
|
53
|
-
|
|
54
|
-
"""
|
|
55
|
-
self.primary_distances, self.secondary_distances, self.distances = [], [], []
|
|
56
|
-
for coord in self.grid:
|
|
57
|
-
distance, primary, secondary = self.get_path_length(coord, angle)
|
|
58
|
-
self.distances.append(distance)
|
|
59
|
-
self.primary_distances.append(primary)
|
|
60
|
-
self.secondary_distances.append(secondary)
|
|
61
|
-
|
|
62
|
-
def set_muls_at_angle(self, angle):
|
|
63
|
-
"""
|
|
64
|
-
compute muls = exp(-mu*distance) for a given angle
|
|
65
|
-
|
|
66
|
-
Parameters
|
|
67
|
-
----------
|
|
68
|
-
angle float
|
|
69
|
-
the angle in degrees
|
|
70
|
-
|
|
71
|
-
Returns
|
|
72
|
-
-------
|
|
73
|
-
an array of floats containing the muls corresponding to each angle
|
|
74
|
-
|
|
75
|
-
"""
|
|
76
|
-
mu = self.mu
|
|
77
|
-
self.muls = []
|
|
78
|
-
if len(self.distances) == 0:
|
|
79
|
-
self.set_distances_at_angle(angle)
|
|
80
|
-
for distance in self.distances:
|
|
81
|
-
self.muls.append(np.exp(-mu * distance))
|
|
82
|
-
|
|
83
52
|
def _get_entry_exit_coordinates(self, coordinate, angle):
|
|
84
|
-
"""
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Parameters
|
|
88
|
-
----------
|
|
89
|
-
grid_point tuple of floats
|
|
90
|
-
the coordinates of the grid point
|
|
91
|
-
|
|
92
|
-
angle float
|
|
93
|
-
the angle in degrees
|
|
94
|
-
|
|
95
|
-
radius float
|
|
96
|
-
the radius of the circle in units of inverse mu
|
|
53
|
+
"""Get the coordinates where the beam enters and leaves the
|
|
54
|
+
circle for a given angle and grid point.
|
|
97
55
|
|
|
98
|
-
|
|
99
|
-
For the entry coordinate,
|
|
56
|
+
It is calculated in the following way:
|
|
57
|
+
For the entry coordinate,
|
|
58
|
+
the y-component will be the y of the grid point
|
|
59
|
+
and the x-component will be minus
|
|
100
60
|
the value of x on the circle at the height of this y.
|
|
101
61
|
|
|
102
62
|
For the exit coordinate:
|
|
103
|
-
Find the line y = ax + b that passes through grid_point at angle
|
|
104
|
-
The circle is x^2 + y^2 = r^2
|
|
63
|
+
Find the line y = ax + b that passes through grid_point at angle.
|
|
64
|
+
The circle is x^2 + y^2 = r^2.
|
|
105
65
|
The exit point is where these are simultaneous equations
|
|
106
66
|
x^2 + y^2 = r^2 & y = ax + b
|
|
107
67
|
x^2 + (ax+b)^2 = r^2
|
|
108
68
|
=> x^2 + a^2x^2 + 2abx + b^2 - r^2 = 0
|
|
109
69
|
=> (1+a^2) x^2 + 2abx + (b^2 - r^2) = 0
|
|
110
|
-
to find x_exit we find the roots of these equations
|
|
111
|
-
|
|
70
|
+
to find x_exit we find the roots of these equations
|
|
71
|
+
and pick the root that is above y-grid
|
|
72
|
+
then we get y_exit from y_exit = a*x_exit + b.
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
coordinate : tuple of floats
|
|
77
|
+
The coordinates of the grid point.
|
|
78
|
+
angle : float
|
|
79
|
+
The angle in degrees.
|
|
112
80
|
|
|
113
81
|
Returns
|
|
114
82
|
-------
|
|
115
|
-
(
|
|
116
|
-
|
|
117
|
-
|
|
83
|
+
(entry_point, exit_point): tuple of floats
|
|
84
|
+
(1) The coordinate of the entry point and
|
|
85
|
+
(2) of the exit point of a beam entering horizontally
|
|
86
|
+
impinging on a coordinate point that lies in the circle
|
|
87
|
+
and then exiting at some angle, angle.
|
|
118
88
|
"""
|
|
119
89
|
epsilon = 1e-7 # precision close to 90
|
|
120
90
|
angle = math.radians(angle)
|
|
121
91
|
xgrid = coordinate[0]
|
|
122
92
|
ygrid = coordinate[1]
|
|
123
|
-
|
|
124
93
|
entry_point = (-math.sqrt(self.radius**2 - ygrid**2), ygrid)
|
|
125
|
-
|
|
126
94
|
if not math.isclose(angle, math.pi / 2, abs_tol=epsilon):
|
|
127
95
|
b = ygrid - xgrid * math.tan(angle)
|
|
128
96
|
a = math.tan(angle)
|
|
129
|
-
xexit_root1, xexit_root2 = np.roots(
|
|
97
|
+
xexit_root1, xexit_root2 = np.roots(
|
|
98
|
+
(1 + a**2, 2 * a * b, b**2 - self.radius**2)
|
|
99
|
+
)
|
|
130
100
|
yexit_root1 = a * xexit_root1 + b
|
|
131
101
|
yexit_root2 = a * xexit_root2 + b
|
|
132
102
|
if yexit_root2 >= yexit_root1: # We pick the point above
|
|
@@ -135,34 +105,28 @@ class Gridded_circle:
|
|
|
135
105
|
exit_point = (xexit_root1, yexit_root1)
|
|
136
106
|
else:
|
|
137
107
|
exit_point = (xgrid, math.sqrt(self.radius**2 - xgrid**2))
|
|
138
|
-
|
|
139
108
|
return entry_point, exit_point
|
|
140
109
|
|
|
141
|
-
def
|
|
142
|
-
"""
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
This is the pathlength of a horizontal line entering the circle at the
|
|
146
|
-
same height to the grid point then exiting at angle angle
|
|
110
|
+
def _get_path_length(self, grid_point, angle):
|
|
111
|
+
"""Return the path length of a horizontal line entering the
|
|
112
|
+
circle at the same height to the grid point then exiting at
|
|
113
|
+
angle.
|
|
147
114
|
|
|
148
115
|
Parameters
|
|
149
116
|
----------
|
|
150
|
-
grid_point double of floats
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
the angle of the output beam
|
|
155
|
-
|
|
156
|
-
radius
|
|
157
|
-
the radius of the circle
|
|
117
|
+
grid_point : double of floats
|
|
118
|
+
The coordinate inside the circle.
|
|
119
|
+
angle : float
|
|
120
|
+
The angle of the output beam in degrees.
|
|
158
121
|
|
|
159
122
|
Returns
|
|
160
123
|
-------
|
|
161
|
-
|
|
162
|
-
|
|
124
|
+
(total distance, primary distance, secondary distance): tuple of floats
|
|
125
|
+
The tuple containing three floats,
|
|
126
|
+
which are the total distance, entry distance and exit distance.
|
|
163
127
|
"""
|
|
164
|
-
|
|
165
|
-
#
|
|
128
|
+
# move angle a tad above zero if it is zero
|
|
129
|
+
# to avoid it having the wrong sign due to some rounding error
|
|
166
130
|
angle_delta = 0.000001
|
|
167
131
|
if angle == float(0):
|
|
168
132
|
angle = angle + angle_delta
|
|
@@ -172,15 +136,51 @@ class Gridded_circle:
|
|
|
172
136
|
total_distance = primary_distance + secondary_distance
|
|
173
137
|
return total_distance, primary_distance, secondary_distance
|
|
174
138
|
|
|
139
|
+
def set_distances_at_angle(self, angle):
|
|
140
|
+
"""Given an angle, set the distances from the grid points to the
|
|
141
|
+
entry and exit coordinates.
|
|
175
142
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
143
|
+
Parameters
|
|
144
|
+
----------
|
|
145
|
+
angle : float
|
|
146
|
+
The angle of the output beam in degrees.
|
|
147
|
+
"""
|
|
148
|
+
self.primary_distances = []
|
|
149
|
+
self.secondary_distances = []
|
|
150
|
+
self.distances = []
|
|
151
|
+
for coord in self.grid:
|
|
152
|
+
distance, primary, secondary = self._get_path_length(coord, angle)
|
|
153
|
+
self.distances.append(distance)
|
|
154
|
+
self.primary_distances.append(primary)
|
|
155
|
+
self.secondary_distances.append(secondary)
|
|
156
|
+
|
|
157
|
+
def set_muls_at_angle(self, angle):
|
|
158
|
+
"""Compute muls = exp(-mu*distance) for a given angle.
|
|
159
|
+
|
|
160
|
+
Parameters
|
|
161
|
+
----------
|
|
162
|
+
angle : float
|
|
163
|
+
The angle of the output beam in degrees.
|
|
164
|
+
"""
|
|
165
|
+
mu = self.mu
|
|
166
|
+
self.muls = []
|
|
167
|
+
if len(self.distances) == 0:
|
|
168
|
+
self.set_distances_at_angle(angle)
|
|
169
|
+
for distance in self.distances:
|
|
170
|
+
self.muls.append(np.exp(-mu * distance))
|
|
181
171
|
|
|
172
|
+
|
|
173
|
+
def _cve_brute_force(input_pattern, mud):
|
|
174
|
+
"""Compute cve for the given mud on a global grid using the brute-
|
|
175
|
+
force method.
|
|
176
|
+
|
|
177
|
+
Assume mu=mud/2, given that the same mu*D yields the same cve and
|
|
178
|
+
D/2=1.
|
|
179
|
+
"""
|
|
182
180
|
mu_sample_invmm = mud / 2
|
|
183
|
-
abs_correction = Gridded_circle(
|
|
181
|
+
abs_correction = Gridded_circle(
|
|
182
|
+
n_points_on_diameter=N_POINTS_ON_DIAMETER, mu=mu_sample_invmm
|
|
183
|
+
)
|
|
184
184
|
distances, muls = [], []
|
|
185
185
|
for angle in TTH_GRID:
|
|
186
186
|
abs_correction.set_distances_at_angle(angle)
|
|
@@ -190,115 +190,118 @@ def _cve_brute_force(diffraction_data, mud):
|
|
|
190
190
|
distances = np.array(distances) / abs_correction.total_points_in_grid
|
|
191
191
|
muls = np.array(muls) / abs_correction.total_points_in_grid
|
|
192
192
|
cve = 1 / muls
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
"tth",
|
|
199
|
-
metadata=diffraction_data.metadata,
|
|
200
|
-
name=f"absorption correction, cve, for {diffraction_data.name}",
|
|
201
|
-
wavelength=diffraction_data.wavelength,
|
|
193
|
+
cve_do = DiffractionObject(
|
|
194
|
+
xarray=TTH_GRID,
|
|
195
|
+
yarray=cve,
|
|
196
|
+
xtype="tth",
|
|
197
|
+
wavelength=input_pattern.wavelength,
|
|
202
198
|
scat_quantity="cve",
|
|
199
|
+
name=f"absorption correction, cve, for {input_pattern.name}",
|
|
200
|
+
metadata=input_pattern.metadata,
|
|
203
201
|
)
|
|
204
202
|
return cve_do
|
|
205
203
|
|
|
206
204
|
|
|
207
|
-
def _cve_polynomial_interpolation(
|
|
208
|
-
"""
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
f"
|
|
215
|
-
f"
|
|
205
|
+
def _cve_polynomial_interpolation(input_pattern, mud):
|
|
206
|
+
"""Compute cve using polynomial interpolation method, default to
|
|
207
|
+
brute- force computation if mu*D is out of the range (0.5 to 7)."""
|
|
208
|
+
if mud > 7 or mud < 0.5:
|
|
209
|
+
warnings.warn(
|
|
210
|
+
f"Input mu*D = {mud} is out of the acceptable range "
|
|
211
|
+
f"({np.min(MUD_LIST)} to {np.max(MUD_LIST)}) "
|
|
212
|
+
f"for polynomial interpolation. "
|
|
213
|
+
f"Proceeding with brute-force computation. "
|
|
216
214
|
)
|
|
217
|
-
|
|
218
|
-
interpolation_function(mud) for interpolation_function in INTERPOLATION_FUNCTIONS
|
|
219
|
-
]
|
|
220
|
-
muls = np.array(coeff_a * MULS**4 + coeff_b * MULS**3 + coeff_c * MULS**2 + coeff_d * MULS + coeff_e)
|
|
221
|
-
cve = 1 / muls
|
|
215
|
+
return _cve_brute_force(input_pattern, mud)
|
|
222
216
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
wavelength=
|
|
217
|
+
coeffs = np.array([f(mud) for f in INTERPOLATION_FUNCTIONS])
|
|
218
|
+
muls = np.polyval(coeffs, MULS)
|
|
219
|
+
cve = 1 / muls
|
|
220
|
+
cve_do = DiffractionObject(
|
|
221
|
+
xarray=TTH_GRID,
|
|
222
|
+
yarray=cve,
|
|
223
|
+
xtype="tth",
|
|
224
|
+
wavelength=input_pattern.wavelength,
|
|
231
225
|
scat_quantity="cve",
|
|
226
|
+
name=f"absorption correction, cve, for {input_pattern.name}",
|
|
227
|
+
metadata=input_pattern.metadata,
|
|
232
228
|
)
|
|
233
229
|
return cve_do
|
|
234
230
|
|
|
235
231
|
|
|
236
232
|
def _cve_method(method):
|
|
237
|
-
"""
|
|
238
|
-
retrieve the cve computation function for the given method
|
|
239
|
-
"""
|
|
233
|
+
"""Retrieve the cve computation function for the given method."""
|
|
240
234
|
methods = {
|
|
241
235
|
"brute_force": _cve_brute_force,
|
|
242
236
|
"polynomial_interpolation": _cve_polynomial_interpolation,
|
|
243
237
|
}
|
|
244
238
|
if method not in CVE_METHODS:
|
|
245
|
-
raise ValueError(
|
|
239
|
+
raise ValueError(
|
|
240
|
+
f"Unknown method: {method}. "
|
|
241
|
+
f"Allowed methods are {*CVE_METHODS, }."
|
|
242
|
+
)
|
|
246
243
|
return methods[method]
|
|
247
244
|
|
|
248
245
|
|
|
249
|
-
def compute_cve(
|
|
250
|
-
|
|
251
|
-
|
|
246
|
+
def compute_cve(
|
|
247
|
+
input_pattern, mud, method="polynomial_interpolation", xtype="tth"
|
|
248
|
+
):
|
|
249
|
+
f"""Compute and interpolate the cylindrical volume effect (cve)
|
|
250
|
+
for the given input diffraction data and mu*D
|
|
251
|
+
using the selected method.
|
|
252
|
+
|
|
252
253
|
Parameters
|
|
253
254
|
----------
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
mud float
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
255
|
+
input_pattern : DiffractionObject
|
|
256
|
+
The input diffraction object to which the cve will be applied.
|
|
257
|
+
mud : float
|
|
258
|
+
The mu*D value of the diffraction object,
|
|
259
|
+
where D is the diameter of the circle.
|
|
260
|
+
xtype : str
|
|
261
|
+
The quantity on the independent variable axis,
|
|
262
|
+
allowed values are {*XQUANTITIES, }.
|
|
263
|
+
method : str
|
|
264
|
+
The method used to calculate cve, must be one of {*CVE_METHODS, }.
|
|
260
265
|
|
|
261
266
|
Returns
|
|
262
267
|
-------
|
|
263
|
-
|
|
268
|
+
cve_do: DiffractionObject
|
|
269
|
+
The diffraction object that contains the cve to be applied.
|
|
264
270
|
"""
|
|
265
|
-
|
|
266
271
|
cve_function = _cve_method(method)
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
newcve = np.interp(orig_grid,
|
|
272
|
-
cve_do =
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
metadata=diffraction_data.metadata,
|
|
278
|
-
name=f"absorption correction, cve, for {diffraction_data.name}",
|
|
279
|
-
wavelength=diffraction_data.wavelength,
|
|
272
|
+
cve_do_on_global_grid = cve_function(input_pattern, mud)
|
|
273
|
+
orig_grid = input_pattern.on_xtype(xtype)[0]
|
|
274
|
+
global_xtype = cve_do_on_global_grid.on_xtype(xtype)[0]
|
|
275
|
+
cve_on_global_xtype = cve_do_on_global_grid.on_xtype(xtype)[1]
|
|
276
|
+
newcve = np.interp(orig_grid, global_xtype, cve_on_global_xtype)
|
|
277
|
+
cve_do = DiffractionObject(
|
|
278
|
+
xarray=orig_grid,
|
|
279
|
+
yarray=newcve,
|
|
280
|
+
xtype=xtype,
|
|
281
|
+
wavelength=input_pattern.wavelength,
|
|
280
282
|
scat_quantity="cve",
|
|
283
|
+
name=f"absorption correction, cve, for {input_pattern.name}",
|
|
284
|
+
metadata=input_pattern.metadata,
|
|
281
285
|
)
|
|
282
|
-
|
|
283
286
|
return cve_do
|
|
284
287
|
|
|
285
288
|
|
|
286
|
-
def apply_corr(
|
|
287
|
-
"""
|
|
288
|
-
|
|
289
|
+
def apply_corr(input_pattern, absorption_correction):
|
|
290
|
+
"""Apply absorption correction to the given diffraction object with
|
|
291
|
+
the correction diffraction object.
|
|
289
292
|
|
|
290
293
|
Parameters
|
|
291
294
|
----------
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
absorption_correction
|
|
295
|
-
|
|
295
|
+
input_pattern : DiffractionObject
|
|
296
|
+
The input diffraction object to which the cve will be applied.
|
|
297
|
+
absorption_correction : DiffractionObject
|
|
298
|
+
The diffraction object that contains the cve to be applied.
|
|
296
299
|
|
|
297
300
|
Returns
|
|
298
301
|
-------
|
|
299
|
-
|
|
300
|
-
|
|
302
|
+
corrected_pattern: DiffractionObject
|
|
303
|
+
The corrected diffraction object
|
|
304
|
+
with the correction applied through multiplication.
|
|
301
305
|
"""
|
|
302
|
-
|
|
303
|
-
corrected_pattern = diffraction_pattern * absorption_correction
|
|
306
|
+
corrected_pattern = input_pattern * absorption_correction
|
|
304
307
|
return corrected_pattern
|