nxs-analysis-tools 0.0.44__tar.gz → 0.0.46__tar.gz
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.
Potentially problematic release.
This version of nxs-analysis-tools might be problematic. Click here for more details.
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/LICENSE +1 -1
- {nxs_analysis_tools-0.0.44/src/nxs_analysis_tools.egg-info → nxs_analysis_tools-0.0.46}/PKG-INFO +2 -2
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/pyproject.toml +1 -1
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/_meta/__init__.py +2 -2
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools/chess.py +54 -12
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools/datareduction.py +24 -8
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools/pairdistribution.py +85 -40
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46/src/nxs_analysis_tools.egg-info}/PKG-INFO +2 -2
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_symmetrizer_rectangular_plane.py +2 -3
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/MANIFEST.in +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/README.md +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/setup.cfg +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/setup.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools/__init__.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools/fitting.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools.egg-info/SOURCES.txt +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools.egg-info/dependency_links.txt +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools.egg-info/requires.txt +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools.egg-info/top_level.txt +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_chess.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_chess_fitting.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_datareduction.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_fitting.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_lmfit.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_mask_plotting.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_pairdistribution.py +0 -0
- {nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_plot_slice_with_ndarray.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2023 Steven J. Gomez Alvarado
|
|
3
|
+
Copyright (c) 2023-2025 Steven J. Gomez Alvarado
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
{nxs_analysis_tools-0.0.44/src/nxs_analysis_tools.egg-info → nxs_analysis_tools-0.0.46}/PKG-INFO
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nxs-analysis-tools
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.46
|
|
4
4
|
Summary: Reduce and transform nexus format (.nxs) scattering data.
|
|
5
5
|
Author-email: "Steven J. Gomez Alvarado" <stevenjgomez@ucsb.edu>
|
|
6
6
|
License: MIT License
|
|
7
7
|
|
|
8
|
-
Copyright (c) 2023 Steven J. Gomez Alvarado
|
|
8
|
+
Copyright (c) 2023-2025 Steven J. Gomez Alvarado
|
|
9
9
|
|
|
10
10
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
11
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
__project__ = 'nxs-analysis-tools'
|
|
5
5
|
__author__ = 'Steven J. Gomez Alvarado'
|
|
6
6
|
__email__ = 'stevenjgomez@ucsb.edu'
|
|
7
|
-
__copyright__ = f"2023, {__author__}"
|
|
7
|
+
__copyright__ = f"2023-2025, {__author__}"
|
|
8
8
|
__license__ = 'MIT'
|
|
9
|
-
__version__ = '0.0.
|
|
9
|
+
__version__ = '0.0.46'
|
|
10
10
|
__repo_url__ = 'https://github.com/stevenjgomez/nxs_analysis_tools'
|
|
@@ -58,9 +58,9 @@ class TempDependence:
|
|
|
58
58
|
Initialize Scissors and LinecutModel objects for each temperature.
|
|
59
59
|
set_data(temperature, data):
|
|
60
60
|
Set the dataset for a specific temperature.
|
|
61
|
-
load_transforms(temperatures_list=None):
|
|
61
|
+
load_transforms(temperatures_list=None, print_tree=True):
|
|
62
62
|
Load transform datasets (from nxrefine) based on temperature.
|
|
63
|
-
load_datasets(file_ending='hkli.nxs', temperatures_list=None):
|
|
63
|
+
load_datasets(file_ending='hkli.nxs', temperatures_list=None, print_tree=True):
|
|
64
64
|
Load datasets (CHESS format) from the specified folder.
|
|
65
65
|
get_sample_directory():
|
|
66
66
|
Get the folder path where the datasets are located.
|
|
@@ -98,6 +98,8 @@ class TempDependence:
|
|
|
98
98
|
Fit the line cut models for each temperature.
|
|
99
99
|
plot_fit(mdheadings=False, **kwargs):
|
|
100
100
|
Plot the fit results for each temperature.
|
|
101
|
+
plot_order_parameter(self):
|
|
102
|
+
Plot the temperature dependence of the peakheight parameter.
|
|
101
103
|
print_fit_report():
|
|
102
104
|
Print the fit report for each temperature.
|
|
103
105
|
"""
|
|
@@ -186,7 +188,7 @@ class TempDependence:
|
|
|
186
188
|
"""
|
|
187
189
|
self.datasets[temperature] = data
|
|
188
190
|
|
|
189
|
-
def load_transforms(self, temperatures_list=None):
|
|
191
|
+
def load_transforms(self, temperatures_list=None, print_tree=True):
|
|
190
192
|
"""
|
|
191
193
|
Load transform datasets (from nxrefine) based on temperature.
|
|
192
194
|
|
|
@@ -194,6 +196,8 @@ class TempDependence:
|
|
|
194
196
|
----------
|
|
195
197
|
temperatures_list : list of int or None, optional
|
|
196
198
|
List of temperatures to load. If None, all available temperatures are loaded.
|
|
199
|
+
print_tree : bool, optional
|
|
200
|
+
Whether to print the data tree upon loading. Default True.
|
|
197
201
|
"""
|
|
198
202
|
# Convert all temperatures to strings
|
|
199
203
|
if temperatures_list:
|
|
@@ -231,7 +235,7 @@ class TempDependence:
|
|
|
231
235
|
|
|
232
236
|
# Save dataset
|
|
233
237
|
try:
|
|
234
|
-
self.datasets[self.temperatures[i]] = load_transform(path)
|
|
238
|
+
self.datasets[self.temperatures[i]] = load_transform(path, print_tree)
|
|
235
239
|
except Exception as e:
|
|
236
240
|
# Report temperature that was unable to load, then raise exception.
|
|
237
241
|
temp_failed = self.temperatures[i]
|
|
@@ -245,7 +249,7 @@ class TempDependence:
|
|
|
245
249
|
# Initialize linecutmodel object
|
|
246
250
|
self.linecutmodels[self.temperatures[i]] = LinecutModel()
|
|
247
251
|
|
|
248
|
-
def load_datasets(self, file_ending='hkli.nxs', temperatures_list=None):
|
|
252
|
+
def load_datasets(self, file_ending='hkli.nxs', temperatures_list=None, print_tree=True):
|
|
249
253
|
"""
|
|
250
254
|
Load datasets (CHESS format) from the specified folder.
|
|
251
255
|
|
|
@@ -256,6 +260,8 @@ class TempDependence:
|
|
|
256
260
|
temperatures_list : list of int or None, optional
|
|
257
261
|
The list of specific temperatures to load. If None, all available temperatures are
|
|
258
262
|
loaded. The default is None.
|
|
263
|
+
print_tree : bool, optional
|
|
264
|
+
Whether to print the data tree upon loading. Default True.
|
|
259
265
|
"""
|
|
260
266
|
temperature_folders = [] # Empty list to store temperature folder names
|
|
261
267
|
for item in os.listdir(self.sample_directory):
|
|
@@ -278,7 +284,7 @@ class TempDependence:
|
|
|
278
284
|
filepath = os.path.join(self.sample_directory, T, file)
|
|
279
285
|
|
|
280
286
|
# Load dataset at each temperature
|
|
281
|
-
self.datasets[T] = load_data(filepath)
|
|
287
|
+
self.datasets[T] = load_data(filepath, print_tree)
|
|
282
288
|
|
|
283
289
|
# Initialize scissors object at each temperature
|
|
284
290
|
self.scissors[T] = Scissors()
|
|
@@ -370,15 +376,13 @@ class TempDependence:
|
|
|
370
376
|
A dictionary of linecuts obtained from the cutting operation.
|
|
371
377
|
"""
|
|
372
378
|
|
|
373
|
-
center = center if center is not None else self.scissors[self.temperatures[0]].center
|
|
374
|
-
window = window if window is not None else self.scissors[self.temperatures[0]].window
|
|
375
|
-
axis = axis if axis is not None else self.scissors[self.temperatures[0]].axis
|
|
376
|
-
|
|
377
379
|
for T in self.temperatures:
|
|
378
380
|
if verbose:
|
|
379
381
|
print("-------------------------------")
|
|
380
382
|
print("Cutting T = " + T + " K data...")
|
|
381
|
-
self.scissors[T].
|
|
383
|
+
self.scissors[T].set_center(center)
|
|
384
|
+
self.scissors[T].set_window(window)
|
|
385
|
+
self.scissors[T].cut_data(axis=axis, verbose=verbose)
|
|
382
386
|
self.linecuts[T] = self.scissors[T].linecut
|
|
383
387
|
self.linecutmodels[T].set_data(self.linecuts[T])
|
|
384
388
|
|
|
@@ -466,7 +470,7 @@ class TempDependence:
|
|
|
466
470
|
_, ax = plt.subplots()
|
|
467
471
|
p = ax.pcolormesh(X, Y, v_2d, **kwargs)
|
|
468
472
|
plt.colorbar(p, label='counts')
|
|
469
|
-
ax.set(xlabel=
|
|
473
|
+
ax.set(xlabel=self.xlabel, ylabel=r'$T$ (K)')
|
|
470
474
|
|
|
471
475
|
return p
|
|
472
476
|
|
|
@@ -641,6 +645,44 @@ class TempDependence:
|
|
|
641
645
|
title=f"{T} K",
|
|
642
646
|
**kwargs)
|
|
643
647
|
|
|
648
|
+
def plot_order_parameter(self):
|
|
649
|
+
"""
|
|
650
|
+
Plot the temperature dependence of the peak height (order parameter).
|
|
651
|
+
|
|
652
|
+
This method extracts the peak height from each temperature-dependent
|
|
653
|
+
line cut fit stored in `linecutmodels` and plots it as a function
|
|
654
|
+
of temperature using matplotlib.
|
|
655
|
+
|
|
656
|
+
Returns
|
|
657
|
+
-------
|
|
658
|
+
Figure
|
|
659
|
+
Matplotlib Figure object containing the peak height vs. temperature plot.
|
|
660
|
+
Axes
|
|
661
|
+
Matplotlib Axes object associated with the figure.
|
|
662
|
+
|
|
663
|
+
Notes
|
|
664
|
+
-----
|
|
665
|
+
- Temperature values are converted to integers for plotting.
|
|
666
|
+
- Peak heights are extracted from the 'peakheight' parameter in the model results.
|
|
667
|
+
- The plot uses standard axes labels with temperature in Kelvin.
|
|
668
|
+
"""
|
|
669
|
+
|
|
670
|
+
# Create an array of temperature values
|
|
671
|
+
temperatures = [int(T) for T in self.temperatures]
|
|
672
|
+
|
|
673
|
+
# Create an empty list for the peak heights
|
|
674
|
+
peakheights = []
|
|
675
|
+
|
|
676
|
+
# Extract the peakheight at every temperature
|
|
677
|
+
for T in self.temperatures:
|
|
678
|
+
peakheights.append(self.linecutmodels[T].modelresult.params['peakheight'].value)
|
|
679
|
+
|
|
680
|
+
# Plot the peakheights vs. temperature
|
|
681
|
+
fig, ax = plt.subplots()
|
|
682
|
+
ax.plot(temperatures, peakheights)
|
|
683
|
+
ax.set(xlabel='$T$ (K)', ylabel='peakheight')
|
|
684
|
+
return fig, ax
|
|
685
|
+
|
|
644
686
|
def print_fit_report(self):
|
|
645
687
|
"""
|
|
646
688
|
Plot the fit results.
|
{nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools/datareduction.py
RENAMED
|
@@ -19,7 +19,7 @@ __all__ = ['load_data', 'load_transform', 'plot_slice', 'Scissors',
|
|
|
19
19
|
'array_to_nxdata', 'Padder']
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def load_data(path):
|
|
22
|
+
def load_data(path, print_tree=True):
|
|
23
23
|
"""
|
|
24
24
|
Load data from a NeXus file at a specified path. It is assumed that the data follows the CHESS
|
|
25
25
|
file structure (i.e., root/entry/data/counts, etc.).
|
|
@@ -29,6 +29,9 @@ def load_data(path):
|
|
|
29
29
|
path : str
|
|
30
30
|
The path to the NeXus data file.
|
|
31
31
|
|
|
32
|
+
print_tree : bool, optional
|
|
33
|
+
Whether to print the data tree upon loading. Default True.
|
|
34
|
+
|
|
32
35
|
Returns
|
|
33
36
|
-------
|
|
34
37
|
data : nxdata object
|
|
@@ -38,31 +41,42 @@ def load_data(path):
|
|
|
38
41
|
|
|
39
42
|
g = nxload(path)
|
|
40
43
|
try:
|
|
41
|
-
print(g.entry.data.tree)
|
|
44
|
+
print(g.entry.data.tree) if print_tree else None
|
|
42
45
|
except NeXusError:
|
|
43
46
|
pass
|
|
44
47
|
|
|
45
48
|
return g.entry.data
|
|
46
49
|
|
|
47
50
|
|
|
48
|
-
def load_transform(path):
|
|
51
|
+
def load_transform(path, print_tree=True):
|
|
49
52
|
"""
|
|
50
53
|
Load data obtained from nxrefine output from a specified path.
|
|
51
54
|
|
|
52
55
|
Parameters
|
|
53
56
|
----------
|
|
54
|
-
path : str
|
|
57
|
+
path : str
|
|
58
|
+
The path to the transform data file.
|
|
59
|
+
|
|
60
|
+
print_tree : bool, optional
|
|
61
|
+
Whether to print the data tree upon loading. Default True.
|
|
55
62
|
|
|
56
63
|
Returns
|
|
57
64
|
-------
|
|
58
|
-
data : nxdata object
|
|
65
|
+
data : nxdata object
|
|
66
|
+
The loaded data stored in a nxdata object.
|
|
59
67
|
"""
|
|
68
|
+
|
|
60
69
|
g = nxload(path)
|
|
61
|
-
|
|
70
|
+
|
|
71
|
+
data = NXdata(NXfield(g.entry.transform.data.nxdata.transpose(2, 1, 0), name='counts'),
|
|
62
72
|
(g.entry.transform.Qh, g.entry.transform.Qk, g.entry.transform.Ql))
|
|
63
73
|
|
|
74
|
+
print(data.tree) if print_tree else None
|
|
75
|
+
|
|
76
|
+
return data
|
|
77
|
+
|
|
64
78
|
|
|
65
|
-
def array_to_nxdata(array, data_template, signal_name=
|
|
79
|
+
def array_to_nxdata(array, data_template, signal_name=None):
|
|
66
80
|
"""
|
|
67
81
|
Create an NXdata object from an input array and an NXdata template,
|
|
68
82
|
with an optional signal name.
|
|
@@ -78,7 +92,7 @@ def array_to_nxdata(array, data_template, signal_name='counts'):
|
|
|
78
92
|
|
|
79
93
|
signal_name : str, optional
|
|
80
94
|
The name of the signal within the NXdata object. If not provided,
|
|
81
|
-
the
|
|
95
|
+
the signal name is inherited from the data_template.
|
|
82
96
|
|
|
83
97
|
Returns
|
|
84
98
|
-------
|
|
@@ -87,6 +101,8 @@ def array_to_nxdata(array, data_template, signal_name='counts'):
|
|
|
87
101
|
based on the template.
|
|
88
102
|
"""
|
|
89
103
|
d = data_template
|
|
104
|
+
if signal_name is None:
|
|
105
|
+
signal_name = d.signal
|
|
90
106
|
return NXdata(NXfield(array, name=signal_name),
|
|
91
107
|
tuple(d[d.axes[i]] for i in range(len(d.axes))))
|
|
92
108
|
|
{nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools/pairdistribution.py
RENAMED
|
@@ -197,7 +197,7 @@ class Symmetrizer2D:
|
|
|
197
197
|
# Scale and skew counts
|
|
198
198
|
skew_angle_adj = 90 - self.skew_angle
|
|
199
199
|
|
|
200
|
-
scale2 = q1.max()/q2.max()
|
|
200
|
+
scale2 = 1 # q1.max()/q2.max() # TODO: Need to double check this
|
|
201
201
|
counts_unscaled2 = ndimage.affine_transform(counts,
|
|
202
202
|
Affine2D().scale(scale2, 1).inverted().get_matrix()[:2, :2],
|
|
203
203
|
offset=[-(1 - scale2) * counts.shape[
|
|
@@ -253,7 +253,7 @@ class Symmetrizer2D:
|
|
|
253
253
|
order=0,
|
|
254
254
|
)
|
|
255
255
|
|
|
256
|
-
scale2 =
|
|
256
|
+
scale2 = counts.shape[0]/counts.shape[1]
|
|
257
257
|
wedge = ndimage.affine_transform(wedge,
|
|
258
258
|
Affine2D().scale(scale2, 1).get_matrix()[:2, :2],
|
|
259
259
|
offset=[(1 - scale2) * counts.shape[0] / 2, 0],
|
|
@@ -458,20 +458,35 @@ class Symmetrizer3D:
|
|
|
458
458
|
self.a_star, self.b_star, self.c_star, \
|
|
459
459
|
self.al_star, self.be_star, self.ga_star = self.reciprocal_lattice_params
|
|
460
460
|
|
|
461
|
-
def symmetrize(self):
|
|
461
|
+
def symmetrize(self, positive_values=True):
|
|
462
462
|
"""
|
|
463
|
-
|
|
464
|
-
|
|
463
|
+
Symmetrize the 3D dataset by sequentially applying 2D symmetrization
|
|
464
|
+
on the three principal planes.
|
|
465
465
|
|
|
466
|
-
This method
|
|
467
|
-
|
|
468
|
-
|
|
466
|
+
This method performs symmetrization along the (q1-q2), (q1-q3),
|
|
467
|
+
and (q2-q3) planes, ensuring that the dataset maintains expected
|
|
468
|
+
symmetry properties. Optionally, negative values resulting from the
|
|
469
|
+
symmetrization process can be set to zero.
|
|
470
|
+
|
|
471
|
+
Parameters
|
|
472
|
+
----------
|
|
473
|
+
positive_values : bool, optional
|
|
474
|
+
If True, sets negative symmetrized values to zero (default is True).
|
|
469
475
|
|
|
470
476
|
Returns
|
|
471
477
|
-------
|
|
472
|
-
|
|
473
|
-
The symmetrized 3D dataset.
|
|
478
|
+
NXdata
|
|
479
|
+
The symmetrized 3D dataset stored in the `symmetrized` attribute.
|
|
480
|
+
|
|
481
|
+
Notes
|
|
482
|
+
-----
|
|
483
|
+
- Symmetrization is performed sequentially across three principal
|
|
484
|
+
planes using corresponding 2D symmetrization methods.
|
|
485
|
+
- The process prints progress updates and timing information.
|
|
486
|
+
- If `theta_max` is not set for a particular plane symmetrizer,
|
|
487
|
+
that plane is skipped.
|
|
474
488
|
"""
|
|
489
|
+
|
|
475
490
|
starttime = time.time()
|
|
476
491
|
data = self.data
|
|
477
492
|
q1, q2, q3 = self.q1, self.q2, self.q3
|
|
@@ -480,7 +495,8 @@ class Symmetrizer3D:
|
|
|
480
495
|
if self.plane1symmetrizer.theta_max is not None:
|
|
481
496
|
print('Symmetrizing ' + self.plane1 + ' planes...')
|
|
482
497
|
for k, value in enumerate(q3):
|
|
483
|
-
print(f'Symmetrizing {q3.nxname}={value:.02f}
|
|
498
|
+
print(f'Symmetrizing {q3.nxname}={value:.02f}.'
|
|
499
|
+
f'..', end='\r')
|
|
484
500
|
data_symmetrized = self.plane1symmetrizer.symmetrize_2d(data[:, :, k])
|
|
485
501
|
out_array[:, :, k] = data_symmetrized[data.signal].nxdata
|
|
486
502
|
print('\nSymmetrized ' + self.plane1 + ' planes.')
|
|
@@ -505,7 +521,8 @@ class Symmetrizer3D:
|
|
|
505
521
|
out_array[i, :, :] = data_symmetrized[data.signal].nxdata
|
|
506
522
|
print('\nSymmetrized ' + self.plane3 + ' planes.')
|
|
507
523
|
|
|
508
|
-
|
|
524
|
+
if positive_values:
|
|
525
|
+
out_array[out_array < 0] = 0
|
|
509
526
|
|
|
510
527
|
stoptime = time.time()
|
|
511
528
|
print(f"\nSymmetrization finished in {((stoptime - starttime) / 60):.02f} minutes.")
|
|
@@ -1032,15 +1049,28 @@ class Interpolator:
|
|
|
1032
1049
|
"""
|
|
1033
1050
|
self.kernel = kernel
|
|
1034
1051
|
|
|
1035
|
-
def interpolate(self):
|
|
1052
|
+
def interpolate(self, verbose=True, positive_values=True):
|
|
1036
1053
|
"""
|
|
1037
1054
|
Perform interpolation on the dataset using the specified kernel.
|
|
1038
1055
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1056
|
+
This method convolves the dataset with a kernel using `convolve_fft`
|
|
1057
|
+
to perform interpolation. The resulting interpolated data is stored
|
|
1058
|
+
in the `interpolated` attribute.
|
|
1059
|
+
|
|
1060
|
+
Parameters
|
|
1061
|
+
----------
|
|
1062
|
+
verbose : bool, optional
|
|
1063
|
+
If True, prints progress messages and timing information
|
|
1064
|
+
(default is True).
|
|
1065
|
+
positive_values : bool, optional
|
|
1066
|
+
If True, sets negative interpolated values to zero
|
|
1067
|
+
(default is True).
|
|
1042
1068
|
|
|
1043
|
-
|
|
1069
|
+
Notes
|
|
1070
|
+
-----
|
|
1071
|
+
- The convolution operation is performed in Fourier space.
|
|
1072
|
+
- If a previous interpolation time is recorded, it is displayed
|
|
1073
|
+
before starting a new interpolation.
|
|
1044
1074
|
|
|
1045
1075
|
Returns
|
|
1046
1076
|
-------
|
|
@@ -1048,21 +1078,22 @@ class Interpolator:
|
|
|
1048
1078
|
"""
|
|
1049
1079
|
start = time.time()
|
|
1050
1080
|
|
|
1051
|
-
if self.interp_time:
|
|
1081
|
+
if self.interp_time and verbose:
|
|
1052
1082
|
print(f"Last interpolation took {self.interp_time / 60:.2f} minutes.")
|
|
1053
1083
|
|
|
1054
|
-
print("Running interpolation...")
|
|
1084
|
+
print("Running interpolation...") if verbose else None
|
|
1055
1085
|
result = np.real(
|
|
1056
1086
|
convolve_fft(self.data[self.data.signal].nxdata,
|
|
1057
1087
|
self.kernel, allow_huge=True, return_fft=False))
|
|
1058
|
-
print("Interpolation finished.")
|
|
1088
|
+
print("Interpolation finished.") if verbose else None
|
|
1059
1089
|
|
|
1060
1090
|
end = time.time()
|
|
1061
1091
|
interp_time = end - start
|
|
1062
1092
|
|
|
1063
|
-
print(f'Interpolation took {interp_time / 60:.2f} minutes.')
|
|
1093
|
+
print(f'Interpolation took {interp_time / 60:.2f} minutes.') if verbose else None
|
|
1064
1094
|
|
|
1065
|
-
|
|
1095
|
+
if positive_values:
|
|
1096
|
+
result[result < 0] = 0
|
|
1066
1097
|
self.interpolated = array_to_nxdata(result, self.data)
|
|
1067
1098
|
|
|
1068
1099
|
def set_tukey_window(self, tukey_alphas=(1.0, 1.0, 1.0)):
|
|
@@ -1479,21 +1510,34 @@ class DeltaPDF:
|
|
|
1479
1510
|
self.interpolator.set_kernel(kernel)
|
|
1480
1511
|
self.kernel = kernel
|
|
1481
1512
|
|
|
1482
|
-
def interpolate(self):
|
|
1513
|
+
def interpolate(self, verbose=True, positive_values=True):
|
|
1483
1514
|
"""
|
|
1484
1515
|
Perform interpolation on the dataset using the specified kernel.
|
|
1485
1516
|
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1517
|
+
This method convolves the dataset with a kernel using `convolve_fft`
|
|
1518
|
+
to perform interpolation. The resulting interpolated data is stored
|
|
1519
|
+
in the `interpolated` attribute.
|
|
1520
|
+
|
|
1521
|
+
Parameters
|
|
1522
|
+
----------
|
|
1523
|
+
verbose : bool, optional
|
|
1524
|
+
If True, prints progress messages and timing information
|
|
1525
|
+
(default is True).
|
|
1526
|
+
positive_values : bool, optional
|
|
1527
|
+
If True, sets negative interpolated values to zero
|
|
1528
|
+
(default is True).
|
|
1489
1529
|
|
|
1490
|
-
|
|
1530
|
+
Notes
|
|
1531
|
+
-----
|
|
1532
|
+
- The convolution operation is performed in Fourier space.
|
|
1533
|
+
- If a previous interpolation time is recorded, it is displayed
|
|
1534
|
+
before starting a new interpolation.
|
|
1491
1535
|
|
|
1492
1536
|
Returns
|
|
1493
1537
|
-------
|
|
1494
1538
|
None
|
|
1495
1539
|
"""
|
|
1496
|
-
self.interpolator.interpolate()
|
|
1540
|
+
self.interpolator.interpolate(verbose, positive_values)
|
|
1497
1541
|
self.interpolated = self.interpolator.interpolated
|
|
1498
1542
|
|
|
1499
1543
|
def set_tukey_window(self, tukey_alphas=(1.0, 1.0, 1.0)):
|
|
@@ -1578,14 +1622,16 @@ class DeltaPDF:
|
|
|
1578
1622
|
"""
|
|
1579
1623
|
Perform a 3D Fourier Transform on the padded data.
|
|
1580
1624
|
|
|
1581
|
-
This
|
|
1582
|
-
using
|
|
1583
|
-
|
|
1584
|
-
|
|
1625
|
+
This method applies an inverse Fourier Transform to the padded data
|
|
1626
|
+
using `pyfftw` for optimized performance. The result is stored in
|
|
1627
|
+
the `fft` attribute as an NXdata object containing the transformed
|
|
1628
|
+
spatial frequency components.
|
|
1585
1629
|
|
|
1586
1630
|
Parameters
|
|
1587
1631
|
----------
|
|
1588
|
-
|
|
1632
|
+
is_2d : bool, optional
|
|
1633
|
+
If True, performs the FFT only along the first two axes,
|
|
1634
|
+
skipping the out-of-plane direction (default is False).
|
|
1589
1635
|
|
|
1590
1636
|
Returns
|
|
1591
1637
|
-------
|
|
@@ -1593,13 +1639,12 @@ class DeltaPDF:
|
|
|
1593
1639
|
|
|
1594
1640
|
Notes
|
|
1595
1641
|
-----
|
|
1596
|
-
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
of the original data axes.
|
|
1602
|
-
|
|
1642
|
+
- Calls `fourier_transform_nxdata` to perform the transformation.
|
|
1643
|
+
- The FFT is computed in two stages: first along the last dimension,
|
|
1644
|
+
then along the first two dimensions.
|
|
1645
|
+
- The output includes frequency components computed from the step
|
|
1646
|
+
sizes of the original data axes.
|
|
1603
1647
|
|
|
1604
1648
|
"""
|
|
1649
|
+
|
|
1605
1650
|
self.fft = fourier_transform_nxdata(self.padded, is_2d=is_2d)
|
{nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46/src/nxs_analysis_tools.egg-info}/PKG-INFO
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nxs-analysis-tools
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.46
|
|
4
4
|
Summary: Reduce and transform nexus format (.nxs) scattering data.
|
|
5
5
|
Author-email: "Steven J. Gomez Alvarado" <stevenjgomez@ucsb.edu>
|
|
6
6
|
License: MIT License
|
|
7
7
|
|
|
8
|
-
Copyright (c) 2023 Steven J. Gomez Alvarado
|
|
8
|
+
Copyright (c) 2023-2025 Steven J. Gomez Alvarado
|
|
9
9
|
|
|
10
10
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
11
|
of this software and associated documentation files (the "Software"), to deal
|
{nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_symmetrizer_rectangular_plane.py
RENAMED
|
@@ -194,14 +194,13 @@ class Symmetrizer2D:
|
|
|
194
194
|
# Scale and skew counts
|
|
195
195
|
skew_angle_adj = 90 - self.skew_angle
|
|
196
196
|
|
|
197
|
-
scale2 = q1.max()/q2.max()
|
|
197
|
+
scale2 = 1 # q1.max()/q2.max()
|
|
198
198
|
counts_unscaled2 = ndimage.affine_transform(counts,
|
|
199
199
|
Affine2D().scale(scale2, 1).inverted().get_matrix()[:2, :2],
|
|
200
200
|
offset=[-(1 - scale2) * counts.shape[
|
|
201
201
|
0] / 2 / scale2, 0],
|
|
202
202
|
order=0,
|
|
203
203
|
)
|
|
204
|
-
plot_slice(counts_unscaled2)
|
|
205
204
|
|
|
206
205
|
scale1 = np.cos(skew_angle_adj * np.pi / 180)
|
|
207
206
|
counts_unscaled1 = ndimage.affine_transform(counts_unscaled2,
|
|
@@ -251,7 +250,7 @@ class Symmetrizer2D:
|
|
|
251
250
|
order=0,
|
|
252
251
|
)
|
|
253
252
|
|
|
254
|
-
scale2 =
|
|
253
|
+
scale2 = counts.shape[0]/counts.shape[1]
|
|
255
254
|
wedge = ndimage.affine_transform(wedge,
|
|
256
255
|
Affine2D().scale(scale2, 1).get_matrix()[:2, :2],
|
|
257
256
|
offset=[(1 - scale2) * counts.shape[0] / 2, 0],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/src/nxs_analysis_tools.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nxs_analysis_tools-0.0.44 → nxs_analysis_tools-0.0.46}/tests/test_plot_slice_with_ndarray.py
RENAMED
|
File without changes
|