Skip to content

Commit 0a3241b

Browse files
authored
Merge pull request #300 from bobleesj/docstrings-overview
docs: improve docstring based on group standards in diffraction_objects.py transforms.py
2 parents 52f1c79 + 5dfff33 commit 0a3241b

File tree

4 files changed

+155
-80
lines changed

4 files changed

+155
-80
lines changed

news/docstrings-refactor.rst

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
**Added:**
2+
3+
* Improved API documentation in `DiffractionObject` methods and properties using the NumPy docstring format and PEP 256
4+
5+
**Changed:**
6+
7+
* <news item>
8+
9+
**Deprecated:**
10+
11+
* <news item>
12+
13+
**Removed:**
14+
15+
* <news item>
16+
17+
**Fixed:**
18+
19+
* <news item>
20+
21+
**Security:**
22+
23+
* <news item>

src/diffpy/utils/diffraction_objects.py

+85-34
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,18 @@ def __init__(
9393
The dependent variable array corresponding to intensity values.
9494
xtype : str
9595
The type of the independent variable in `xarray`. Must be one of {*XQUANTITIES}.
96-
wavelength : float, optional
97-
The wavelength of the incoming beam, specified in angstroms (Å). Default is none.
98-
scat_quantity : str, optional
99-
The type of scattering experiment (e.g., "x-ray", "neutron"). Default is an empty string "".
100-
name : str, optional
101-
The name or label for the scattering data. Default is an empty string "".
102-
metadata : dict, optional
103-
The additional metadata associated with the diffraction object. Default is {}.
96+
wavelength : float, optional, default is None.
97+
The wavelength of the incoming beam, specified in angstroms (Å)
98+
scat_quantity : str, optional, default is an empty string "".
99+
The type of scattering experiment (e.g., "x-ray", "neutron").
100+
name : str, optional, default is an empty string "".
101+
The name or label for the scattering data.
102+
metadata : dict, optional, default is an empty dictionary {}
103+
The additional metadata associated with the diffraction object.
104104
105105
Examples
106106
--------
107-
Create a DiffractionObject for X-ray scattering data
107+
Create a DiffractionObject for X-ray scattering data:
108108
>>> import numpy as np
109109
>>> from diffpy.utils.diffraction_objects import DiffractionObject
110110
...
@@ -181,30 +181,32 @@ def __add__(self, other):
181181
182182
Parameters
183183
----------
184-
other : DiffractionObject or int or float
185-
The object to add to the current DiffractionObject. If `other` is a scalar value,
186-
it will be added to all yarray. The length of the yarray must match if `other` is
187-
an instance of DiffractionObject.
184+
other : DiffractionObject, int, or float
185+
The item to be added. If `other` is a scalar value, this value will be added to each element of the
186+
yarray of this DiffractionObject instance. If `other` is another DiffractionObject, the yarrays of the
187+
two DiffractionObjects will be combined element-wise. The result is a new DiffractionObject instance,
188+
representing the addition and using the xarray from the left-hand side DiffractionObject.
188189
189190
Returns
190191
-------
191192
DiffractionObject
192-
The new and deep-copied DiffractionObject instance after adding values to the yarray.
193+
The new DiffractionObject instance with modified yarray values. This instance is a deep copy of the
194+
original with the additions applied.
193195
194196
Raises
195197
------
196198
ValueError
197-
Raised when the length of the yarray of the two DiffractionObject instances do not match.
199+
Raised when the xarrays of two DiffractionObject instances are not equal.
198200
TypeError
199-
Raised when the type of `other` is not an instance of DiffractionObject, int, or float.
201+
Raised when `other` is not an instance of DiffractionObject, int, or float.
200202
201203
Examples
202204
--------
203-
Add a scalar value to the yarray of the DiffractionObject instance:
205+
Add a scalar value to the yarray of a DiffractionObject instance:
204206
>>> new_do = my_do + 10.1
205207
>>> new_do = 10.1 + my_do
206208
207-
Add the yarray of two DiffractionObject instances:
209+
Combine the yarrays of two DiffractionObject instances:
208210
>>> new_do = my_do_1 + my_do_2
209211
"""
210212

@@ -219,6 +221,21 @@ def __add__(self, other):
219221
__radd__ = __add__
220222

221223
def __sub__(self, other):
224+
"""Subtract scalar value or another DiffractionObject to the yarray of
225+
the DiffractionObject.
226+
227+
This method behaves similarly to the `__add__` method, but performs subtraction instead of addition.
228+
For details on parameters, returns, and exceptions, refer to the documentation for `__add__`.
229+
230+
Examples
231+
--------
232+
Subtract a scalar value from the yarray of a DiffractionObject instance:
233+
>>> new_do = my_do - 10.1
234+
235+
Subtract the yarrays of two DiffractionObject instances:
236+
>>> new_do = my_do_1 - my_do_2
237+
"""
238+
222239
self._check_operation_compatibility(other)
223240
subtracted_do = deepcopy(self)
224241
if isinstance(other, (int, float)):
@@ -230,6 +247,21 @@ def __sub__(self, other):
230247
__rsub__ = __sub__
231248

232249
def __mul__(self, other):
250+
"""Multiply a scalar value or another DiffractionObject with the yarray
251+
of this DiffractionObject.
252+
253+
This method behaves similarly to the `__add__` method, but performs multiplication instead of addition.
254+
For details on parameters, returns, and exceptions, refer to the documentation for `__add__`.
255+
256+
Examples
257+
--------
258+
Multiply a scalar value with the yarray of a DiffractionObject instance:
259+
>>> new_do = my_do * 3.5
260+
261+
Multiply the yarrays of two DiffractionObject instances:
262+
>>> new_do = my_do_1 * my_do_2
263+
"""
264+
233265
self._check_operation_compatibility(other)
234266
multiplied_do = deepcopy(self)
235267
if isinstance(other, (int, float)):
@@ -241,6 +273,20 @@ def __mul__(self, other):
241273
__rmul__ = __mul__
242274

243275
def __truediv__(self, other):
276+
"""Divide the yarray of this DiffractionObject by a scalar value or
277+
another DiffractionObject.
278+
279+
This method behaves similarly to the `__add__` method, but performs division instead of addition.
280+
For details on parameters, returns, and exceptions, refer to the documentation for `__add__`.
281+
282+
Examples
283+
--------
284+
Divide the yarray of a DiffractionObject instance by a scalar value:
285+
>>> new_do = my_do / 2.0
286+
287+
Divide the yarrays of two DiffractionObject instances:
288+
>>> new_do = my_do_1 / my_do_2
289+
"""
244290
self._check_operation_compatibility(other)
245291
divided_do = deepcopy(self)
246292
if isinstance(other, (int, float)):
@@ -291,7 +337,7 @@ def input_xtype(self):
291337
292338
Returns
293339
-------
294-
str
340+
input_xtype : str
295341
The type of `xarray`, which must be one of {*XQUANTITIES}.
296342
"""
297343
return self._input_xtype
@@ -306,7 +352,7 @@ def uuid(self):
306352
307353
Returns
308354
-------
309-
uuid
355+
uuid : UUID
310356
The unique identifier of the DiffractionObject instance.
311357
"""
312358
return self._uuid
@@ -328,7 +374,7 @@ def get_array_index(self, xtype, xvalue):
328374
329375
Returns
330376
-------
331-
int
377+
index : int
332378
The index of the closest value in the array associated with the specified xtype and the value provided.
333379
"""
334380

@@ -381,7 +427,7 @@ def on_d(self):
381427
return [self.all_arrays[:, 3], self.all_arrays[:, 0]]
382428

383429
def scale_to(self, target_diff_object, q=None, tth=None, d=None, offset=None):
384-
"""Returns a new diffraction object which is the current object but
430+
"""Return a new diffraction object which is the current object but
385431
rescaled in y to the target.
386432
387433
By default, if `q`, `tth`, or `d` are not provided, scaling is based on the max intensity from each object.
@@ -403,12 +449,12 @@ def scale_to(self, target_diff_object, q=None, tth=None, d=None, offset=None):
403449
404450
Returns
405451
-------
406-
scaled : DiffractionObject
452+
scaled_do : DiffractionObject
407453
The rescaled DiffractionObject as a new object.
408454
"""
409455
if offset is None:
410456
offset = 0
411-
scaled = self.copy()
457+
scaled_do = self.copy()
412458
count = sum([q is not None, tth is not None, d is not None])
413459
if count > 1:
414460
raise ValueError(
@@ -419,8 +465,8 @@ def scale_to(self, target_diff_object, q=None, tth=None, d=None, offset=None):
419465
if count == 0:
420466
q_target_max = max(target_diff_object.on_q()[1])
421467
q_self_max = max(self.on_q()[1])
422-
scaled._all_arrays[:, 0] = scaled._all_arrays[:, 0] * q_target_max / q_self_max + offset
423-
return scaled
468+
scaled_do._all_arrays[:, 0] = scaled_do._all_arrays[:, 0] * q_target_max / q_self_max + offset
469+
return scaled_do
424470

425471
xtype = "q" if q is not None else "tth" if tth is not None else "d"
426472
data = self.on_xtype(xtype)
@@ -430,21 +476,26 @@ def scale_to(self, target_diff_object, q=None, tth=None, d=None, offset=None):
430476

431477
xindex_data = (np.abs(data[0] - xvalue)).argmin()
432478
xindex_target = (np.abs(target[0] - xvalue)).argmin()
433-
scaled._all_arrays[:, 0] = data[1] * target[1][xindex_target] / data[1][xindex_data] + offset
434-
return scaled
479+
scaled_do._all_arrays[:, 0] = data[1] * target[1][xindex_target] / data[1][xindex_data] + offset
480+
return scaled_do
435481

436482
def on_xtype(self, xtype):
437-
"""Return a list of two 1D np array with x and y data, raise an error
438-
if the specified xtype is invalid.
483+
"""Return a tuple of two 1D numpy arrays containing x and y data.
439484
440485
Parameters
441486
----------
442-
xtype str
443-
the type of quantity for the independent variable from {*XQUANTITIES, }
487+
xtype : str
488+
The type of quantity for the independent variable chosen from {*XQUANTITIES, }
489+
490+
Raises
491+
------
492+
ValueError
493+
Raised when the specified xtype is not among {*XQUANTITIES, }
444494
445495
Returns
446496
-------
447-
a list of two 1D np array with x and y data
497+
(xarray, yarray) : tuple of ndarray
498+
The tuple containing two 1D numpy arrays with x and y data for the specified xtype.
448499
"""
449500
if xtype.lower() in ANGLEQUANTITIES:
450501
return self.on_tth()
@@ -485,6 +536,6 @@ def copy(self):
485536
Returns
486537
-------
487538
DiffractionObject
488-
A new instance of DiffractionObject, which is a deep copy of the current instance.
539+
The new instance of DiffractionObject, which is a deep copy of the current instance.
489540
"""
490541
return deepcopy(self)

src/diffpy/utils/tools.py

+20-19
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,33 @@
1111
from diffpy.utils.parsers.loaddata import loadData
1212

1313

14-
def _stringify(obj):
14+
def _stringify(string_value):
1515
"""Convert None to an empty string.
1616
1717
Parameters
1818
----------
19-
obj: str
20-
The object to convert. If None, return an empty string.
19+
string_value : str or None
20+
The value to be converted. If None, an empty string is returned.
2121
2222
Returns
2323
-------
24-
str or None:
25-
The converted string if obj is not None, otherwise an empty string.
24+
str
25+
The original string if string_value is not None, otherwise an empty string.
2626
"""
27-
return obj if obj is not None else ""
27+
return string_value if string_value is not None else ""
2828

2929

3030
def _load_config(file_path):
3131
"""Load configuration from a .json file.
3232
3333
Parameters
3434
----------
35-
file_path: Path
35+
file_path : Path
3636
The path to the configuration file.
3737
3838
Returns
3939
-------
40-
dict:
40+
config : dict
4141
The configuration dictionary or {} if the config file does not exist.
4242
"""
4343
config_file = Path(file_path).resolve()
@@ -50,7 +50,7 @@ def _load_config(file_path):
5050

5151

5252
def get_user_info(owner_name=None, owner_email=None, owner_orcid=None):
53-
"""Get name, email and orcid of the owner/user from various sources and
53+
"""Get name, email, and orcid of the owner/user from various sources and
5454
return it as a metadata dictionary.
5555
5656
The function looks for the information in json format configuration files with the name 'diffpyconfig.json'.
@@ -71,16 +71,16 @@ def get_user_info(owner_name=None, owner_email=None, owner_orcid=None):
7171
7272
Parameters
7373
----------
74-
owner_name: string, optional, default is the value stored in the global or local config file.
74+
owner_name : str, optional, default is the value stored in the global or local config file.
7575
The name of the user who will show as owner in the metadata that is stored with the data
76-
owner_email: string, optional, default is the value stored in the global or local config file.
76+
owner_email : str, optional, default is the value stored in the global or local config file.
7777
The email of the user/owner
78-
owner_orcid: string, optional, default is the value stored in the global or local config file.
78+
owner_orcid : str, optional, default is the value stored in the global or local config file.
7979
The ORCID id of the user/owner
8080
8181
Returns
8282
-------
83-
dict:
83+
user_info : dict
8484
The dictionary containing username, email and orcid of the user/owner, and any other information
8585
stored in the global or local config files.
8686
"""
@@ -97,7 +97,7 @@ def get_user_info(owner_name=None, owner_email=None, owner_orcid=None):
9797

9898

9999
def check_and_build_global_config(skip_config_creation=False):
100-
"""Checks for a global diffpu config file in user's home directory and
100+
"""Check for a global diffpu config file in user's home directory and
101101
creates one if it is missing.
102102
103103
The file it looks for is called diffpyconfig.json. This can contain anything in json format, but
@@ -116,12 +116,13 @@ def check_and_build_global_config(skip_config_creation=False):
116116
117117
Parameters
118118
----------
119-
skip_config_creation: bool, optional, Default is False
120-
The bool that will override the creation workflow even if no config file exists.
119+
skip_config_creation : bool, optional, default is False.
120+
The boolean that will override the creation workflow even if no config file exists.
121121
122122
Returns
123123
-------
124-
bool: True if the file exists and False otherwise.
124+
config_exists : bool
125+
The boolean indicating whether the config file exists.
125126
"""
126127
config_exists = False
127128
config_path = Path().home() / "diffpyconfig.json"
@@ -168,7 +169,7 @@ def check_and_build_global_config(skip_config_creation=False):
168169

169170

170171
def get_package_info(package_names, metadata=None):
171-
"""Fetches package version and updates it into (given) metadata.
172+
"""Fetch package version and updates it into (given) metadata.
172173
173174
Package info stored in metadata as {'package_info': {'package_name': 'version_number'}}.
174175
@@ -180,7 +181,7 @@ def get_package_info(package_names, metadata=None):
180181
181182
Returns
182183
-------
183-
dict:
184+
metadata : dict
184185
The updated metadata dict with package info inserted.
185186
"""
186187
if metadata is None:

0 commit comments

Comments
 (0)