pyrmcmon 0.1.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.
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.3
2
+ Name: pyrmcmon
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author: ccoverstreet
6
+ Author-email: ccoverstreet <cale.overstreet@gmail.com>
7
+ Requires-Dist: matplotlib>=3.10.9
8
+ Requires-Dist: pyqt6>=6.11.0
9
+ Requires-Dist: pyqtgraph>=0.14.0
10
+ Requires-Python: >=3.14
11
+ Description-Content-Type: text/markdown
12
+
File without changes
@@ -0,0 +1,21 @@
1
+ [project]
2
+ name = "pyrmcmon"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "ccoverstreet", email = "cale.overstreet@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.14"
10
+ dependencies = [
11
+ "matplotlib>=3.10.9",
12
+ "pyqt6>=6.11.0",
13
+ "pyqtgraph>=0.14.0",
14
+ ]
15
+
16
+ [project.scripts]
17
+ pyrmcmon = "pyrmcmon:__main__.main"
18
+
19
+ [build-system]
20
+ requires = ["uv_build>=0.10.9,<0.11.0"]
21
+ build-backend = "uv_build"
@@ -0,0 +1,2 @@
1
+ def main() -> None:
2
+ print("Hello from pyrmcmon!")
@@ -0,0 +1,16 @@
1
+ import sys
2
+ from PyQt6.QtWidgets import QApplication
3
+ import pyrmcmon.gui as prm
4
+
5
+
6
+
7
+
8
+ def main():
9
+ app = QApplication(sys.argv)
10
+ window = prm.MainWindow()
11
+
12
+ window.show()
13
+
14
+ app.exec()
15
+
16
+
@@ -0,0 +1,273 @@
1
+ import sys
2
+ import os
3
+
4
+ from PyQt6.QtCore import (pyqtSignal, pyqtSlot)
5
+ from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton, QLabel, QHBoxLayout, QTabWidget, QVBoxLayout, QFileDialog
6
+ import pyqtgraph as pg
7
+ from dataclasses import dataclass
8
+ import numpy as np
9
+ from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg, NavigationToolbar2QT
10
+ from matplotlib.backends.backend_qtagg import FigureCanvas
11
+ from matplotlib.figure import Figure
12
+
13
+ def get_dir_and_stem(file):
14
+ dirname = os.path.dirname(file)
15
+ stem = os.path.splitext(os.path.basename(file))[0]
16
+
17
+ return (dirname, stem)
18
+
19
+ class MainWindow(QMainWindow):
20
+ def __init__(self):
21
+ super().__init__()
22
+
23
+ self.setWindowTitle("PyRMCMon")
24
+
25
+ self.container = QWidget()
26
+
27
+ self.hbox = QHBoxLayout()
28
+
29
+ self.controls = ControlPane()
30
+ self.hbox.addWidget(self.controls)
31
+
32
+ self.tabs = QTabWidget()
33
+
34
+ self.SQTab = SQTab()
35
+ self.PartialSQTab = PartialSQTab()
36
+ self.BraggTab = BraggTab()
37
+ self.PDFTab = PDFTab()
38
+ self.PartialPDFTab = PartialPDFTab()
39
+ self.tabs.addTab(self.SQTab, "S(Q)")
40
+ self.tabs.addTab(self.PartialSQTab, "S(Q) Partials")
41
+ self.tabs.addTab(self.BraggTab, "Bragg")
42
+ self.tabs.addTab(self.PDFTab, "PDF")
43
+ self.tabs.addTab(self.PartialPDFTab, "PDF Partials")
44
+
45
+ self.hbox.addWidget(self.tabs)
46
+
47
+ self.container.setLayout(self.hbox)
48
+
49
+ self.controls.rmc_file_selected.connect(self.handle_rmc_file_selected)
50
+ self.controls.rmc_file_selected.connect(self.SQTab.plot_rmc)
51
+ self.controls.rmc_file_selected.connect(self.PartialSQTab.plot_rmc)
52
+ self.controls.rmc_file_selected.connect(self.BraggTab.plot_rmc)
53
+ self.controls.rmc_file_selected.connect(self.PDFTab.plot_rmc)
54
+ self.controls.rmc_file_selected.connect(self.PartialPDFTab.plot_rmc)
55
+
56
+ self.setCentralWidget(self.container)
57
+
58
+
59
+ @pyqtSlot(str)
60
+ def handle_rmc_file_selected(self, filename):
61
+ print(f"RMC file selected: {filename}")
62
+
63
+ class ControlPane(QWidget):
64
+ rmc_file_selected = pyqtSignal(str)
65
+
66
+ def __init__(self):
67
+ super().__init__()
68
+
69
+ self.vbox = QVBoxLayout()
70
+
71
+ self.select_button = QPushButton("Select RMC .dat file")
72
+ self.select_button.clicked.connect(self.select_rmc_dat_file)
73
+ self.vbox.addWidget(self.select_button)
74
+
75
+ self.rmc_file = ""
76
+
77
+ self.setLayout(self.vbox)
78
+
79
+ def select_rmc_dat_file(self):
80
+ file = QFileDialog.getOpenFileName(self, "Select RMC .dat file")
81
+
82
+ # No file selected
83
+ if file[0] == "":
84
+ return
85
+
86
+ self.rmc_file = file[0]
87
+ self.rmc_file_selected.emit(self.rmc_file)
88
+
89
+
90
+ class MplCanvas(FigureCanvas):
91
+ def __init__(self, parent=None, width=5, height=4, dpi=100):
92
+ fig = Figure()
93
+ self.fig = fig
94
+ self.axes = fig.add_subplot(111)
95
+ super().__init__(fig)
96
+
97
+ def update_plot(self):
98
+ self.fig.canvas.draw()
99
+ self.fig.canvas.flush_events()
100
+
101
+ class PlotWidget(QWidget):
102
+ def __init__(self):
103
+ super().__init__()
104
+
105
+ self.canvas = MplCanvas()
106
+ self.fig = self.canvas.fig
107
+ self.axes = self.canvas.axes
108
+ self.toolbar = NavigationToolbar2QT(self.canvas)
109
+
110
+ layout = QVBoxLayout()
111
+
112
+ layout.addWidget(self.toolbar)
113
+ layout.addWidget(self.canvas)
114
+ self.setLayout(layout)
115
+
116
+ def update_plot(self):
117
+ self.canvas.update_plot()
118
+
119
+ class SQTab(QWidget):
120
+ def __init__(self):
121
+ super().__init__()
122
+
123
+ self.layout = QHBoxLayout()
124
+
125
+ self.plot = PlotWidget()
126
+ self.layout.addWidget(self.plot)
127
+
128
+ self.setLayout(self.layout)
129
+
130
+ @pyqtSlot(str)
131
+ def plot_rmc(self, file):
132
+ dirname, stem = get_dir_and_stem(file)
133
+ SQ1_filename = f"{dirname}/{stem}_SQ1.csv"
134
+ self.data = np.genfromtxt(SQ1_filename, delimiter=",")
135
+
136
+ self.plot.axes.clear()
137
+ self.plot.axes.plot(self.data[:, 0], self.data[:, 2], label="Data",
138
+ color="k")
139
+ self.plot.axes.plot(self.data[:, 0], self.data[:, 1], label="RMC",
140
+ color="tab:red", ls="--")
141
+ self.plot.axes.set_xlabel(r"Q [$\AA^{-1}$]", fontsize=16)
142
+ self.plot.axes.set_ylabel(r"S(Q)", fontsize=16)
143
+ self.plot.axes.legend()
144
+
145
+ self.plot.update_plot()
146
+
147
+
148
+ class PartialSQTab(QWidget):
149
+ def __init__(self):
150
+ super().__init__()
151
+
152
+ self.layout = QHBoxLayout()
153
+
154
+ self.plot = PlotWidget()
155
+ self.layout.addWidget(self.plot)
156
+
157
+ self.setLayout(self.layout)
158
+
159
+ @pyqtSlot(str)
160
+ def plot_rmc(self, file):
161
+ dirname, stem = get_dir_and_stem(file)
162
+ filename = f"{dirname}/{stem}_SQ1partials.csv"
163
+ self.data = np.genfromtxt(filename, delimiter=",", skip_header=1)
164
+
165
+ header = []
166
+ with open(filename) as f:
167
+ for line in f:
168
+ header = line.replace("\n", "").split(",")
169
+ break
170
+
171
+ self.plot.axes.clear()
172
+
173
+ for i in range(1, len(header)):
174
+ self.plot.axes.plot(self.data[:, 0], self.data[:, i], label=header[i])
175
+
176
+ self.plot.axes.set_xlabel(r"Q [$\AA^{-1}$]", fontsize=16)
177
+ self.plot.axes.set_ylabel(r"S(Q)", fontsize=16)
178
+ self.plot.axes.legend()
179
+
180
+ self.plot.update_plot()
181
+
182
+
183
+
184
+ class BraggTab(QWidget):
185
+ def __init__(self):
186
+ super().__init__()
187
+
188
+ self.layout = QHBoxLayout()
189
+
190
+ self.plot = PlotWidget()
191
+ self.layout.addWidget(self.plot)
192
+
193
+ self.setLayout(self.layout)
194
+
195
+ @pyqtSlot(str)
196
+ def plot_rmc(self, file):
197
+ dirname, stem = get_dir_and_stem(file)
198
+ SQ1_filename = f"{dirname}/{stem}_bragg.csv"
199
+ self.data = np.genfromtxt(SQ1_filename, delimiter=",")
200
+
201
+ self.plot.axes.clear()
202
+ self.plot.axes.plot(self.data[:, 0], self.data[:, 2], label="Data",
203
+ color="k")
204
+ self.plot.axes.plot(self.data[:, 0], self.data[:, 1], label="RMC",
205
+ color="tab:red", ls="--")
206
+ self.plot.axes.set_xlabel(r"TOF or 2$\theta$", fontsize=16)
207
+ self.plot.axes.set_ylabel(r"Intensity", fontsize=16)
208
+ self.plot.axes.legend()
209
+
210
+ self.plot.update_plot()
211
+
212
+
213
+ class PDFTab(QWidget):
214
+ def __init__(self):
215
+ super().__init__()
216
+
217
+ self.layout = QHBoxLayout()
218
+
219
+ self.plot = PlotWidget()
220
+ self.layout.addWidget(self.plot)
221
+
222
+ self.setLayout(self.layout)
223
+
224
+ @pyqtSlot(str)
225
+ def plot_rmc(self, file):
226
+ dirname, stem = get_dir_and_stem(file)
227
+ filename = f"{dirname}/{stem}_PDF1.csv"
228
+ self.data = np.genfromtxt(filename, delimiter=",")
229
+
230
+ self.plot.axes.clear()
231
+ self.plot.axes.plot(self.data[:, 0], self.data[:, 2], label="Data",
232
+ color="k")
233
+ self.plot.axes.plot(self.data[:, 0], self.data[:, 1], label="RMC",
234
+ color="tab:red", ls="--")
235
+ self.plot.axes.set_xlabel(r"r [$\AA$]", fontsize=16)
236
+ self.plot.axes.set_ylabel(r"G(r), D(r), or T(r)", fontsize=16)
237
+ self.plot.axes.legend()
238
+
239
+ self.plot.update_plot()
240
+
241
+ class PartialPDFTab(QWidget):
242
+ def __init__(self):
243
+ super().__init__()
244
+
245
+ self.layout = QHBoxLayout()
246
+
247
+ self.plot = PlotWidget()
248
+ self.layout.addWidget(self.plot)
249
+
250
+ self.setLayout(self.layout)
251
+
252
+ @pyqtSlot(str)
253
+ def plot_rmc(self, file):
254
+ dirname, stem = get_dir_and_stem(file)
255
+ filename = f"{dirname}/{stem}_PDFpartials.csv"
256
+ self.data = np.genfromtxt(filename, delimiter=",", skip_header=1)
257
+
258
+ header = []
259
+ with open(filename) as f:
260
+ for line in f:
261
+ header = line.replace("\n", "").split(",")
262
+ break
263
+
264
+ self.plot.axes.clear()
265
+
266
+ for i in range(1, len(header)):
267
+ self.plot.axes.plot(self.data[:, 0], self.data[:, i], label=header[i])
268
+
269
+ self.plot.axes.set_xlabel(r"r [$\AA$]", fontsize=16)
270
+ self.plot.axes.set_ylabel(r"G(r), D(r), or T(r)", fontsize=16)
271
+ self.plot.axes.legend()
272
+
273
+ self.plot.update_plot()