diffpy.labpdfproc 0.1.1__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 +23 -0
- diffpy/labpdfproc/__init__.py +24 -0
- diffpy/labpdfproc/functions.py +245 -0
- diffpy/labpdfproc/labpdfprocapp.py +147 -0
- diffpy/labpdfproc/tools.py +262 -0
- diffpy/labpdfproc/version.py +26 -0
- diffpy.labpdfproc-0.1.1.dist-info/AUTHORS.rst +10 -0
- diffpy.labpdfproc-0.1.1.dist-info/LICENSE +29 -0
- diffpy.labpdfproc-0.1.1.dist-info/LICENSE.rst +30 -0
- diffpy.labpdfproc-0.1.1.dist-info/METADATA +150 -0
- diffpy.labpdfproc-0.1.1.dist-info/RECORD +13 -0
- diffpy.labpdfproc-0.1.1.dist-info/WHEEL +5 -0
- diffpy.labpdfproc-0.1.1.dist-info/top_level.txt +1 -0
diffpy/__init__.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
##############################################################################
|
|
3
|
+
#
|
|
4
|
+
# (c) 2024 The Trustees of Columbia University in the City of New York.
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# File coded by: Billinge Group members and community contributors.
|
|
8
|
+
#
|
|
9
|
+
# See GitHub contributions for a more detailed list of contributors.
|
|
10
|
+
# https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors
|
|
11
|
+
#
|
|
12
|
+
# See LICENSE.rst for license information.
|
|
13
|
+
#
|
|
14
|
+
##############################################################################
|
|
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
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
##############################################################################
|
|
3
|
+
#
|
|
4
|
+
# (c) 2024 The Trustees of Columbia University in the City of New York.
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# File coded by: Billinge Group members and community contributors.
|
|
8
|
+
#
|
|
9
|
+
# See GitHub contributions for a more detailed list of contributors.
|
|
10
|
+
# https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors
|
|
11
|
+
#
|
|
12
|
+
# See LICENSE.rst for license information.
|
|
13
|
+
#
|
|
14
|
+
##############################################################################
|
|
15
|
+
|
|
16
|
+
"""Tools for processing x-ray powder diffraction data from laboratory sources"""
|
|
17
|
+
|
|
18
|
+
# package version
|
|
19
|
+
from diffpy.labpdfproc.version import __version__
|
|
20
|
+
|
|
21
|
+
# silence the pyflakes syntax checker
|
|
22
|
+
assert __version__ or True
|
|
23
|
+
|
|
24
|
+
# End of file
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from diffpy.utils.scattering_objects.diffraction_objects import Diffraction_object
|
|
6
|
+
|
|
7
|
+
RADIUS_MM = 1
|
|
8
|
+
N_POINTS_ON_DIAMETER = 300
|
|
9
|
+
TTH_GRID = np.arange(1, 141, 1)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Gridded_circle:
|
|
13
|
+
def __init__(self, radius=1, n_points_on_diameter=N_POINTS_ON_DIAMETER, mu=None):
|
|
14
|
+
self.radius = radius
|
|
15
|
+
self.npoints = n_points_on_diameter
|
|
16
|
+
self.mu = mu
|
|
17
|
+
self.distances = []
|
|
18
|
+
self.muls = []
|
|
19
|
+
self._get_grid_points()
|
|
20
|
+
|
|
21
|
+
def _get_grid_points(self):
|
|
22
|
+
"""
|
|
23
|
+
given a radius and a grid size, return a grid of points to uniformly sample that circle
|
|
24
|
+
"""
|
|
25
|
+
xs = np.linspace(-self.radius, self.radius, self.npoints)
|
|
26
|
+
ys = np.linspace(-self.radius, self.radius, self.npoints)
|
|
27
|
+
self.grid = {(x, y) for x in xs for y in ys if x**2 + y**2 <= self.radius**2}
|
|
28
|
+
self.total_points_in_grid = len(self.grid)
|
|
29
|
+
|
|
30
|
+
# def get_coordinate_index(self, coordinate): # I think we probably dont need this function?
|
|
31
|
+
# count = 0
|
|
32
|
+
# for i, target in enumerate(self.grid):
|
|
33
|
+
# if coordinate == target:
|
|
34
|
+
# return i
|
|
35
|
+
# else:
|
|
36
|
+
# count += 1
|
|
37
|
+
# if count >= len(self.grid):
|
|
38
|
+
# raise IndexError(f"WARNING: no coordinate {coordinate} found in coordinates list")
|
|
39
|
+
|
|
40
|
+
def set_distances_at_angle(self, angle):
|
|
41
|
+
"""
|
|
42
|
+
given an angle, set the distances from the grid points to the entry and exit coordinates
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
angle float
|
|
47
|
+
the angle in degrees
|
|
48
|
+
|
|
49
|
+
Returns
|
|
50
|
+
-------
|
|
51
|
+
the list of distances containing total distance, primary distance and secondary distance
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
self.primary_distances, self.secondary_distances, self.distances = [], [], []
|
|
55
|
+
for coord in self.grid:
|
|
56
|
+
distance, primary, secondary = self.get_path_length(coord, angle)
|
|
57
|
+
self.distances.append(distance)
|
|
58
|
+
self.primary_distances.append(primary)
|
|
59
|
+
self.secondary_distances.append(secondary)
|
|
60
|
+
|
|
61
|
+
def set_muls_at_angle(self, angle):
|
|
62
|
+
"""
|
|
63
|
+
compute muls = exp(-mu*distance) for a given angle
|
|
64
|
+
|
|
65
|
+
Parameters
|
|
66
|
+
----------
|
|
67
|
+
angle float
|
|
68
|
+
the angle in degrees
|
|
69
|
+
|
|
70
|
+
Returns
|
|
71
|
+
-------
|
|
72
|
+
an array of floats containing the muls corresponding to each angle
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
mu = self.mu
|
|
76
|
+
self.muls = []
|
|
77
|
+
if len(self.distances) == 0:
|
|
78
|
+
self.set_distances_at_angle(angle)
|
|
79
|
+
for distance in self.distances:
|
|
80
|
+
self.muls.append(np.exp(-mu * distance))
|
|
81
|
+
|
|
82
|
+
def _get_entry_exit_coordinates(self, coordinate, angle):
|
|
83
|
+
"""
|
|
84
|
+
get the coordinates where the beam enters and leaves the circle for a given angle and grid point
|
|
85
|
+
|
|
86
|
+
Parameters
|
|
87
|
+
----------
|
|
88
|
+
grid_point tuple of floats
|
|
89
|
+
the coordinates of the grid point
|
|
90
|
+
|
|
91
|
+
angle float
|
|
92
|
+
the angle in degrees
|
|
93
|
+
|
|
94
|
+
radius float
|
|
95
|
+
the radius of the circle in units of inverse mu
|
|
96
|
+
|
|
97
|
+
it is calculated in the following way:
|
|
98
|
+
For the entry coordinate, the y-component will be the y of the grid point and the x-component will be minus
|
|
99
|
+
the value of x on the circle at the height of this y.
|
|
100
|
+
|
|
101
|
+
For the exit coordinate:
|
|
102
|
+
Find the line y = ax + b that passes through grid_point at angle angle
|
|
103
|
+
The circle is x^2 + y^2 = r^2
|
|
104
|
+
The exit point is where these are simultaneous equations
|
|
105
|
+
x^2 + y^2 = r^2 & y = ax + b
|
|
106
|
+
x^2 + (ax+b)^2 = r^2
|
|
107
|
+
=> x^2 + a^2x^2 + 2abx + b^2 - r^2 = 0
|
|
108
|
+
=> (1+a^2) x^2 + 2abx + (b^2 - r^2) = 0
|
|
109
|
+
to find x_exit we find the roots of these equations and pick the root that is above y-grid
|
|
110
|
+
then we get y_exit from y_exit = a*x_exit + b
|
|
111
|
+
|
|
112
|
+
Returns
|
|
113
|
+
-------
|
|
114
|
+
(1) the coordinate of the entry point and (2) of the exit point of a beam entering horizontally
|
|
115
|
+
impinging on a coordinate point that lies in the circle and then exiting at some angle, angle.
|
|
116
|
+
|
|
117
|
+
"""
|
|
118
|
+
epsilon = 1e-7 # precision close to 90
|
|
119
|
+
angle = math.radians(angle)
|
|
120
|
+
xgrid = coordinate[0]
|
|
121
|
+
ygrid = coordinate[1]
|
|
122
|
+
|
|
123
|
+
entry_point = (-math.sqrt(self.radius**2 - ygrid**2), ygrid)
|
|
124
|
+
|
|
125
|
+
if not math.isclose(angle, math.pi / 2, abs_tol=epsilon):
|
|
126
|
+
b = ygrid - xgrid * math.tan(angle)
|
|
127
|
+
a = math.tan(angle)
|
|
128
|
+
xexit_root1, xexit_root2 = np.roots((1 + a**2, 2 * a * b, b**2 - self.radius**2))
|
|
129
|
+
yexit_root1 = a * xexit_root1 + b
|
|
130
|
+
yexit_root2 = a * xexit_root2 + b
|
|
131
|
+
if yexit_root2 >= yexit_root1: # We pick the point above
|
|
132
|
+
exit_point = (xexit_root2, yexit_root2)
|
|
133
|
+
else:
|
|
134
|
+
exit_point = (xexit_root1, yexit_root1)
|
|
135
|
+
else:
|
|
136
|
+
exit_point = (xgrid, math.sqrt(self.radius**2 - xgrid**2))
|
|
137
|
+
|
|
138
|
+
return entry_point, exit_point
|
|
139
|
+
|
|
140
|
+
def get_path_length(self, grid_point, angle):
|
|
141
|
+
"""
|
|
142
|
+
return the path length
|
|
143
|
+
|
|
144
|
+
This is the pathlength of a horizontal line entering the circle at the
|
|
145
|
+
same height to the grid point then exiting at angle angle
|
|
146
|
+
|
|
147
|
+
Parameters
|
|
148
|
+
----------
|
|
149
|
+
grid_point double of floats
|
|
150
|
+
the coordinate inside the circle
|
|
151
|
+
|
|
152
|
+
angle float
|
|
153
|
+
the angle of the output beam
|
|
154
|
+
|
|
155
|
+
radius
|
|
156
|
+
the radius of the circle
|
|
157
|
+
|
|
158
|
+
Returns
|
|
159
|
+
-------
|
|
160
|
+
floats total distance, primary distance and secondary distance
|
|
161
|
+
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
# move angle a tad above zero if it is zero to avoid it having the wrong sign due to some rounding error
|
|
165
|
+
angle_delta = 0.000001
|
|
166
|
+
if angle == float(0):
|
|
167
|
+
angle = angle + angle_delta
|
|
168
|
+
entry, exit = self._get_entry_exit_coordinates(grid_point, angle)
|
|
169
|
+
primary_distance = math.dist(grid_point, entry)
|
|
170
|
+
secondary_distance = math.dist(grid_point, exit)
|
|
171
|
+
total_distance = primary_distance + secondary_distance
|
|
172
|
+
return total_distance, primary_distance, secondary_distance
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def compute_cve(diffraction_data, mud, wavelength):
|
|
176
|
+
"""
|
|
177
|
+
compute the cve for given diffraction data, mud and wavelength
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
diffraction_data Diffraction_object
|
|
182
|
+
the diffraction pattern
|
|
183
|
+
mud float
|
|
184
|
+
the mu*D of the diffraction object, where D is the diameter of the circle
|
|
185
|
+
wavelength float
|
|
186
|
+
the wavelength of the diffraction object
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
the diffraction object with cve curves
|
|
191
|
+
|
|
192
|
+
it is computed as follows:
|
|
193
|
+
We first resample data and absorption correction to a more reasonable grid,
|
|
194
|
+
then calculate corresponding cve for the given mud in the resample grid
|
|
195
|
+
(since the same mu*D yields the same cve, we can assume that D/2=1, so mu=mud/2),
|
|
196
|
+
and finally interpolate cve to the original grid in diffraction_data.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
mu_sample_invmm = mud / 2
|
|
200
|
+
abs_correction = Gridded_circle(mu=mu_sample_invmm)
|
|
201
|
+
distances, muls = [], []
|
|
202
|
+
for angle in TTH_GRID:
|
|
203
|
+
abs_correction.set_distances_at_angle(angle)
|
|
204
|
+
abs_correction.set_muls_at_angle(angle)
|
|
205
|
+
distances.append(sum(abs_correction.distances))
|
|
206
|
+
muls.append(sum(abs_correction.muls))
|
|
207
|
+
distances = np.array(distances) / abs_correction.total_points_in_grid
|
|
208
|
+
muls = np.array(muls) / abs_correction.total_points_in_grid
|
|
209
|
+
cve = 1 / muls
|
|
210
|
+
|
|
211
|
+
orig_grid = diffraction_data.on_tth[0]
|
|
212
|
+
newcve = np.interp(orig_grid, TTH_GRID, cve)
|
|
213
|
+
abdo = Diffraction_object(wavelength=wavelength)
|
|
214
|
+
abdo.insert_scattering_quantity(
|
|
215
|
+
orig_grid,
|
|
216
|
+
newcve,
|
|
217
|
+
"tth",
|
|
218
|
+
metadata=diffraction_data.metadata,
|
|
219
|
+
name=f"absorption correction, cve, for {diffraction_data.name}",
|
|
220
|
+
wavelength=diffraction_data.wavelength,
|
|
221
|
+
scat_quantity="cve",
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
return abdo
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def apply_corr(diffraction_pattern, absorption_correction):
|
|
228
|
+
"""
|
|
229
|
+
Apply absorption correction to the given diffraction object modo with the correction diffraction object abdo
|
|
230
|
+
|
|
231
|
+
Parameters
|
|
232
|
+
----------
|
|
233
|
+
diffraction_pattern Diffraction_object
|
|
234
|
+
the input diffraction object to which the cve will be applied
|
|
235
|
+
absorption_correction Diffraction_object
|
|
236
|
+
the diffraction object that contains the cve to be applied
|
|
237
|
+
|
|
238
|
+
Returns
|
|
239
|
+
-------
|
|
240
|
+
a corrected diffraction object with the correction applied through multiplication
|
|
241
|
+
|
|
242
|
+
"""
|
|
243
|
+
|
|
244
|
+
corrected_pattern = diffraction_pattern * absorption_correction
|
|
245
|
+
return corrected_pattern
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from argparse import ArgumentParser
|
|
3
|
+
|
|
4
|
+
from diffpy.labpdfproc.functions import apply_corr, compute_cve
|
|
5
|
+
from diffpy.labpdfproc.tools import known_sources, load_metadata, preprocessing_args
|
|
6
|
+
from diffpy.utils.parsers.loaddata import loadData
|
|
7
|
+
from diffpy.utils.scattering_objects.diffraction_objects import XQUANTITIES, Diffraction_object
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_args(override_cli_inputs=None):
|
|
11
|
+
p = ArgumentParser()
|
|
12
|
+
p.add_argument("mud", help="Value of mu*D for your " "sample. Required.", type=float)
|
|
13
|
+
p.add_argument(
|
|
14
|
+
"input",
|
|
15
|
+
nargs="+",
|
|
16
|
+
help="The filename(s) or folder(s) of the datafile(s) to load. "
|
|
17
|
+
"Required.\nSupply a space-separated list of files or directories."
|
|
18
|
+
"Long lists can be supplied, one per line, in a file with name "
|
|
19
|
+
"file_list.txt. If one or more directory is provided, all valid "
|
|
20
|
+
"data-files in that directory will be processed. Examples of valid "
|
|
21
|
+
"inputs are 'file.xy', 'data/file.xy', 'file.xy, data/file.xy', "
|
|
22
|
+
"'.' (load everything in the current directory), 'data' (load"
|
|
23
|
+
"everything in the folder ./data), 'data/file_list.txt' (load"
|
|
24
|
+
" the list of files contained in the text-file called "
|
|
25
|
+
"file_list.txt that can be found in the folder ./data), "
|
|
26
|
+
"'./*.chi', 'data/*.chi' (load all files with extension .chi in the "
|
|
27
|
+
"folder ./data).",
|
|
28
|
+
)
|
|
29
|
+
p.add_argument(
|
|
30
|
+
"-a",
|
|
31
|
+
"--anode-type",
|
|
32
|
+
help=f"The type of the x-ray source. Allowed values are "
|
|
33
|
+
f"{*[known_sources], }. Either specify a known x-ray source or specify wavelength.",
|
|
34
|
+
default="Mo",
|
|
35
|
+
)
|
|
36
|
+
p.add_argument(
|
|
37
|
+
"-w",
|
|
38
|
+
"--wavelength",
|
|
39
|
+
help="X-ray source wavelength in angstroms. Not needed if the anode-type "
|
|
40
|
+
"is specified. This wavelength will override the anode wavelength if both are specified.",
|
|
41
|
+
default=None,
|
|
42
|
+
type=float,
|
|
43
|
+
)
|
|
44
|
+
p.add_argument(
|
|
45
|
+
"-o",
|
|
46
|
+
"--output-directory",
|
|
47
|
+
help="The name of the output directory. If not specified "
|
|
48
|
+
"then corrected files will be written to the current directory."
|
|
49
|
+
"If the specified directory doesn't exist it will be created.",
|
|
50
|
+
default=None,
|
|
51
|
+
)
|
|
52
|
+
p.add_argument(
|
|
53
|
+
"-x",
|
|
54
|
+
"--xtype",
|
|
55
|
+
help=f"The quantity on the independent variable axis. Allowed "
|
|
56
|
+
f"values: {*XQUANTITIES, }. If not specified then two-theta "
|
|
57
|
+
f"is assumed for the independent variable. Only implemented for "
|
|
58
|
+
f"tth currently.",
|
|
59
|
+
default="tth",
|
|
60
|
+
)
|
|
61
|
+
p.add_argument(
|
|
62
|
+
"-c",
|
|
63
|
+
"--output-correction",
|
|
64
|
+
action="store_true",
|
|
65
|
+
help="The absorption correction will be output to a file if this "
|
|
66
|
+
"flag is set. Default is that it is not output.",
|
|
67
|
+
default="tth",
|
|
68
|
+
)
|
|
69
|
+
p.add_argument(
|
|
70
|
+
"-f",
|
|
71
|
+
"--force-overwrite",
|
|
72
|
+
action="store_true",
|
|
73
|
+
help="Outputs will not overwrite existing file unless --force is specified.",
|
|
74
|
+
)
|
|
75
|
+
p.add_argument(
|
|
76
|
+
"-u",
|
|
77
|
+
"--user-metadata",
|
|
78
|
+
metavar="KEY=VALUE",
|
|
79
|
+
nargs="+",
|
|
80
|
+
help="Specify key-value pairs to be loaded into metadata using the format key=value. "
|
|
81
|
+
"Separate pairs with whitespace, and ensure no whitespaces before or after the = sign. "
|
|
82
|
+
"Avoid using = in keys. If multiple = signs are present, only the first separates the key and value. "
|
|
83
|
+
"If a key or value contains whitespace, enclose it in quotes. "
|
|
84
|
+
"For example, facility='NSLS II', 'facility=NSLS II', beamline=28ID-2, "
|
|
85
|
+
"'beamline'='28ID-2', 'favorite color'=blue, are all valid key=value items. ",
|
|
86
|
+
)
|
|
87
|
+
p.add_argument(
|
|
88
|
+
"-n",
|
|
89
|
+
"--username",
|
|
90
|
+
help="Username will be loaded from config files. Specify here "
|
|
91
|
+
"only if you want to override that behavior at runtime. ",
|
|
92
|
+
default=None,
|
|
93
|
+
)
|
|
94
|
+
p.add_argument(
|
|
95
|
+
"-e",
|
|
96
|
+
"--email",
|
|
97
|
+
help="Email will be loaded from config files. Specify here "
|
|
98
|
+
"only if you want to override that behavior at runtime. ",
|
|
99
|
+
default=None,
|
|
100
|
+
)
|
|
101
|
+
args = p.parse_args(override_cli_inputs)
|
|
102
|
+
return args
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def main():
|
|
106
|
+
args = get_args()
|
|
107
|
+
args = preprocessing_args(args)
|
|
108
|
+
|
|
109
|
+
for filepath in args.input_paths:
|
|
110
|
+
outfilestem = filepath.stem + "_corrected"
|
|
111
|
+
corrfilestem = filepath.stem + "_cve"
|
|
112
|
+
outfile = args.output_directory / (outfilestem + ".chi")
|
|
113
|
+
corrfile = args.output_directory / (corrfilestem + ".chi")
|
|
114
|
+
|
|
115
|
+
if outfile.exists() and not args.force_overwrite:
|
|
116
|
+
sys.exit(
|
|
117
|
+
f"Output file {str(outfile)} already exists. Please rerun "
|
|
118
|
+
f"specifying -f if you want to overwrite it."
|
|
119
|
+
)
|
|
120
|
+
if corrfile.exists() and args.output_correction and not args.force_overwrite:
|
|
121
|
+
sys.exit(
|
|
122
|
+
f"Corrections file {str(corrfile)} was requested and already "
|
|
123
|
+
f"exists. Please rerun specifying -f if you want to overwrite it."
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
input_pattern = Diffraction_object(wavelength=args.wavelength)
|
|
127
|
+
xarray, yarray = loadData(filepath, unpack=True)
|
|
128
|
+
input_pattern.insert_scattering_quantity(
|
|
129
|
+
xarray,
|
|
130
|
+
yarray,
|
|
131
|
+
"tth",
|
|
132
|
+
scat_quantity="x-ray",
|
|
133
|
+
name=filepath.stem,
|
|
134
|
+
metadata=load_metadata(args, filepath),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
absorption_correction = compute_cve(input_pattern, args.mud, args.wavelength)
|
|
138
|
+
corrected_data = apply_corr(input_pattern, absorption_correction)
|
|
139
|
+
corrected_data.name = f"Absorption corrected input_data: {input_pattern.name}"
|
|
140
|
+
corrected_data.dump(f"{outfile}", xtype="tth")
|
|
141
|
+
|
|
142
|
+
if args.output_correction:
|
|
143
|
+
absorption_correction.dump(f"{corrfile}", xtype="tth")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
if __name__ == "__main__":
|
|
147
|
+
main()
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from diffpy.utils.tools import get_package_info, get_user_info
|
|
5
|
+
|
|
6
|
+
WAVELENGTHS = {"Mo": 0.71, "Ag": 0.59, "Cu": 1.54}
|
|
7
|
+
known_sources = [key for key in WAVELENGTHS.keys()]
|
|
8
|
+
METADATA_KEYS_TO_EXCLUDE = ["output_correction", "force_overwrite", "input", "input_paths"]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def set_output_directory(args):
|
|
12
|
+
"""
|
|
13
|
+
set the output directory based on the given input arguments
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
args argparse.Namespace
|
|
18
|
+
the arguments from the parser
|
|
19
|
+
|
|
20
|
+
Returns
|
|
21
|
+
-------
|
|
22
|
+
pathlib.PosixPath that contains the full path of the output directory
|
|
23
|
+
|
|
24
|
+
it is determined as follows:
|
|
25
|
+
If user provides an output directory, use it.
|
|
26
|
+
Otherwise, we set it to the current directory if nothing is provided.
|
|
27
|
+
We then create the directory if it does not exist.
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
output_dir = Path(args.output_directory).resolve() if args.output_directory else Path.cwd().resolve()
|
|
31
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
32
|
+
return output_dir
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _expand_user_input(args):
|
|
36
|
+
"""
|
|
37
|
+
Expands the list of inputs by adding files from file lists and wildcards.
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
args argparse.Namespace
|
|
42
|
+
the arguments from the parser
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
the arguments with the modified input list
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
file_list_inputs = [input_name for input_name in args.input if "file_list" in input_name]
|
|
50
|
+
for file_list_input in file_list_inputs:
|
|
51
|
+
with open(file_list_input, "r") as f:
|
|
52
|
+
file_inputs = [input_name.strip() for input_name in f.readlines()]
|
|
53
|
+
args.input.extend(file_inputs)
|
|
54
|
+
args.input.remove(file_list_input)
|
|
55
|
+
wildcard_inputs = [input_name for input_name in args.input if "*" in input_name]
|
|
56
|
+
for wildcard_input in wildcard_inputs:
|
|
57
|
+
input_files = [str(file) for file in Path(".").glob(wildcard_input) if "file_list" not in file.name]
|
|
58
|
+
args.input.extend(input_files)
|
|
59
|
+
args.input.remove(wildcard_input)
|
|
60
|
+
return args
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def set_input_lists(args):
|
|
64
|
+
"""
|
|
65
|
+
Set input directory and files.
|
|
66
|
+
|
|
67
|
+
It takes cli inputs, checks if they are files or directories and creates
|
|
68
|
+
a list of files to be processed which is stored in the args Namespace.
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
args argparse.Namespace
|
|
73
|
+
the arguments from the parser
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
args argparse.Namespace
|
|
78
|
+
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
input_paths = []
|
|
82
|
+
args = _expand_user_input(args)
|
|
83
|
+
for input_name in args.input:
|
|
84
|
+
input_path = Path(input_name).resolve()
|
|
85
|
+
if input_path.exists():
|
|
86
|
+
if input_path.is_file():
|
|
87
|
+
input_paths.append(input_path)
|
|
88
|
+
elif input_path.is_dir():
|
|
89
|
+
input_files = input_path.glob("*")
|
|
90
|
+
input_files = [
|
|
91
|
+
file.resolve() for file in input_files if file.is_file() and "file_list" not in file.name
|
|
92
|
+
]
|
|
93
|
+
input_paths.extend(input_files)
|
|
94
|
+
else:
|
|
95
|
+
raise FileNotFoundError(
|
|
96
|
+
f"Cannot find {input_name}. Please specify valid input file(s) or directories."
|
|
97
|
+
)
|
|
98
|
+
else:
|
|
99
|
+
raise FileNotFoundError(f"Cannot find {input_name}.")
|
|
100
|
+
setattr(args, "input_paths", list(set(input_paths)))
|
|
101
|
+
return args
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def set_wavelength(args):
|
|
105
|
+
"""
|
|
106
|
+
Set the wavelength based on the given input arguments
|
|
107
|
+
|
|
108
|
+
Parameters
|
|
109
|
+
----------
|
|
110
|
+
args argparse.Namespace
|
|
111
|
+
the arguments from the parser
|
|
112
|
+
|
|
113
|
+
Returns
|
|
114
|
+
-------
|
|
115
|
+
args argparse.Namespace
|
|
116
|
+
|
|
117
|
+
we raise an ValueError if the input wavelength is non-positive
|
|
118
|
+
or if the input anode_type is not one of the known sources
|
|
119
|
+
|
|
120
|
+
"""
|
|
121
|
+
if args.wavelength is not None and args.wavelength <= 0:
|
|
122
|
+
raise ValueError(
|
|
123
|
+
"No valid wavelength. Please rerun specifying a known anode_type or a positive wavelength."
|
|
124
|
+
)
|
|
125
|
+
if not args.wavelength and args.anode_type and args.anode_type not in WAVELENGTHS:
|
|
126
|
+
raise ValueError(
|
|
127
|
+
f"Anode type not recognized. Please rerun specifying an anode_type from {*known_sources, }."
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
if args.wavelength:
|
|
131
|
+
delattr(args, "anode_type")
|
|
132
|
+
elif args.anode_type:
|
|
133
|
+
args.wavelength = WAVELENGTHS[args.anode_type]
|
|
134
|
+
else:
|
|
135
|
+
args.wavelength = WAVELENGTHS["Mo"]
|
|
136
|
+
return args
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _load_key_value_pair(s):
|
|
140
|
+
items = s.split("=")
|
|
141
|
+
key = items[0].strip()
|
|
142
|
+
if len(items) > 1:
|
|
143
|
+
value = "=".join(items[1:])
|
|
144
|
+
return (key, value)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def load_user_metadata(args):
|
|
148
|
+
"""
|
|
149
|
+
Load user metadata into the provided argparse Namespace, raise ValueError if in incorrect format
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
args argparse.Namespace
|
|
154
|
+
the arguments from the parser
|
|
155
|
+
|
|
156
|
+
Returns
|
|
157
|
+
-------
|
|
158
|
+
the updated argparse Namespace with user metadata inserted as key-value pairs
|
|
159
|
+
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
reserved_keys = vars(args).keys()
|
|
163
|
+
|
|
164
|
+
if args.user_metadata:
|
|
165
|
+
for item in args.user_metadata:
|
|
166
|
+
if "=" not in item:
|
|
167
|
+
raise ValueError(
|
|
168
|
+
"Please provide key-value pairs in the format key=value. "
|
|
169
|
+
"For more information, use `labpdfproc --help.`"
|
|
170
|
+
)
|
|
171
|
+
key, value = _load_key_value_pair(item)
|
|
172
|
+
if key in reserved_keys:
|
|
173
|
+
raise ValueError(f"{key} is a reserved name. Please rerun using a different key name. ")
|
|
174
|
+
if hasattr(args, key):
|
|
175
|
+
raise ValueError(f"Please do not specify repeated keys: {key}. ")
|
|
176
|
+
setattr(args, key, value)
|
|
177
|
+
delattr(args, "user_metadata")
|
|
178
|
+
return args
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def load_user_info(args):
|
|
182
|
+
"""
|
|
183
|
+
Update username and email using get_user_info function from diffpy.utils
|
|
184
|
+
|
|
185
|
+
Parameters
|
|
186
|
+
----------
|
|
187
|
+
args argparse.Namespace
|
|
188
|
+
the arguments from the parser, default is None
|
|
189
|
+
|
|
190
|
+
Returns
|
|
191
|
+
-------
|
|
192
|
+
the updated argparse Namespace with username and email inserted
|
|
193
|
+
|
|
194
|
+
"""
|
|
195
|
+
config = {"username": args.username, "email": args.email}
|
|
196
|
+
config = get_user_info(config)
|
|
197
|
+
args.username = config["username"]
|
|
198
|
+
args.email = config["email"]
|
|
199
|
+
return args
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def load_package_info(args):
|
|
203
|
+
"""
|
|
204
|
+
Load diffpy.labpdfproc package name and version into args using get_package_info function from diffpy.utils
|
|
205
|
+
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
208
|
+
args argparse.Namespace
|
|
209
|
+
the arguments from the parser, default is None
|
|
210
|
+
|
|
211
|
+
Returns
|
|
212
|
+
-------
|
|
213
|
+
the updated argparse Namespace with diffpy.labpdfproc name and version inserted
|
|
214
|
+
|
|
215
|
+
"""
|
|
216
|
+
metadata = get_package_info("diffpy.labpdfproc")
|
|
217
|
+
setattr(args, "package_info", metadata["package_info"])
|
|
218
|
+
return args
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def preprocessing_args(args):
|
|
222
|
+
"""
|
|
223
|
+
Perform preprocessing on the provided argparse Namespace
|
|
224
|
+
|
|
225
|
+
Parameters
|
|
226
|
+
----------
|
|
227
|
+
args argparse.Namespace
|
|
228
|
+
the arguments from the parser, default is None
|
|
229
|
+
|
|
230
|
+
Returns
|
|
231
|
+
-------
|
|
232
|
+
the updated argparse Namespace with arguments preprocessed
|
|
233
|
+
"""
|
|
234
|
+
args = load_package_info(args)
|
|
235
|
+
args = load_user_info(args)
|
|
236
|
+
args = set_input_lists(args)
|
|
237
|
+
args.output_directory = set_output_directory(args)
|
|
238
|
+
args = set_wavelength(args)
|
|
239
|
+
args = load_user_metadata(args)
|
|
240
|
+
return args
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def load_metadata(args, filepath):
|
|
244
|
+
"""
|
|
245
|
+
Load relevant metadata from args
|
|
246
|
+
|
|
247
|
+
Parameters
|
|
248
|
+
----------
|
|
249
|
+
args argparse.Namespace
|
|
250
|
+
the arguments from the parser
|
|
251
|
+
|
|
252
|
+
Returns
|
|
253
|
+
-------
|
|
254
|
+
A dictionary with relevant arguments from the parser
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
metadata = copy.deepcopy(vars(args))
|
|
258
|
+
for key in METADATA_KEYS_TO_EXCLUDE:
|
|
259
|
+
metadata.pop(key, None)
|
|
260
|
+
metadata["input_directory"] = str(filepath)
|
|
261
|
+
metadata["output_directory"] = str(metadata["output_directory"])
|
|
262
|
+
return metadata
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
##############################################################################
|
|
3
|
+
#
|
|
4
|
+
# (c) 2024 The Trustees of Columbia University in the City of New York.
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# File coded by: Billinge Group members and community contributors.
|
|
8
|
+
#
|
|
9
|
+
# See GitHub contributions for a more detailed list of contributors.
|
|
10
|
+
# https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors
|
|
11
|
+
#
|
|
12
|
+
# See LICENSE.rst for license information.
|
|
13
|
+
#
|
|
14
|
+
##############################################################################
|
|
15
|
+
|
|
16
|
+
"""Definition of __version__."""
|
|
17
|
+
|
|
18
|
+
# We do not use the other three variables, but can be added back if needed.
|
|
19
|
+
# __all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"]
|
|
20
|
+
|
|
21
|
+
# obtain version information
|
|
22
|
+
from importlib.metadata import version
|
|
23
|
+
|
|
24
|
+
__version__ = version("diffpy.labpdfproc")
|
|
25
|
+
|
|
26
|
+
# End of file
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, diffpy
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
17
|
+
may be used to endorse or promote products derived from this software
|
|
18
|
+
without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, The Trustees of Columbia University
|
|
4
|
+
in the City of New York.
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
|
8
|
+
modification, are permitted provided that the following conditions are met:
|
|
9
|
+
|
|
10
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
11
|
+
list of conditions and the following disclaimer.
|
|
12
|
+
|
|
13
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
and/or other materials provided with the distribution.
|
|
16
|
+
|
|
17
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
18
|
+
may be used to endorse or promote products derived from this software
|
|
19
|
+
without specific prior written permission.
|
|
20
|
+
|
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
24
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
25
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
26
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
27
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
28
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
29
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
30
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: diffpy.labpdfproc
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Tools for processing x-ray powder diffraction data from laboratory sources
|
|
5
|
+
Author-email: "Simon J.L. Billinge group" <simon.billinge@gmail.com>
|
|
6
|
+
Maintainer-email: "Simon J.L. Billinge group" <simon.billinge@gmail.com>
|
|
7
|
+
Project-URL: Homepage, https://github.com/diffpy/diffpy.labpdfproc/
|
|
8
|
+
Project-URL: Issues, https://github.com/diffpy/diffpy.labpdfproc/issues/
|
|
9
|
+
Keywords: powder xrd,absorption correction,pdf,diffpy
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
15
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
16
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
17
|
+
Classifier: Operating System :: POSIX
|
|
18
|
+
Classifier: Operating System :: Unix
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/x-rst
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
License-File: LICENSE.rst
|
|
28
|
+
License-File: AUTHORS.rst
|
|
29
|
+
|
|
30
|
+
|Icon| |title|_
|
|
31
|
+
===============
|
|
32
|
+
|
|
33
|
+
.. |title| replace:: diffpy.labpdfproc
|
|
34
|
+
.. _title: https://diffpy.github.io/diffpy.labpdfproc
|
|
35
|
+
|
|
36
|
+
.. |Icon| image:: https://avatars.githubusercontent.com/diffpy
|
|
37
|
+
:target: https://diffpy.github.io/diffpy.labpdfproc
|
|
38
|
+
:height: 100px
|
|
39
|
+
|
|
40
|
+
|PyPi| |Forge| |PythonVersion| |PR|
|
|
41
|
+
|
|
42
|
+
|CI| |Codecov| |Black| |Tracking|
|
|
43
|
+
|
|
44
|
+
.. |Black| image:: https://img.shields.io/badge/code_style-black-black
|
|
45
|
+
:target: https://github.com/psf/black
|
|
46
|
+
|
|
47
|
+
.. |CI| image:: https://github.com/diffpy/diffpy.labpdfproc/actions/workflows/main.yml/badge.svg
|
|
48
|
+
:target: https://github.com/diffpy/diffpy.labpdfproc/actions/workflows/main.yml
|
|
49
|
+
|
|
50
|
+
.. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.labpdfproc/branch/main/graph/badge.svg
|
|
51
|
+
:target: https://codecov.io/gh/diffpy/diffpy.labpdfproc
|
|
52
|
+
|
|
53
|
+
.. |Forge| image:: https://img.shields.io/conda/vn/conda-forge/diffpy.labpdfproc
|
|
54
|
+
:target: https://anaconda.org/conda-forge/diffpy.labpdfproc
|
|
55
|
+
|
|
56
|
+
.. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff
|
|
57
|
+
|
|
58
|
+
.. |PyPi| image:: https://img.shields.io/pypi/v/diffpy.labpdfproc
|
|
59
|
+
:target: https://pypi.org/project/diffpy.labpdfproc/
|
|
60
|
+
|
|
61
|
+
.. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/diffpy.labpdfproc
|
|
62
|
+
:target: https://pypi.org/project/diffpy.labpdfproc/
|
|
63
|
+
|
|
64
|
+
.. |Tracking| image:: https://img.shields.io/badge/issue_tracking-github-blue
|
|
65
|
+
:target: https://github.com/diffpy/diffpy.labpdfproc/issues
|
|
66
|
+
|
|
67
|
+
Tools for processing x-ray powder diffraction data from laboratory sources
|
|
68
|
+
|
|
69
|
+
* LONGER DESCRIPTION HERE
|
|
70
|
+
|
|
71
|
+
For more information about the diffpy.labpdfproc library, please consult our `online documentation <https://diffpy.github.io/diffpy.labpdfproc>`_.
|
|
72
|
+
|
|
73
|
+
Citation
|
|
74
|
+
--------
|
|
75
|
+
|
|
76
|
+
If you use diffpy.labpdfproc in a scientific publication, we would like you to cite this package as
|
|
77
|
+
|
|
78
|
+
diffpy.labpdfproc Package, https://github.com/diffpy/diffpy.labpdfproc
|
|
79
|
+
|
|
80
|
+
Installation
|
|
81
|
+
------------
|
|
82
|
+
|
|
83
|
+
The preferred method is to use `Miniconda Python
|
|
84
|
+
<https://docs.conda.io/projects/miniconda/en/latest/miniconda-install.html>`_
|
|
85
|
+
and install from the "conda-forge" channel of Conda packages.
|
|
86
|
+
|
|
87
|
+
To add "conda-forge" to the conda channels, run the following in a terminal. ::
|
|
88
|
+
|
|
89
|
+
conda config --add channels conda-forge
|
|
90
|
+
|
|
91
|
+
We want to install our packages in a suitable conda environment.
|
|
92
|
+
The following creates and activates a new environment named ``diffpy.labpdfproc_env`` ::
|
|
93
|
+
|
|
94
|
+
conda create -n diffpy.labpdfproc_env python=3
|
|
95
|
+
conda activate diffpy.labpdfproc_env
|
|
96
|
+
|
|
97
|
+
Then, to fully install ``diffpy.labpdfproc`` in our active environment, run ::
|
|
98
|
+
|
|
99
|
+
conda install diffpy.labpdfproc
|
|
100
|
+
|
|
101
|
+
Another option is to use ``pip`` to download and install the latest release from
|
|
102
|
+
`Python Package Index <https://pypi.python.org>`_.
|
|
103
|
+
To install using ``pip`` into your ``diffpy.labpdfproc_env`` environment, we will also have to install dependencies ::
|
|
104
|
+
|
|
105
|
+
pip install -r https://raw.githubusercontent.com/diffpy/diffpy.labpdfproc/main/requirements/run.txt
|
|
106
|
+
|
|
107
|
+
and then install the package ::
|
|
108
|
+
|
|
109
|
+
pip install diffpy.labpdfproc
|
|
110
|
+
|
|
111
|
+
If you prefer to install from sources, after installing the dependencies, obtain the source archive from
|
|
112
|
+
`GitHub <https://github.com/diffpy/diffpy.labpdfproc/>`_. Once installed, ``cd`` into your ``diffpy.labpdfproc`` directory
|
|
113
|
+
and run the following ::
|
|
114
|
+
|
|
115
|
+
pip install .
|
|
116
|
+
|
|
117
|
+
Support and Contribute
|
|
118
|
+
----------------------
|
|
119
|
+
|
|
120
|
+
`Diffpy user group <https://groups.google.com/g/diffpy-users>`_ is the discussion forum for general questions and discussions about the use of diffpy.labpdfproc. Please join the diffpy.labpdfproc users community by joining the Google group. The diffpy.labpdfproc project welcomes your expertise and enthusiasm!
|
|
121
|
+
|
|
122
|
+
If you see a bug or want to request a feature, please `report it as an issue <https://github.com/diffpy/diffpy.labpdfproc/issues>`_ and/or `submit a fix as a PR <https://github.com/diffpy/diffpy.labpdfproc/pulls>`_. You can also post it to the `Diffpy user group <https://groups.google.com/g/diffpy-users>`_.
|
|
123
|
+
|
|
124
|
+
Feel free to fork the project and contribute. To install diffpy.labpdfproc
|
|
125
|
+
in a development mode, with its sources being directly used by Python
|
|
126
|
+
rather than copied to a package directory, use the following in the root
|
|
127
|
+
directory ::
|
|
128
|
+
|
|
129
|
+
pip install -e .
|
|
130
|
+
|
|
131
|
+
To ensure code quality and to prevent accidental commits into the default branch, please set up the use of our pre-commit
|
|
132
|
+
hooks.
|
|
133
|
+
|
|
134
|
+
1. Install pre-commit in your working environment by running ``conda install pre-commit``.
|
|
135
|
+
|
|
136
|
+
2. Initialize pre-commit (one time only) ``pre-commit install``.
|
|
137
|
+
|
|
138
|
+
Thereafter your code will be linted by black and isort and checked against flake8 before you can commit.
|
|
139
|
+
If it fails by black or isort, just rerun and it should pass (black and isort will modify the files so should
|
|
140
|
+
pass after they are modified). If the flake8 test fails please see the error messages and fix them manually before
|
|
141
|
+
trying to commit again.
|
|
142
|
+
|
|
143
|
+
Improvements and fixes are always appreciated.
|
|
144
|
+
|
|
145
|
+
Before contribuing, please read our `Code of Conduct <https://github.com/diffpy/diffpy.labpdfproc/blob/main/CODE_OF_CONDUCT.rst>`_.
|
|
146
|
+
|
|
147
|
+
Contact
|
|
148
|
+
-------
|
|
149
|
+
|
|
150
|
+
For more information on diffpy.labpdfproc please visit the project `web-page <https://diffpy.github.io/>`_ or email Prof. Simon Billinge at sb2896@columbia.edu.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
diffpy/__init__.py,sha256=mY5GT0s9cbvYOTt3dN_jc_-f1YX2S8U8WCOIRVdiwtY,674
|
|
2
|
+
diffpy/labpdfproc/__init__.py,sha256=ggPCM4ODqRR7HBSHodssOVqWcH1o3QvBveP99jTTjIY,763
|
|
3
|
+
diffpy/labpdfproc/functions.py,sha256=-FuCd9P-sYMnlo9r9hllYQBUi1uw7wEOmb8Zn2S7uWo,8447
|
|
4
|
+
diffpy/labpdfproc/labpdfprocapp.py,sha256=_9buPJzHahusIwLeSHQCfw80VcfmiPKbKUonVU-Xl9Q,5819
|
|
5
|
+
diffpy/labpdfproc/tools.py,sha256=LnGIa0Vmnu5IgCVO81qYdDnjmXsjHoMDdIl3aRh5x_k,7624
|
|
6
|
+
diffpy/labpdfproc/version.py,sha256=FvkklxMbPcPDVNb__bMPkZf6595jO6Qtbc74VcmKkuk,847
|
|
7
|
+
diffpy.labpdfproc-0.1.1.dist-info/AUTHORS.rst,sha256=B1ylUKR-H0qRuQM-HVGeOOSmeaV014G1PKEol2or4-8,185
|
|
8
|
+
diffpy.labpdfproc-0.1.1.dist-info/LICENSE,sha256=IY-Wt45bp8H44YBkdTvdSp7e5E4GkoV2_hyUgUTuwBs,1514
|
|
9
|
+
diffpy.labpdfproc-0.1.1.dist-info/LICENSE.rst,sha256=FFZAG9Hh02sJbGQEu06NuMxdgx_i1GuezTT4cKTyLkc,1568
|
|
10
|
+
diffpy.labpdfproc-0.1.1.dist-info/METADATA,sha256=IUEwpDTcxkIApXGGA0ZneB6bVE0xhpbzfjZwlsOgRj4,6559
|
|
11
|
+
diffpy.labpdfproc-0.1.1.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
|
|
12
|
+
diffpy.labpdfproc-0.1.1.dist-info/top_level.txt,sha256=34qLZyi9mxikpHepVDTMHrrNbe8VoOuz3ShYeiWA7KA,7
|
|
13
|
+
diffpy.labpdfproc-0.1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
diffpy
|