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 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,10 @@
1
+ Authors
2
+ =======
3
+
4
+ Billinge Group and community contibutors.
5
+
6
+ Contributors
7
+ ------------
8
+
9
+ For a list of contributors, visit
10
+ https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors
@@ -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,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (70.1.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ diffpy