diffpy.fourigui 0.1.0rc2__tar.gz → 0.2.0__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.
Files changed (37) hide show
  1. {diffpy_fourigui-0.1.0rc2/src/diffpy.fourigui.egg-info → diffpy_fourigui-0.2.0}/PKG-INFO +26 -15
  2. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/README.rst +23 -12
  3. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/pyproject.toml +10 -2
  4. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/requirements/test.txt +1 -0
  5. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/src/diffpy/fourigui/fourigui.py +43 -25
  6. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0/src/diffpy.fourigui.egg-info}/PKG-INFO +26 -15
  7. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/src/diffpy.fourigui.egg-info/SOURCES.txt +2 -1
  8. diffpy_fourigui-0.2.0/src/diffpy.fourigui.egg-info/entry_points.txt +2 -0
  9. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/integration_test.py +0 -28
  10. diffpy_fourigui-0.1.0rc2/tests/unit_test.py → diffpy_fourigui-0.2.0/tests/test_fourigui.py +78 -0
  11. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/AUTHORS.rst +0 -0
  12. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/LICENSE.rst +0 -0
  13. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/MANIFEST.in +0 -0
  14. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/requirements/build.txt +0 -0
  15. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/requirements/conda.txt +0 -0
  16. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/requirements/docs.txt +0 -0
  17. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/requirements/pip.txt +0 -0
  18. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/setup.cfg +0 -0
  19. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/src/diffpy/__init__.py +0 -0
  20. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/src/diffpy/fourigui/__init__.py +0 -0
  21. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/src/diffpy/fourigui/version.py +0 -0
  22. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/src/diffpy.fourigui.egg-info/dependency_links.txt +0 -0
  23. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/src/diffpy.fourigui.egg-info/requires.txt +0 -0
  24. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/src/diffpy.fourigui.egg-info/top_level.txt +0 -0
  25. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/conftest.py +0 -0
  26. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/test_version.py +0 -0
  27. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/__init__.py +0 -0
  28. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/dummydata.h5 +0 -0
  29. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/gofr.h5 +0 -0
  30. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/gofr_.h5 +0 -0
  31. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/gofr_cut.h5 +0 -0
  32. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/gofr_from_sofq_cut_10to40px.h5 +0 -0
  33. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/gofr_from_sofq_cut_15to35px.h5 +0 -0
  34. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/make_testdata.py +0 -0
  35. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/sofq.h5 +0 -0
  36. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/sofq_cut_10to40px.h5 +0 -0
  37. {diffpy_fourigui-0.1.0rc2 → diffpy_fourigui-0.2.0}/tests/testdata/sofq_cut_15to35px.h5 +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diffpy.fourigui
3
- Version: 0.1.0rc2
3
+ Version: 0.2.0
4
4
  Summary: Tool for visualizing 3D diffraction and PDF Images.
5
5
  Author-email: "Simon J.L. Billinge group" <simon.billinge@gmail.com>
6
6
  Maintainer-email: "Simon J.L. Billinge group" <simon.billinge@gmail.com>
@@ -16,12 +16,12 @@ Classifier: Operating System :: MacOS :: MacOS X
16
16
  Classifier: Operating System :: Microsoft :: Windows
17
17
  Classifier: Operating System :: POSIX
18
18
  Classifier: Operating System :: Unix
19
- Classifier: Programming Language :: Python :: 3.10
20
19
  Classifier: Programming Language :: Python :: 3.11
21
20
  Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
22
  Classifier: Topic :: Scientific/Engineering :: Physics
23
23
  Classifier: Topic :: Scientific/Engineering :: Chemistry
24
- Requires-Python: >=3.10
24
+ Requires-Python: <3.14,>=3.11
25
25
  Description-Content-Type: text/x-rst
26
26
  License-File: LICENSE.rst
27
27
  License-File: AUTHORS.rst
@@ -69,7 +69,13 @@ Requires-Dist: numpy
69
69
 
70
70
  Tool for visualizing 3D diffraction and PDF Images.
71
71
 
72
- * LONGER DESCRIPTION HERE
72
+ Diffpy.fourigui is a tool to visualize and process 3D data sets written with the Python programming language.
73
+ Diffpy.fourigui always displays one slice perpendicular to one axis and allows scrolling through the 3D data set along
74
+ the given axis with a slider. It shows feedback values such as global and local maxima, minima or NAN ratios.
75
+ The matplotlib panel e.g. for zooming and saving figures is featured. Diffpy.fourigui is designed for the processing of 3D
76
+ atomic pair distribution functions (PDFs). One can load a 3D reciprocal space scattering volume which can be Fourier
77
+ transformed to the 3D PDF. Thereby, one can apply cut off frequencies beyond and below given Q values, compare the
78
+ results and switch between the scattering volume in reciprocal space and 3D PDF in real space.
73
79
 
74
80
  For more information about the diffpy.fourigui library, please consult our `online documentation <https://diffpy.github.io/diffpy.fourigui>`_.
75
81
 
@@ -78,7 +84,9 @@ Citation
78
84
 
79
85
  If you use diffpy.fourigui in a scientific publication, we would like you to cite this package as
80
86
 
81
- diffpy.fourigui Package, https://github.com/diffpy/diffpy.fourigui
87
+ S. Y. Harouna-Mayer, S. Tao, Z. Gong, M. V. Zimmermann, D. Koziej, A.-C. Dippel, and S. J. L. Billinge,
88
+ `Real-Space Texture and Pole-Figure Analysis Using the 3D Pair Distribution
89
+ Function on a Platinum Thin Film <https://doi.org/10.1107/S2052252522006674>`_. *IUCrJ* **9 (5)**, 594–603 (2022).
82
90
 
83
91
  Installation
84
92
  ------------
@@ -94,20 +102,18 @@ To add "conda-forge" to the conda channels, run the following in a terminal. ::
94
102
  We want to install our packages in a suitable conda environment.
95
103
  The following creates and activates a new environment named ``diffpy.fourigui_env`` ::
96
104
 
97
- conda create -n diffpy.fourigui_env python=3
105
+ conda create -n diffpy.fourigui_env diffpy.fourigui
98
106
  conda activate diffpy.fourigui_env
99
107
 
100
- Then, to fully install ``diffpy.fourigui`` in our active environment, run ::
108
+ To confirm that the installation was successful, type ::
101
109
 
102
- conda install diffpy.fourigui
110
+ python -c "import diffpy.fourigui; print(diffpy.fourigui.__version__)"
103
111
 
104
- Another option is to use ``pip`` to download and install the latest release from
105
- `Python Package Index <https://pypi.python.org>`_.
106
- To install using ``pip`` into your ``diffpy.fourigui_env`` environment, we will also have to install dependencies ::
107
-
108
- pip install -r https://raw.githubusercontent.com/diffpy/diffpy.fourigui/main/requirements/run.txt
112
+ The output should print the latest version displayed on the badges above.
109
113
 
110
- and then install the package ::
114
+ If the above does not work, you can use ``pip`` to download and install the latest release from
115
+ `Python Package Index <https://pypi.python.org>`_.
116
+ To install using ``pip`` into your ``diffpy.fourigui_env`` environment, type ::
111
117
 
112
118
  pip install diffpy.fourigui
113
119
 
@@ -117,6 +123,11 @@ and run the following ::
117
123
 
118
124
  pip install .
119
125
 
126
+ Getting Started
127
+ ---------------
128
+
129
+ You may consult our `online documentation <https://diffpy.github.io/diffpy.fourigui>`_ for tutorials and API references.
130
+
120
131
  Support and Contribute
121
132
  ----------------------
122
133
 
@@ -145,7 +156,7 @@ trying to commit again.
145
156
 
146
157
  Improvements and fixes are always appreciated.
147
158
 
148
- Before contribuing, please read our `Code of Conduct <https://github.com/diffpy/diffpy.fourigui/blob/main/CODE_OF_CONDUCT.rst>`_.
159
+ Before contributing, please read our `Code of Conduct <https://github.com/diffpy/diffpy.fourigui/blob/main/CODE_OF_CONDUCT.rst>`_.
149
160
 
150
161
  Contact
151
162
  -------
@@ -37,7 +37,13 @@
37
37
 
38
38
  Tool for visualizing 3D diffraction and PDF Images.
39
39
 
40
- * LONGER DESCRIPTION HERE
40
+ Diffpy.fourigui is a tool to visualize and process 3D data sets written with the Python programming language.
41
+ Diffpy.fourigui always displays one slice perpendicular to one axis and allows scrolling through the 3D data set along
42
+ the given axis with a slider. It shows feedback values such as global and local maxima, minima or NAN ratios.
43
+ The matplotlib panel e.g. for zooming and saving figures is featured. Diffpy.fourigui is designed for the processing of 3D
44
+ atomic pair distribution functions (PDFs). One can load a 3D reciprocal space scattering volume which can be Fourier
45
+ transformed to the 3D PDF. Thereby, one can apply cut off frequencies beyond and below given Q values, compare the
46
+ results and switch between the scattering volume in reciprocal space and 3D PDF in real space.
41
47
 
42
48
  For more information about the diffpy.fourigui library, please consult our `online documentation <https://diffpy.github.io/diffpy.fourigui>`_.
43
49
 
@@ -46,7 +52,9 @@ Citation
46
52
 
47
53
  If you use diffpy.fourigui in a scientific publication, we would like you to cite this package as
48
54
 
49
- diffpy.fourigui Package, https://github.com/diffpy/diffpy.fourigui
55
+ S. Y. Harouna-Mayer, S. Tao, Z. Gong, M. V. Zimmermann, D. Koziej, A.-C. Dippel, and S. J. L. Billinge,
56
+ `Real-Space Texture and Pole-Figure Analysis Using the 3D Pair Distribution
57
+ Function on a Platinum Thin Film <https://doi.org/10.1107/S2052252522006674>`_. *IUCrJ* **9 (5)**, 594–603 (2022).
50
58
 
51
59
  Installation
52
60
  ------------
@@ -62,20 +70,18 @@ To add "conda-forge" to the conda channels, run the following in a terminal. ::
62
70
  We want to install our packages in a suitable conda environment.
63
71
  The following creates and activates a new environment named ``diffpy.fourigui_env`` ::
64
72
 
65
- conda create -n diffpy.fourigui_env python=3
73
+ conda create -n diffpy.fourigui_env diffpy.fourigui
66
74
  conda activate diffpy.fourigui_env
67
75
 
68
- Then, to fully install ``diffpy.fourigui`` in our active environment, run ::
76
+ To confirm that the installation was successful, type ::
69
77
 
70
- conda install diffpy.fourigui
78
+ python -c "import diffpy.fourigui; print(diffpy.fourigui.__version__)"
71
79
 
72
- Another option is to use ``pip`` to download and install the latest release from
73
- `Python Package Index <https://pypi.python.org>`_.
74
- To install using ``pip`` into your ``diffpy.fourigui_env`` environment, we will also have to install dependencies ::
75
-
76
- pip install -r https://raw.githubusercontent.com/diffpy/diffpy.fourigui/main/requirements/run.txt
80
+ The output should print the latest version displayed on the badges above.
77
81
 
78
- and then install the package ::
82
+ If the above does not work, you can use ``pip`` to download and install the latest release from
83
+ `Python Package Index <https://pypi.python.org>`_.
84
+ To install using ``pip`` into your ``diffpy.fourigui_env`` environment, type ::
79
85
 
80
86
  pip install diffpy.fourigui
81
87
 
@@ -85,6 +91,11 @@ and run the following ::
85
91
 
86
92
  pip install .
87
93
 
94
+ Getting Started
95
+ ---------------
96
+
97
+ You may consult our `online documentation <https://diffpy.github.io/diffpy.fourigui>`_ for tutorials and API references.
98
+
88
99
  Support and Contribute
89
100
  ----------------------
90
101
 
@@ -113,7 +124,7 @@ trying to commit again.
113
124
 
114
125
  Improvements and fixes are always appreciated.
115
126
 
116
- Before contribuing, please read our `Code of Conduct <https://github.com/diffpy/diffpy.fourigui/blob/main/CODE_OF_CONDUCT.rst>`_.
127
+ Before contributing, please read our `Code of Conduct <https://github.com/diffpy/diffpy.fourigui/blob/main/CODE_OF_CONDUCT.rst>`_.
117
128
 
118
129
  Contact
119
130
  -------
@@ -14,7 +14,7 @@ maintainers = [
14
14
  description = "Tool for visualizing 3D diffraction and PDF Images."
15
15
  keywords = ['diffraction', 'pdf', 'pair distribution function', 'gui']
16
16
  readme = "README.rst"
17
- requires-python = ">=3.10"
17
+ requires-python = ">=3.11, <3.14"
18
18
  classifiers = [
19
19
  'Development Status :: 5 - Production/Stable',
20
20
  'Environment :: Console',
@@ -25,13 +25,16 @@ classifiers = [
25
25
  'Operating System :: Microsoft :: Windows',
26
26
  'Operating System :: POSIX',
27
27
  'Operating System :: Unix',
28
- 'Programming Language :: Python :: 3.10',
29
28
  'Programming Language :: Python :: 3.11',
30
29
  'Programming Language :: Python :: 3.12',
30
+ 'Programming Language :: Python :: 3.13',
31
31
  'Topic :: Scientific/Engineering :: Physics',
32
32
  'Topic :: Scientific/Engineering :: Chemistry',
33
33
  ]
34
34
 
35
+ [project.scripts]
36
+ fourigui = "diffpy.fourigui.fourigui:main"
37
+
35
38
  [project.urls]
36
39
  Homepage = "https://github.com/diffpy/diffpy.fourigui/"
37
40
  Issues = "https://github.com/diffpy/diffpy.fourigui/issues/"
@@ -51,6 +54,11 @@ namespaces = false # to disable scanning PEP 420 namespaces (true by default)
51
54
  [tool.setuptools.dynamic]
52
55
  dependencies = {file = ["requirements/pip.txt"]}
53
56
 
57
+ [tool.codespell]
58
+ exclude-file = ".codespell/ignore_lines.txt"
59
+ ignore-words = ".codespell/ignore_words.txt"
60
+ skip = "*.cif,*.dat"
61
+
54
62
  [tool.black]
55
63
  line-length = 115
56
64
  include = '\.pyi?$'
@@ -4,3 +4,4 @@ codecov
4
4
  coverage
5
5
  pytest-cov
6
6
  pytest-env
7
+ pytest-mock
@@ -21,6 +21,7 @@ class Gui(tk.Frame):
21
21
  self.initUI()
22
22
 
23
23
  def initUI(self):
24
+ """Initialize the GUI for fourigui"""
24
25
 
25
26
  self.loaded = False # denotes whether a dataset is loaded
26
27
  self.transformed = False # denotes whether dataset is Fourier transformed
@@ -154,10 +155,10 @@ class Gui(tk.Frame):
154
155
  anibutton.grid(row=8, column=4)
155
156
 
156
157
  # row 10-12 Fourier transformation
157
- seperator = tk.Label(
158
+ separator = tk.Label(
158
159
  frame00, text=" "
159
160
  ) # __________________________________________________________________")
160
- seperator.grid(row=9, column=0, columnspan=5)
161
+ separator.grid(row=9, column=0, columnspan=5)
161
162
  cutofflabel = tk.Label(frame00, text="cutoff frequency")
162
163
  cutofflabel.grid(row=10, column=2, columnspan=2)
163
164
  qminlabel = tk.Label(frame00, text="qmin [px]:")
@@ -290,14 +291,11 @@ class Gui(tk.Frame):
290
291
  self.slider.grid(row=0, column=0, padx=10, pady=10, sticky=tk.N + tk.E + tk.S + tk.W)
291
292
 
292
293
  if not self.loaded:
293
-
294
294
  fig, ax = plt.subplots(figsize=(4.95, 4.95))
295
295
  fig = plt.gcf()
296
296
  DPI = fig.get_dpi()
297
297
  fig.set_size_inches(500 / float(DPI), 500 / float(DPI))
298
-
299
298
  self.plane_num.set(np.shape(self.cube)[0] // 2)
300
-
301
299
  if self.axis.get() == 0:
302
300
  self.im = plt.imshow(self.cube[self.plane_num.get(), :, :])
303
301
  elif self.axis.get() == 1:
@@ -318,7 +316,6 @@ class Gui(tk.Frame):
318
316
  self.canvas.draw()
319
317
  self.canvas.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
320
318
  self.loaded = True
321
-
322
319
  else:
323
320
  self.plot_plane()
324
321
  self.transformed = False
@@ -370,18 +367,18 @@ class Gui(tk.Frame):
370
367
  elif self.axis.get() == 2:
371
368
  plane = self.cube[:, :, self.plane_num.get()]
372
369
  nan_ratio = np.count_nonzero(np.isnan(plane)) / plane.size
373
- self.localmax["text"] = "{}".format(np.format_float_scientific(np.nanmax(plane), 1))
374
- self.localmin["text"] = "{}".format(np.format_float_scientific(np.nanmin(plane), 1))
375
- self.localsum["text"] = "{}".format(np.format_float_scientific(np.nansum(plane), 1))
376
- self.localnanratio["text"] = "{}".format(round(nan_ratio, 2))
370
+ self.localmax["text"] = f"{np.format_float_scientific(np.nanmax(plane), 1)}"
371
+ self.localmin["text"] = f"{np.format_float_scientific(np.nanmin(plane), 1)}"
372
+ self.localsum["text"] = f"{np.format_float_scientific(np.nansum(plane), 1)}"
373
+ self.localnanratio["text"] = f"{round(nan_ratio, 2)}"
377
374
 
378
375
  def intensity_upd_global(self):
379
- """show global intensity minimum, maximum and sum of 3D array"""
376
+ """Load global intensity minimum, maximum and sum of 3D array"""
380
377
  self.intensity_upd_local()
381
378
  nan_ratio = np.count_nonzero(np.isnan(self.cube)) / self.cube.size
382
- self.globalmax["text"] = "{}".format(np.format_float_scientific(np.nanmax(self.cube), 1))
383
- self.globalmin["text"] = "{}".format(np.format_float_scientific(np.nanmin(self.cube), 1))
384
- self.globalsum["text"] = "{}".format(np.format_float_scientific(np.nansum(self.cube), 1))
379
+ self.globalmax["text"] = f"{np.format_float_scientific(np.nanmax(self.cube), 1)}"
380
+ self.globalmin["text"] = f"{np.format_float_scientific(np.nanmin(self.cube), 1)}"
381
+ self.globalsum["text"] = f"{np.format_float_scientific(np.nansum(self.cube), 1)}"
385
382
  self.globalnanratio["text"] = "{}".format(round(nan_ratio, 2))
386
383
 
387
384
  def fft(self):
@@ -393,8 +390,9 @@ class Gui(tk.Frame):
393
390
  def perform_fft(fftholder):
394
391
  fftholder = np.nan_to_num(fftholder)
395
392
  size = list(fftholder.shape)
393
+ axes = list(range(fftholder.ndim))
396
394
  fftholder = np.fft.ifftshift(fftholder)
397
- fftholder = np.fft.fftn(fftholder, s=size, norm="ortho")
395
+ fftholder = np.fft.fftn(fftholder, s=size, axes=axes, norm="ortho")
398
396
  fftholder = np.fft.fftshift(fftholder)
399
397
  fftholder = fftholder.real
400
398
  return fftholder
@@ -458,25 +456,33 @@ class Gui(tk.Frame):
458
456
 
459
457
  def applycutoff(self):
460
458
  """
459
+ shape the reciprocal-space array
460
+
461
461
  reassign all voxels with distance smaller than qmin and greater than qmax
462
- from the central voxel to 0.0
462
+ to np.nan.
463
+
464
+ parameters:
465
+ -----------
463
466
  qmin, qmax is loaded from the qmin, qmax input panel
464
- currently opperates in units of pixels
467
+ currently operates in units of pixels
468
+
469
+ Returns:
470
+ --------
471
+ nothing
465
472
  """
466
473
  if not self.cutted:
467
-
468
- X, Y, Z = self.cube.shape
469
- sphere = np.ones((X, Y, Z))
474
+ xdim, ydim, zdim = self.cube.shape
475
+ sphere = np.ones((xdim, ydim, zdim))
470
476
  qmin = float(self.qminentry.get())
471
477
  qmax = float(self.qmaxentry.get())
472
478
  # convert qmin to pixels
473
479
  # convert qmax to pixels
474
480
  r2_inner = qmin**2
475
481
  r2_outer = qmax**2
476
- XS, YS, ZS = np.meshgrid(np.arange(X), np.arange(Y), np.arange(Z))
477
- R2 = (XS - X // 2) ** 2 + (YS - Y // 2) ** 2 + (ZS - Z // 2) ** 2
478
- mask = (R2 <= r2_inner) | (R2 >= r2_outer)
479
- sphere[mask] = np.nan
482
+ i, j, k = np.meshgrid(np.arange(xdim), np.arange(ydim), np.arange(zdim))
483
+ r2 = (i - xdim // 2) ** 2 + (j - ydim // 2) ** 2 + (k - zdim // 2) ** 2
484
+ mask = (r2 < r2_inner) | (r2 > r2_outer) # True if voxel is out of range
485
+ sphere[mask] = np.nan # therefore set to np.nan if out of range
480
486
 
481
487
  if self.space.get():
482
488
  self.cube_real = self.cube
@@ -501,6 +507,9 @@ class Gui(tk.Frame):
501
507
  self.intensity_upd_global()
502
508
 
503
509
  def redocutuff(self):
510
+ """
511
+ Redo the cutoff operation depending on the current space (real or reciprocal).
512
+ """
504
513
  if self.space.get(): # in real space
505
514
  self.cube_realcut = self.cube
506
515
  if not self.transformed:
@@ -513,6 +522,9 @@ class Gui(tk.Frame):
513
522
  self.intensity_upd_global()
514
523
 
515
524
  def newcutoff(self):
525
+ """
526
+ Apply a new cutoff based on the current space and cutoff settings.
527
+ """
516
528
  if self.cutoff.get():
517
529
  if self.space.get() and self.transformed:
518
530
  self.cube = self.cube_real
@@ -523,6 +535,9 @@ class Gui(tk.Frame):
523
535
  self.applycutoff()
524
536
 
525
537
  def plot_next_plane(self):
538
+ """
539
+ Plot the next plane in the dataset, looping back to the first if at the end.
540
+ """
526
541
  n = self.plane_num.get()
527
542
  if n == len(self.cube[self.axis.get()]) - 1:
528
543
  n = 0
@@ -533,7 +548,7 @@ class Gui(tk.Frame):
533
548
 
534
549
  def animation(self):
535
550
  """
536
- slices through the 3D array along the selcted axis
551
+ slices through the 3D array along the selected axis
537
552
  """
538
553
  try:
539
554
  if not self.anientry.get():
@@ -548,6 +563,9 @@ class Gui(tk.Frame):
548
563
  self.plot_next_plane()
549
564
 
550
565
  def multiple_funcs(*funcs):
566
+ """
567
+ Executes multiple functions passed as arguments in sequence.
568
+ """
551
569
  for func in funcs:
552
570
  func
553
571
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diffpy.fourigui
3
- Version: 0.1.0rc2
3
+ Version: 0.2.0
4
4
  Summary: Tool for visualizing 3D diffraction and PDF Images.
5
5
  Author-email: "Simon J.L. Billinge group" <simon.billinge@gmail.com>
6
6
  Maintainer-email: "Simon J.L. Billinge group" <simon.billinge@gmail.com>
@@ -16,12 +16,12 @@ Classifier: Operating System :: MacOS :: MacOS X
16
16
  Classifier: Operating System :: Microsoft :: Windows
17
17
  Classifier: Operating System :: POSIX
18
18
  Classifier: Operating System :: Unix
19
- Classifier: Programming Language :: Python :: 3.10
20
19
  Classifier: Programming Language :: Python :: 3.11
21
20
  Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
22
  Classifier: Topic :: Scientific/Engineering :: Physics
23
23
  Classifier: Topic :: Scientific/Engineering :: Chemistry
24
- Requires-Python: >=3.10
24
+ Requires-Python: <3.14,>=3.11
25
25
  Description-Content-Type: text/x-rst
26
26
  License-File: LICENSE.rst
27
27
  License-File: AUTHORS.rst
@@ -69,7 +69,13 @@ Requires-Dist: numpy
69
69
 
70
70
  Tool for visualizing 3D diffraction and PDF Images.
71
71
 
72
- * LONGER DESCRIPTION HERE
72
+ Diffpy.fourigui is a tool to visualize and process 3D data sets written with the Python programming language.
73
+ Diffpy.fourigui always displays one slice perpendicular to one axis and allows scrolling through the 3D data set along
74
+ the given axis with a slider. It shows feedback values such as global and local maxima, minima or NAN ratios.
75
+ The matplotlib panel e.g. for zooming and saving figures is featured. Diffpy.fourigui is designed for the processing of 3D
76
+ atomic pair distribution functions (PDFs). One can load a 3D reciprocal space scattering volume which can be Fourier
77
+ transformed to the 3D PDF. Thereby, one can apply cut off frequencies beyond and below given Q values, compare the
78
+ results and switch between the scattering volume in reciprocal space and 3D PDF in real space.
73
79
 
74
80
  For more information about the diffpy.fourigui library, please consult our `online documentation <https://diffpy.github.io/diffpy.fourigui>`_.
75
81
 
@@ -78,7 +84,9 @@ Citation
78
84
 
79
85
  If you use diffpy.fourigui in a scientific publication, we would like you to cite this package as
80
86
 
81
- diffpy.fourigui Package, https://github.com/diffpy/diffpy.fourigui
87
+ S. Y. Harouna-Mayer, S. Tao, Z. Gong, M. V. Zimmermann, D. Koziej, A.-C. Dippel, and S. J. L. Billinge,
88
+ `Real-Space Texture and Pole-Figure Analysis Using the 3D Pair Distribution
89
+ Function on a Platinum Thin Film <https://doi.org/10.1107/S2052252522006674>`_. *IUCrJ* **9 (5)**, 594–603 (2022).
82
90
 
83
91
  Installation
84
92
  ------------
@@ -94,20 +102,18 @@ To add "conda-forge" to the conda channels, run the following in a terminal. ::
94
102
  We want to install our packages in a suitable conda environment.
95
103
  The following creates and activates a new environment named ``diffpy.fourigui_env`` ::
96
104
 
97
- conda create -n diffpy.fourigui_env python=3
105
+ conda create -n diffpy.fourigui_env diffpy.fourigui
98
106
  conda activate diffpy.fourigui_env
99
107
 
100
- Then, to fully install ``diffpy.fourigui`` in our active environment, run ::
108
+ To confirm that the installation was successful, type ::
101
109
 
102
- conda install diffpy.fourigui
110
+ python -c "import diffpy.fourigui; print(diffpy.fourigui.__version__)"
103
111
 
104
- Another option is to use ``pip`` to download and install the latest release from
105
- `Python Package Index <https://pypi.python.org>`_.
106
- To install using ``pip`` into your ``diffpy.fourigui_env`` environment, we will also have to install dependencies ::
107
-
108
- pip install -r https://raw.githubusercontent.com/diffpy/diffpy.fourigui/main/requirements/run.txt
112
+ The output should print the latest version displayed on the badges above.
109
113
 
110
- and then install the package ::
114
+ If the above does not work, you can use ``pip`` to download and install the latest release from
115
+ `Python Package Index <https://pypi.python.org>`_.
116
+ To install using ``pip`` into your ``diffpy.fourigui_env`` environment, type ::
111
117
 
112
118
  pip install diffpy.fourigui
113
119
 
@@ -117,6 +123,11 @@ and run the following ::
117
123
 
118
124
  pip install .
119
125
 
126
+ Getting Started
127
+ ---------------
128
+
129
+ You may consult our `online documentation <https://diffpy.github.io/diffpy.fourigui>`_ for tutorials and API references.
130
+
120
131
  Support and Contribute
121
132
  ----------------------
122
133
 
@@ -145,7 +156,7 @@ trying to commit again.
145
156
 
146
157
  Improvements and fixes are always appreciated.
147
158
 
148
- Before contribuing, please read our `Code of Conduct <https://github.com/diffpy/diffpy.fourigui/blob/main/CODE_OF_CONDUCT.rst>`_.
159
+ Before contributing, please read our `Code of Conduct <https://github.com/diffpy/diffpy.fourigui/blob/main/CODE_OF_CONDUCT.rst>`_.
149
160
 
150
161
  Contact
151
162
  -------
@@ -12,6 +12,7 @@ src/diffpy/__init__.py
12
12
  src/diffpy.fourigui.egg-info/PKG-INFO
13
13
  src/diffpy.fourigui.egg-info/SOURCES.txt
14
14
  src/diffpy.fourigui.egg-info/dependency_links.txt
15
+ src/diffpy.fourigui.egg-info/entry_points.txt
15
16
  src/diffpy.fourigui.egg-info/requires.txt
16
17
  src/diffpy.fourigui.egg-info/top_level.txt
17
18
  src/diffpy/fourigui/__init__.py
@@ -19,8 +20,8 @@ src/diffpy/fourigui/fourigui.py
19
20
  src/diffpy/fourigui/version.py
20
21
  tests/conftest.py
21
22
  tests/integration_test.py
23
+ tests/test_fourigui.py
22
24
  tests/test_version.py
23
- tests/unit_test.py
24
25
  tests/testdata/__init__.py
25
26
  tests/testdata/dummydata.h5
26
27
  tests/testdata/gofr.h5
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ fourigui = diffpy.fourigui.fourigui:main
@@ -97,34 +97,6 @@ class TestGui(unittest.TestCase):
97
97
  # then
98
98
  self.assertTrue(np.allclose(result, self.test_gofr_cut_15to35px))
99
99
 
100
- def test_applycutoff_range1(self):
101
- # given
102
- self.test_gui.plot_plane = lambda *a, **b: ()
103
- self.test_gui.cube = self.test_sofq
104
- self.test_gui.qminentry.insert(0, "10")
105
- self.test_gui.qmaxentry.insert(0, "40")
106
-
107
- # when
108
- self.test_gui.applycutoff()
109
- result = self.test_gui.cube
110
-
111
- # then
112
- self.assertTrue(np.allclose(np.nan_to_num(result), np.nan_to_num(self.test_sofq_cut_10to40px)))
113
-
114
- def test_applycutoff_range2(self):
115
- # given
116
- self.test_gui.plot_plane = lambda *a, **b: ()
117
- self.test_gui.cube = self.test_sofq
118
- self.test_gui.qminentry.insert(0, "15")
119
- self.test_gui.qmaxentry.insert(0, "35")
120
-
121
- # when
122
- self.test_gui.applycutoff()
123
- result = self.test_gui.cube
124
-
125
- # then
126
- self.assertTrue(np.allclose(np.nan_to_num(result), np.nan_to_num(self.test_sofq_cut_15to35px)))
127
-
128
100
 
129
101
  if __name__ == "__main__":
130
102
  unittest.main()
@@ -1,6 +1,8 @@
1
+ import tkinter as tk
1
2
  import unittest
2
3
 
3
4
  import h5py
5
+ import numpy as np
4
6
 
5
7
  from diffpy.fourigui.fourigui import Gui
6
8
 
@@ -146,5 +148,81 @@ class TestGui(unittest.TestCase):
146
148
  self.assertTrue(self.test_gui.transformed and self.test_gui.transcutted)
147
149
 
148
150
 
151
+ def test_applycutoff(mocker):
152
+ root = tk.Tk()
153
+ fg = Gui()
154
+ # qmin of 1 and qmax of 2 is expected to leave the central pixel and corner
155
+ # pixels as NaN's
156
+ mocker.patch.object(fg.qminentry, "get", return_value=1.0)
157
+ mocker.patch.object(fg.qmaxentry, "get", return_value=2.0)
158
+ mocker.patch.object(fg, "plot_plane") # we don't want it to plot anything so intercept
159
+ fg.cutted = False
160
+ fg.cube = np.ones((5, 5, 5))
161
+ expected_ones = np.ones((5, 5, 5))
162
+ expected_recip = np.array(
163
+ [
164
+ [
165
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
166
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
167
+ [np.nan, np.nan, 1, np.nan, np.nan],
168
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
169
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
170
+ ],
171
+ [
172
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
173
+ [np.nan, 1, 1, 1, np.nan],
174
+ [np.nan, 1, 1, 1, np.nan],
175
+ [np.nan, 1, 1, 1, np.nan],
176
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
177
+ ],
178
+ [
179
+ [np.nan, np.nan, 1, np.nan, np.nan],
180
+ [np.nan, 1, 1, 1, np.nan],
181
+ [1, 1, np.nan, 1, 1],
182
+ [np.nan, 1, 1, 1, np.nan],
183
+ [np.nan, np.nan, 1, np.nan, np.nan],
184
+ ],
185
+ [
186
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
187
+ [np.nan, 1, 1, 1, np.nan],
188
+ [np.nan, 1, 1, 1, np.nan],
189
+ [np.nan, 1, 1, 1, np.nan],
190
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
191
+ ],
192
+ [
193
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
194
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
195
+ [np.nan, np.nan, 1, np.nan, np.nan],
196
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
197
+ [np.nan, np.nan, np.nan, np.nan, np.nan],
198
+ ],
199
+ ]
200
+ )
201
+ # test the case where fg.space is 0
202
+ fg.applycutoff()
203
+ np.testing.assert_array_equal(fg.cube_reci, expected_ones)
204
+ np.testing.assert_array_equal(fg.cube_recicut, expected_recip)
205
+ root.destroy() # Clean up Tkinter instance
206
+
207
+ # test the case where fg.space is 1
208
+ root = tk.Tk()
209
+ fg = Gui()
210
+ # qmin of 1 and qmax of 2 is expected to leave the central pixel and corner
211
+ # pixels as NaN's
212
+ mocker.patch.object(fg.qminentry, "get", return_value=1)
213
+ mocker.patch.object(fg.qmaxentry, "get", return_value=2)
214
+ mocker.patch.object(
215
+ fg, "fft"
216
+ ) # we don't want it to do the fft so intercept. Should be tested separately (fixme).
217
+ fg.cutted = False
218
+ fg.cube_reci = np.ones((5, 5, 5))
219
+ fg.cube = np.ones((5, 5, 5))
220
+ mocker.patch.object(fg.space, "get", return_value=1)
221
+ fg.applycutoff()
222
+ np.testing.assert_array_equal(fg.cube_real, expected_ones)
223
+ np.testing.assert_array_equal(fg.cube_recicut, expected_recip)
224
+ root.destroy() # Clean up Tkinter instance
225
+
226
+
149
227
  if __name__ == "__main__":
150
228
  unittest.main()