rubycond_of 0.2.0__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.
@@ -0,0 +1,881 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+
4
+ Title: OF_View: tool for opening data files in the most common formats
5
+
6
+ This file is part of Rubycond: Pressure by Ruby Luminescence (PRL) software to determine pressure in diamond anvil cell experiments.
7
+
8
+ Version 0.2.0
9
+ Release 260301
10
+
11
+ Author:
12
+
13
+ Yiuri Garino
14
+ yiuri.garino@cnrs.fr
15
+
16
+ Copyright (c) 2023-2026 Yiuri Garino
17
+
18
+ Download:
19
+ https://github.com/CelluleProjet/Rubycond_OF
20
+
21
+ License: GPLv3
22
+
23
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
24
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
25
+ You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
26
+
27
+ """
28
+
29
+ def reset():
30
+ import sys
31
+
32
+ if hasattr(sys, 'ps1'):
33
+
34
+ #clean Console and Memory
35
+ from IPython import get_ipython
36
+ get_ipython().run_line_magic('clear','/')
37
+ get_ipython().run_line_magic('reset','-sf')
38
+ print("Running interactively")
39
+ print()
40
+ terminal = False
41
+ else:
42
+ print("Running in terminal")
43
+ print()
44
+ terminal = True
45
+
46
+ if __name__ == '__main__':
47
+ reset()
48
+
49
+ import configparser as cp
50
+ from pathlib import Path
51
+ import numpy as np
52
+ import matplotlib.pyplot as plt
53
+ from matplotlib.lines import Line2D
54
+ from matplotlib.backend_bases import MouseEvent
55
+ from datetime import datetime
56
+ import sys
57
+ import os
58
+
59
+ try:
60
+ from StringIO import StringIO
61
+ except ImportError:
62
+ from io import StringIO
63
+
64
+ from PyQt5 import QtWidgets, QtCore, QtGui
65
+ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
66
+ from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
67
+
68
+ import traceback
69
+
70
+ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
71
+
72
+ class Data_Table(QtWidgets.QTableWidget):
73
+ def __init__(self, model, debug = False):
74
+ super().__init__()
75
+ self.__name__ = 'Rubycond Open File View'
76
+ self.__version__ = '0.2.0'
77
+ self.__release__ = '260301'
78
+ self.model = model
79
+ self.debug = debug
80
+ if self.debug : print('\nData_Table\n')
81
+
82
+ self.setColumnCount(5)
83
+ self.setRowCount(5)
84
+ layout = QtWidgets.QVBoxLayout()
85
+ layout.addWidget(self)
86
+
87
+ def error_box(self, title):
88
+ msgBox = QtWidgets.QMessageBox()
89
+ msgBox.setIcon(QtWidgets.QMessageBox.Critical)
90
+ msgBox.setWindowTitle(str(title))
91
+ msgBox.setText(traceback.format_exc())
92
+ msgBox.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
93
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
94
+ msgBox.exec()
95
+
96
+ def reset(self):
97
+ tot = self.rowCount()
98
+ for i in range(tot+1):
99
+ self.removeColumn(i)
100
+
101
+ def set_numpy_2D(self, data):
102
+ try:
103
+ self.clear()
104
+ row, col = data.shape
105
+ self.model.table_row = row
106
+ self.model.table_col = col
107
+ self.setColumnCount(col)
108
+ self.setRowCount(row)
109
+ for i_r in range(row):
110
+ for i_c in range(col):
111
+ self.setItem(i_r, i_c, QtWidgets.QTableWidgetItem(f'{data[i_r,i_c]:.2f}'))
112
+ except Exception:
113
+ self.error_box('Data_Table set_numpy_2D')
114
+
115
+ def set_str_2D(self, data):
116
+ try:
117
+ self.clear()
118
+ row, col = data.shape
119
+ self.model.table_row = row
120
+ self.model.table_col = col
121
+ self.setColumnCount(col)
122
+ self.setRowCount(row)
123
+ for i_r in range(row):
124
+ for i_c in range(col):
125
+ self.setItem(i_r, i_c, QtWidgets.QTableWidgetItem(data[i_r,i_c]))
126
+ except Exception:
127
+ self.error_box('Data_Table set_str_2D')
128
+
129
+ class show_text_file(QtWidgets.QFrame):
130
+ def __init__(self, filename, debug = False):
131
+ super().__init__()
132
+
133
+
134
+ self.setWindowTitle(f'file = {str(filename)}')
135
+ try:
136
+
137
+ text_edit = QtWidgets.QPlainTextEdit()
138
+ text=open(filename).read()
139
+ text_edit.setPlainText(text)
140
+
141
+ #Final layout
142
+
143
+ layout = QtWidgets.QVBoxLayout()
144
+ layout.addWidget(text_edit)
145
+
146
+ self.setLayout(layout)
147
+
148
+ self.setSizePolicy(
149
+ QtWidgets.QSizePolicy.Fixed,
150
+ QtWidgets.QSizePolicy.Fixed)
151
+ except Exception:
152
+ self.error_box('Show text file error')
153
+
154
+ def error_box(self, title):
155
+ msgBox = QtWidgets.QMessageBox()
156
+ msgBox.setIcon(QtWidgets.QMessageBox.Critical)
157
+ msgBox.setWindowTitle(str(title))
158
+ msgBox.setText(traceback.format_exc())
159
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
160
+ msgBox.exec()
161
+
162
+ class open_file_commands(QtWidgets.QFrame):
163
+
164
+ signal_plot_data = QtCore.pyqtSignal(np.ndarray)
165
+ #signal_add_plot = QtCore.pyqtSignal(np.ndarray)
166
+ signal_fill_float_table = QtCore.pyqtSignal(np.ndarray)
167
+ signal_fill_str_table = QtCore.pyqtSignal(np.ndarray)
168
+
169
+ signal_selected_data_all = QtCore.pyqtSignal(np.ndarray, str)
170
+ signal_selected_data_xy = QtCore.pyqtSignal(np.ndarray, np.ndarray, str)
171
+
172
+
173
+
174
+ signal_quit = QtCore.pyqtSignal()
175
+
176
+ def __init__(self, model, debug = False, about = None):
177
+ super().__init__()
178
+ self.model = model
179
+ self.debug = debug
180
+ self.about = about
181
+
182
+ if self.debug : print('\nopen_file_commands\n')
183
+
184
+ self.file_data = None
185
+ self.file_data_i_x = 0 #Default value X data = column 0
186
+ self.file_data_i_y = 1 #Default value Y data = column 1
187
+ self.flag_custom_file = False
188
+ self.loadtxt_comments = ['#', '"']
189
+ self.loadtxt_delimiter = r' '
190
+ self.loadtxt_skiprows = 0
191
+
192
+ self.max_width = 300
193
+
194
+ self.label_decimal = QtWidgets.QLabel(self)
195
+ self.label_decimal.setText('Decimal separator')
196
+
197
+ #(['Decimal separator = point .', 'Decimal separator = comma ,'])
198
+
199
+ self.combobox_decimal_separator = QtWidgets.QComboBox()
200
+ self.combobox_decimal_separator.addItems(['point .', 'comma ,'])
201
+ self.combobox_decimal_separator.currentIndexChanged.connect(self.combobox_decimal_separator_index_changed)
202
+
203
+ self.button_Open_npy = QtWidgets.QPushButton("Open numpy (npy)")
204
+ self.button_Open_npy.clicked.connect(self.open_data_File_npy)
205
+
206
+ self.button_Open_csv = QtWidgets.QPushButton("Open comma delimiter (csv)")
207
+ self.button_Open_csv.clicked.connect(self.open_data_File_csv)
208
+
209
+ self.button_Open_dat = QtWidgets.QPushButton("Open space/tab delimiter (txt, dat)")
210
+ self.button_Open_dat.clicked.connect(self.open_data_File_dat)
211
+
212
+ #self.button_Open_tab = QtWidgets.QPushButton("Open tab delimiter")
213
+ #self.button_Open_tab.clicked.connect(self.open_data_File_tab)
214
+
215
+ self.button_Show_preview = QtWidgets.QPushButton("Show plain text")
216
+ self.button_Show_preview.clicked.connect(self.open_Show_preview)
217
+
218
+ self.button_Open_custom = QtWidgets.QPushButton("Open")
219
+ self.button_Open_custom.clicked.connect(self.open_data_File_custom)
220
+
221
+
222
+ self.label_comments = QtWidgets.QLabel(self)
223
+ self.label_comments.setText('Commented lines (ch)')
224
+
225
+ self.label_delimiter = QtWidgets.QLabel(self)
226
+ self.label_delimiter.setText('Columns delimiter')
227
+
228
+ self.label_skiprows = QtWidgets.QLabel(self)
229
+ self.label_skiprows.setText('Skip first (n) lines')
230
+
231
+
232
+ self.button_about = QtWidgets.QPushButton("About Open File")
233
+ self.button_about.clicked.connect(self.open_about)
234
+
235
+ _ =''
236
+ for i in self.loadtxt_comments:
237
+ _ = _ + i
238
+ self.open_button_comments = QtWidgets.QPushButton(_)
239
+ self.open_button_comments.clicked.connect(self.command_button_comments)
240
+
241
+ '''ComboBox better ?
242
+ self.label_loadtxt_delimiter = QtWidgets.QLineEdit(self, placeholderText=self.loadtxt_delimiter,
243
+ clearButtonEnabled=True)
244
+ #self.label_loadtxt_delimiter.returnPressed.connect(self.change_loadtxt_delimiter)
245
+ '''
246
+
247
+ self.combobox_loadtxt_delimiter = QtWidgets.QComboBox()
248
+ self.combobox_loadtxt_delimiter.addItems(['space', 'tab', 'comma ,', 'semicolon ;'])
249
+ self.combobox_loadtxt_delimiter.currentIndexChanged.connect(self.combobox_loadtxt_delimiter_index_changed)
250
+
251
+ #self.label_loadtxt_skiprows = QtWidgets.QLineEdit(self, placeholderText=str(self.loadtxt_skiprows),clearButtonEnabled=True)
252
+ #self.label_loadtxt_skiprows.returnPressed.connect(self.change_loadtxt_skiprows)
253
+ #Plot Commands
254
+
255
+ self.open_button_skiprows = QtWidgets.QPushButton("0")
256
+ self.open_button_skiprows.clicked.connect(self.command_button_skiprows)
257
+
258
+ self.open_button_skiprows
259
+
260
+ self.button_Plot_data = QtWidgets.QPushButton("Plot")
261
+ #self.button_Plot_data.clicked.connect(self.open_data_File_custom)
262
+
263
+ self.label_plot_x = QtWidgets.QLabel(self)
264
+ self.label_plot_x.setText('X Data')
265
+
266
+ self.combobox_Plot_data_column_x = QtWidgets.QComboBox()
267
+
268
+ self.label_plot_y = QtWidgets.QLabel(self)
269
+ self.label_plot_y.setText('Y Data')
270
+
271
+ self.combobox_Plot_data_column_y = QtWidgets.QComboBox()
272
+
273
+ self.button_Delete_plot = QtWidgets.QPushButton("Delete")
274
+ #self.button_Delete_plot.clicked.connect(self.open_data_File_custom)
275
+
276
+ self.combobox_button_Delete_plot = QtWidgets.QComboBox()
277
+
278
+ #Accept Close Commands
279
+ self.button_Accept = QtWidgets.QPushButton("Accept")
280
+ self.button_Accept.setStyleSheet("background-color: limegreen"); #lightgreen
281
+ self.button_Accept.clicked.connect(self.app_accept_quit)
282
+
283
+ self.combobox_Accept_data_column_x = QtWidgets.QComboBox()
284
+ self.combobox_Accept_data_column_y = QtWidgets.QComboBox()
285
+
286
+ self.button_Cancel = QtWidgets.QPushButton("Cancel")
287
+ self.button_Cancel.setStyleSheet("background-color: red");
288
+ self.button_Cancel.clicked.connect(self.app_quit)
289
+
290
+
291
+
292
+ Widget_Open = QtWidgets.QWidget()
293
+ Widget_Open.setMaximumWidth(self.max_width)
294
+ Widget_Open.setObjectName('Widget_Open')
295
+ Widget_Open.setStyleSheet("#Widget_Open {border: 2px solid green; border-radius: 10px;}")
296
+
297
+ layout_Open = QtWidgets.QGridLayout(Widget_Open)
298
+
299
+ layout_Open.addWidget(self.label_decimal, 0, 1)
300
+ layout_Open.addWidget(self.combobox_decimal_separator, 0, 2)
301
+
302
+
303
+ #layout_Open.addWidget(self.button_Open_csv, 2, 1)
304
+ #layout_Open.addWidget(self.button_Open_dat, 3, 1)
305
+
306
+ layout_Open.addWidget(self.label_comments, 1, 1)
307
+ layout_Open.addWidget(self.label_delimiter, 2, 1)
308
+ layout_Open.addWidget(self.label_skiprows, 3, 1)
309
+
310
+
311
+
312
+ #layout_Open.addWidget(self.label_loadtxt_comments, 1, 2)
313
+ layout_Open.addWidget(self.open_button_comments, 1, 2)
314
+ layout_Open.addWidget(self.combobox_loadtxt_delimiter, 2, 2)
315
+ layout_Open.addWidget(self.open_button_skiprows, 3, 2)
316
+
317
+ layout_Open.addWidget(self.button_Open_custom, 4, 1)
318
+
319
+ Widget_numpy = QtWidgets.QWidget()
320
+ Widget_numpy.setMaximumWidth(self.max_width)
321
+ Widget_numpy.setObjectName('Widget_numpy')
322
+ Widget_numpy.setStyleSheet("#Widget_numpy {border: 2px solid green; border-radius: 10px;}")
323
+
324
+ layout_numpy = QtWidgets.QGridLayout(Widget_numpy)
325
+ layout_numpy.addWidget(self.button_Open_npy, 1, 1)
326
+
327
+ Widget_text = QtWidgets.QWidget()
328
+ Widget_text.setMaximumWidth(self.max_width)
329
+ Widget_text.setObjectName('Widget_Text')
330
+ Widget_text.setStyleSheet("#Widget_Text {border: 2px solid black; border-radius: 10px;}")
331
+
332
+ layout_text = QtWidgets.QGridLayout(Widget_text)
333
+ layout_text.addWidget(self.button_Show_preview, 0, 1)
334
+
335
+ # Widget_Custom = QtWidgets.QWidget()
336
+ # Widget_Custom.setMaximumWidth(self.max_width)
337
+ # Widget_Custom.setObjectName('Widget_Custom')
338
+ # Widget_Custom.setStyleSheet("#Widget_Custom {border: 2px solid green; border-radius: 10px;}")
339
+
340
+ # layout_Custom = QtWidgets.QGridLayout(Widget_Custom)
341
+
342
+ # layout_Custom.addWidget(self.label_comments, 1, 1)
343
+ # layout_Custom.addWidget(self.label_delimiter, 2, 1)
344
+ # layout_Custom.addWidget(self.label_skiprows, 3, 1)
345
+ # layout_Custom.addWidget(self.button_Open_custom, 4, 1)
346
+
347
+
348
+ # layout_Custom.addWidget(self.label_loadtxt_comments, 1, 2)
349
+ # layout_Custom.addWidget(self.combobox_loadtxt_delimiter, 2, 2)
350
+ # layout_Custom.addWidget(self.label_loadtxt_skiprows, 3, 2)
351
+
352
+ #Plot Widget
353
+ Widget_Plot = QtWidgets.QWidget()
354
+ Widget_Plot.setMaximumWidth(self.max_width)
355
+ Widget_Plot.setObjectName('Widget_Close')
356
+ Widget_Plot.setStyleSheet("#Widget_Close {border: 2px solid blue; border-radius: 10px;}")
357
+
358
+ layout_Plot = QtWidgets.QGridLayout(Widget_Plot)
359
+ layout_Plot.addWidget(self.button_Plot_data, 1, 1)
360
+ layout_Plot.addWidget(self.label_plot_x, 2, 1)
361
+ layout_Plot.addWidget(self.label_plot_y, 3, 1)
362
+ layout_Plot.addWidget(self.combobox_Plot_data_column_x, 2, 2)
363
+ layout_Plot.addWidget(self.combobox_Plot_data_column_y, 3, 2)
364
+ layout_Plot.addWidget(self.button_Delete_plot, 4, 1)
365
+ layout_Plot.addWidget(self.combobox_button_Delete_plot, 4, 2)
366
+
367
+ #Accept Close Widget
368
+ Widget_Close = QtWidgets.QWidget()
369
+ Widget_Close.setMaximumWidth(self.max_width)
370
+ Widget_Close.setObjectName('Widget_Close')
371
+ Widget_Close.setStyleSheet("#Widget_Close {border: 2px solid blue; border-radius: 10px;}")
372
+
373
+ layout_Close = QtWidgets.QGridLayout(Widget_Close)
374
+ layout_Close.addWidget(self.button_Accept, 1, 1)
375
+ layout_Close.addWidget(self.combobox_Accept_data_column_x, 1, 2)
376
+ layout_Close.addWidget(self.combobox_Accept_data_column_y, 1, 3)
377
+ layout_Close.addWidget(self.button_Cancel, 2, 1, 1, 3) #, columnSpan = 3)
378
+
379
+ #About Widget
380
+ Widget_About = QtWidgets.QWidget()
381
+ Widget_About.setMaximumWidth(self.max_width)
382
+ Widget_About.setObjectName('Widget_About')
383
+ #Widget_About.setStyleSheet("#Widget_Close {border: 2px solid blue; border-radius: 10px;}")
384
+
385
+ layout_About = QtWidgets.QGridLayout(Widget_About)
386
+ layout_About.addWidget(self.button_about, 1, 1)
387
+
388
+ #Final layout
389
+
390
+ layout_controls = QtWidgets.QVBoxLayout()
391
+
392
+ layout_controls.addWidget(Widget_About)
393
+ layout_controls.addWidget(Widget_text)
394
+ layout_controls.addWidget(Widget_Open)
395
+ #layout_controls.addWidget(Widget_Custom)
396
+ layout_controls.addWidget(Widget_numpy)
397
+
398
+ layout_controls.addWidget(Widget_Plot)
399
+ layout_controls.addWidget(Widget_Close)
400
+
401
+ layout_controls.setAlignment(QtCore.Qt.AlignTop)
402
+ # layout_controls = QtWidgets.QVBoxLayout()
403
+
404
+ # layout_controls.addWidget(button_Open_csv)
405
+ # layout_controls.addWidget(button_Open_dat)
406
+ # layout_controls.addWidget(button_Open_custom)
407
+ # #layout_controls.addWidget(self.combo)
408
+
409
+ # layout_controls.addWidget(button_Accept)
410
+ # layout_controls.addWidget(button_Cancel)
411
+ # layout_controls.setAlignment(QtCore.Qt.AlignTop)
412
+
413
+ self.setLayout(layout_controls)
414
+
415
+ self.setSizePolicy(
416
+ QtWidgets.QSizePolicy.Fixed,
417
+ QtWidgets.QSizePolicy.Fixed)
418
+
419
+ def open_about(self):
420
+ if self.about is not None:
421
+ self.about.show()
422
+
423
+ def command_button_comments(self):
424
+ title = 'New comment character'
425
+ label = 'The characters or list of characters used to indicate the start of a comment'
426
+
427
+ new_value, ok = QtWidgets.QInputDialog.getText(self, title, label)
428
+ if ok:
429
+ self.loadtxt_comments = list(new_value)
430
+ self.open_button_comments.setText(new_value)
431
+ self.model.statusbar_message('Commented lines (ch) = ' + '|'.join(self.loadtxt_comments))
432
+
433
+ def command_button_skiprows(self):
434
+ title = 'New skip lines number'
435
+ label = 'Skip the first n lines, including comments'
436
+
437
+ new_value, ok = QtWidgets.QInputDialog.getInt(self, title, label, self.loadtxt_skiprows, 0)
438
+ if ok:
439
+ self.loadtxt_skiprows = new_value
440
+ self.open_button_skiprows.setText(str(new_value))
441
+ self.model.statusbar_message('Skip the first ' + str(self.loadtxt_skiprows0 + ' lines, including comments'))
442
+
443
+ def error_box(self, title : str):
444
+ msgBox = QtWidgets.QMessageBox()
445
+ msgBox.setIcon(QtWidgets.QMessageBox.Critical)
446
+ msgBox.setWindowTitle(str(title))
447
+ msgBox.setText(traceback.format_exc())
448
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
449
+ msgBox.exec()
450
+
451
+ def error_message(self, title : str, error : str):
452
+ msgBox = QtWidgets.QMessageBox()
453
+ msgBox.setIcon(QtWidgets.QMessageBox.Critical)
454
+ msgBox.setWindowTitle(title)
455
+ msgBox.setText(error)
456
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
457
+ msgBox.exec()
458
+
459
+ def open_Show_preview(self):
460
+ self.fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select File")
461
+ if self.fileName:
462
+ self.model.statusbar_message(message = "Open plain text")
463
+ self.show_text_file = show_text_file(self.fileName)
464
+ self.show_text_file.show()
465
+
466
+ def combobox_loadtxt_delimiter_index_changed(self):
467
+ index = self.combobox_decimal_separator.currentIndex()
468
+ # if index = 0:
469
+ # self.loadtxt_delimiter
470
+ # elif index == 1 :
471
+ # ['space', 'tab', 'comma ,', 'semicolon ;']
472
+
473
+ #setItemText
474
+
475
+ def combobox_decimal_separator_index_changed(self):
476
+ index = self.combobox_decimal_separator.currentIndex()
477
+ if self.debug : print(f'combobox_decimal_separator = {index}')
478
+ if index == 0: # point .
479
+ self.button_Open_csv.setText("Open comma delimiter (csv)")
480
+ self.model.statusbar_message(message = "'Decimal separator = point .")
481
+ self.combobox_loadtxt_delimiter.setItemText(2, 'comma ,')
482
+ elif index == 1: # comma ,
483
+ self.button_Open_csv.setText("Open semicolon delimiter (csv)")
484
+ self.model.statusbar_message(message = "'Decimal separator = comma ,")
485
+ self.combobox_loadtxt_delimiter.setItemText(2, 'point .')
486
+
487
+ def open_data_File_csv(self):
488
+
489
+ index = self.combobox_decimal_separator.currentIndex()
490
+ if self.debug : print('open_data_File_csv')
491
+ if index == 0: # point .
492
+ self.open_data_File(delimiter=',')
493
+ self.model.statusbar_message(message = "Open comma delimiter (csv)")
494
+ elif index == 1: # comma ,
495
+ self.open_data_File(delimiter=';')
496
+ self.model.statusbar_message(message = "Open semicolon delimiter (csv)")
497
+
498
+
499
+
500
+ def change_loadtxt_skiprows(self):
501
+ try :
502
+ text = self.label_loadtxt_skiprows.text()
503
+ self.loadtxt_skiprows = int(text)
504
+ self.model.statusbar_message('Skip first (n) lines = ' + self.label_loadtxt_skiprows.text())
505
+ self.label_loadtxt_skiprows.setPlaceholderText(text)
506
+
507
+
508
+ except Exception:
509
+ self.model.error_box('open_file_commands change_loadtxt_skiprows')
510
+ self.model.statusbar_message('Skip first (n) lines = ' + self.loadtxt_skiprows)
511
+
512
+ def change_loadtxt_comments(self):
513
+
514
+ try :
515
+ text = self.label_loadtxt_comments.text()
516
+ self.loadtxt_comments = text
517
+ message='Commented lines (ch) = '
518
+ for i in text:
519
+ message = message + i
520
+ self.model.statusbar_message(message)
521
+ self.label_loadtxt_comments.setPlaceholderText(text)
522
+
523
+
524
+ except Exception:
525
+ self.model.error_box('open_file_commands change_loadtxt_comments')
526
+ self.model.statusbar_message('invalid value, Commented lines (ch) =' + self.loadtxt_comments)
527
+
528
+ def print_time(self, event = None, Message = 'Now = '):
529
+ now = datetime.now()
530
+ current_time = now.strftime("%A %d %B %Y %H:%M:%S")
531
+ print(Message + current_time)
532
+
533
+ def open_data_File_custom(self):
534
+ self.flag_custom_file = True
535
+
536
+ self.fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select File")
537
+ try:
538
+
539
+ if self.fileName:
540
+ if self.debug: print(self.fileName)
541
+
542
+ loadtxt_delimiter = self.combobox_loadtxt_delimiter.currentText()
543
+ #['space', 'tab', 'comma ,', 'semicolon ;']
544
+
545
+ if loadtxt_delimiter == 'space':
546
+ self.loadtxt_delimiter = ' '
547
+ elif loadtxt_delimiter == 'tab' :
548
+ self.loadtxt_delimiter = '\t'
549
+ elif loadtxt_delimiter == 'comma ,' :
550
+ self.loadtxt_delimiter = ','
551
+ elif loadtxt_delimiter == 'semicolon ;' :
552
+ self.loadtxt_delimiter = ';'
553
+ elif loadtxt_delimiter == 'point .':
554
+ self.loadtxt_delimiter = '.'
555
+
556
+ index = self.combobox_decimal_separator.currentIndex()
557
+
558
+
559
+ # if index == 0: # point .
560
+ # s = self.fileName
561
+ # elif index == 1: # comma ,
562
+ # s = open(self.fileName).read().replace(',','.')
563
+ #if self.debug:
564
+
565
+ if self.debug: print(f'delim = {loadtxt_delimiter} = |{self.loadtxt_delimiter}| decimal = |{index}|0=. 1=,')
566
+ _ = ''
567
+ for i in self.loadtxt_delimiter:
568
+ _ = _ + i
569
+ if self.debug: print(f'comments = {self.loadtxt_comments} delim = {_} skip = {self.loadtxt_skiprows}')
570
+ message = f'comments = {self.loadtxt_comments} delim = {self.loadtxt_delimiter} skip = {self.loadtxt_skiprows}'
571
+ self.model.statusbar_message(message)
572
+
573
+ self.file_data = np.loadtxt(self.fileName, dtype = str,
574
+ comments = self.loadtxt_comments,
575
+ delimiter = self.loadtxt_delimiter,
576
+ skiprows = self.loadtxt_skiprows)
577
+ if self.debug: print(self.file_data)
578
+ # print(self.loadtxt_comments)
579
+ # print(self.loadtxt_delimiter)
580
+ # print(self.loadtxt_skiprows)
581
+ # print(len(self.file_data.shape))
582
+
583
+ if len(self.file_data.shape) == 2:
584
+ self.signal_fill_str_table.emit(self.file_data)
585
+ try:
586
+ a = self.file_data[:,0].astype(float)
587
+ b = self.file_data[:,1].astype(float)
588
+ c = np.column_stack((a,b))
589
+ self.signal_plot_data.emit(c)
590
+ except:
591
+ self.error_message('column 1 or column 2 contains text that cannot be converted to numbers')
592
+ else:
593
+ self.error_message('Open data file error', 'Data must be in a 2D format, at least 2 lines 2 columns')
594
+
595
+ except Exception:
596
+ self.error_box('open_file_commands open_data_File_custom')
597
+
598
+ def open_data_File_npy(self, delimiter = ''):
599
+ self.model.statusbar_message(message = "Open numpy npy")
600
+ self.fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select File", filter = "numpy files (*.npy)")
601
+ try:
602
+ if self.fileName:
603
+ if self.debug: print(self.fileName)
604
+ self.file_data= np.load(self.fileName)
605
+
606
+ if len(self.file_data.shape) == 2:
607
+ self.signal_plot_data.emit(self.file_data)
608
+ self.signal_fill_float_table.emit(self.file_data)
609
+ else:
610
+ self.error_message('Open numpy data file error', 'Data must be in a 2D format, at least 2 lines 2 columns')
611
+
612
+ except Exception:
613
+ self.error_box('open_file_commands open_data_File_npy')
614
+
615
+
616
+ def open_data_File(self, delimiter = ''):
617
+ self.flag_custom_file = False
618
+ self.fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select File")
619
+ try:
620
+ if self.fileName:
621
+ index = self.combobox_decimal_separator.currentIndex()
622
+ if index == 0: # point .
623
+ self.file_data= np.loadtxt(self.fileName, delimiter = delimiter)
624
+ elif index == 1: # comma ,
625
+ s = open(self.fileName).read().replace(',','.')
626
+ self.file_data= np.loadtxt(StringIO(s), delimiter = delimiter)
627
+
628
+ if len(self.file_data.shape) == 2:
629
+ self.signal_plot_data.emit(self.file_data)
630
+ self.signal_fill_float_table.emit(self.file_data)
631
+ else:
632
+ self.error_message('Open data file error', 'Data must be in a 2D format, at least 2 lines 2 columns')
633
+
634
+ if self.debug: print(self.fileName)
635
+ if self.debug: print(self.file_data)
636
+ except Exception:
637
+ self.error_box('open_file_commands open_data_File')
638
+
639
+
640
+
641
+ def open_data_File_dat(self):
642
+ self.model.statusbar_message(message = "Open space delimiter")
643
+ self.open_data_File(delimiter= None)
644
+
645
+ def open_data_File_tab(self):
646
+ self.model.statusbar_message(message = "Open tab delimiter")
647
+ self.open_data_File(delimiter='\t')
648
+
649
+
650
+ def data_to_model(self, data):
651
+ #Data to model
652
+ self.model.ndarray_from_file = self.ndarray_from_file
653
+ self.model.x_data_from_file = self.ndarray_from_file[:,0]
654
+ self.model.x_data_from_file = self.ndarray_from_file[:,1]
655
+
656
+ def app_quit(self):
657
+ self.signal_quit.emit()
658
+
659
+ def app_accept_quit(self):
660
+
661
+ file_data_i_x = self.combobox_Accept_data_column_x.currentIndex()
662
+ file_data_i_y = self.combobox_Accept_data_column_y.currentIndex()
663
+ print(file_data_i_x)
664
+ print(file_data_i_y)
665
+ try:
666
+ if self.file_data is not None:
667
+ self.file_data = self.file_data.astype(float)
668
+ file_data_i_x = self.combobox_Accept_data_column_x.currentIndex()
669
+ file_data_i_y = self.combobox_Accept_data_column_y.currentIndex()
670
+ try:
671
+ file_data_x = self.file_data[:, file_data_i_x].astype(float)
672
+ file_data_y = self.file_data[:, file_data_i_y].astype(float)
673
+ self.signal_selected_data_all.emit(self.file_data, self.fileName)
674
+ self.signal_selected_data_xy.emit(file_data_x, file_data_y, self.fileName)
675
+ self.signal_quit.emit()
676
+ except:
677
+ print('error')
678
+ choice = QtWidgets.QMessageBox.question(self, "Quit", "Data conversion to numbers failed, exit without data?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
679
+ QtWidgets.QMessageBox()
680
+ if choice == QtWidgets.QMessageBox.Yes:
681
+ self.signal_quit.emit()
682
+ self.signal_selected_data_all.emit(self.file_data, self.fileName)
683
+ else:
684
+ self.signal_quit.emit()
685
+ except Exception:
686
+ self.error_box('open_file_commands app_accept_quit')
687
+
688
+ class Frame_1_graph(QtWidgets.QFrame):
689
+
690
+ signal_fig_on_click = QtCore.pyqtSignal(MouseEvent)
691
+ signal_fig_click_no_drag = QtCore.pyqtSignal(MouseEvent)
692
+ signal_fig_click_drag = QtCore.pyqtSignal(MouseEvent)
693
+
694
+ def __init__(self, model, debug = False):
695
+
696
+ super().__init__()
697
+ self.model = model
698
+ self.debug = debug
699
+ if self.debug: print("\nDebug mode\n")
700
+ if self.debug: self.setStyleSheet("border: 20px solid red")
701
+
702
+ layout = QtWidgets.QVBoxLayout()
703
+
704
+ self.fig_ref = [] #List of plot ref
705
+ self.fig_ref_names = [] #List of plot names
706
+ self.x_min_all = np.inf
707
+ self.x_max_all = -np.inf
708
+ self.y_min_all = np.inf
709
+ self.y_max_all = -np.inf
710
+ self.total_plot_n = 0
711
+
712
+ self.fig = plt.figure(figsize=(5, 5))
713
+ self.canvas = FigureCanvas(self.fig)
714
+ self.canvas.mpl_connect('button_press_event', self.on_click)
715
+ self.canvas.mpl_connect('button_release_event', self.off_click)
716
+
717
+ self.navigationToolbar = NavigationToolbar(self.canvas, self, coordinates=True)
718
+ self.ax = self.fig.add_subplot(111)
719
+ self.ax.grid()
720
+ self.x_moving_ref_left = 0 #Ref to detect drag
721
+ self.y_moving_ref_left = 0 #Ref to detect drag
722
+ #self.navigationToolbar.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
723
+
724
+ # show canvas
725
+ self.canvas.show()
726
+
727
+ # create main layout
728
+
729
+ layout.addWidget(self.canvas)
730
+ layout.addWidget(self.navigationToolbar)
731
+
732
+ self.setLayout(layout)
733
+
734
+ self.plot_ref = None
735
+ self.data_x = None
736
+ self.data_y = None
737
+ self.plot_simple_calib_ref = None
738
+
739
+ def error_box(self, title):
740
+ msgBox = QtWidgets.QMessageBox()
741
+ msgBox.setIcon(QtWidgets.QMessageBox.Critical)
742
+ msgBox.setWindowTitle(str(title))
743
+ msgBox.setText(traceback.format_exc())
744
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
745
+ msgBox.exec()
746
+
747
+ def on_click(self, event):
748
+ if self.debug: print('on_click')
749
+ self.x_moving_ref_left = event.xdata
750
+ self.y_moving_ref_left = event.ydata
751
+ self.signal_fig_on_click.emit(event)
752
+
753
+ def off_click(self, event):
754
+ if self.debug: print('off_click')
755
+ _x = event.xdata
756
+ _y = event.ydata
757
+ not_moved = ((self.x_moving_ref_left == _x) and (self.y_moving_ref_left == _y))
758
+ if not_moved:
759
+ self.signal_fig_click_no_drag.emit(event)
760
+ else:
761
+ self.signal_fig_click_drag.emit(event)
762
+
763
+ def reset(self):
764
+ self.ax.cla()
765
+ self.fig_ref = []
766
+ self.fig_ref_names = []
767
+ self.total_plot_n = 0
768
+
769
+ def plot_data(self, data):
770
+ self.reset()
771
+
772
+ self.data_x = data[:,0]
773
+ self.data_y = data[:,1]
774
+
775
+ self.ax.grid()
776
+ plot_label = 'Col_X 1 Col_Y 2'
777
+ ref, = self.ax.plot(self.data_x, self.data_y, '-o', label = plot_label)
778
+ self.total_plot_n+= 1
779
+ self.fig_ref.append(ref)
780
+ self.fig_ref_names.append(plot_label)
781
+ leg = self.ax.legend()
782
+ leg.set_draggable(True)
783
+ self.canvas.draw()
784
+
785
+ def delete_plot(self, element):
786
+ try:
787
+ if self.debug: print(f'pop {element}')
788
+ _ = self.fig_ref.pop(element)
789
+ _.remove()
790
+ self.fig_ref_names.pop(element)
791
+ leg = self.ax.legend()
792
+ leg.set_draggable(True)
793
+ self.autoscale_ax()
794
+ self.canvas.draw()
795
+ except Exception:
796
+ self.error_box('Frame_1_graph delete_plot')
797
+
798
+ def add_plot(self, data_x, data_y = None, plot_label = None):
799
+ if data_y is None:
800
+ data_y = data_x[:,1]
801
+ data_x = data_x[:,0]
802
+ i = self.total_plot_n
803
+ #plot_label = f'Plot {i}'
804
+ self.total_plot_n+= 1
805
+ ref, = self.ax.plot(data_x, data_y, '-o', label = plot_label)
806
+ self.fig_ref.append(ref)
807
+ self.fig_ref_names.append(plot_label)
808
+
809
+ leg = self.ax.legend()
810
+ leg.set_draggable(True)
811
+ self.autoscale_ax()
812
+ self.canvas.draw()
813
+
814
+ def autoscale_ax(self):
815
+ try:
816
+ border = 0.1
817
+ max_x = -np.inf
818
+ max_y = -np.inf
819
+ min_x = np.inf
820
+ min_y = np.inf
821
+ lines = self.ax.get_lines()
822
+ for line in lines:
823
+ x_data = line.get_xdata()
824
+ y_data = line.get_ydata()
825
+ max_x = max(max_x, x_data.max())
826
+ max_y = max(max_y, y_data.max())
827
+ min_x = min(min_x, x_data.min())
828
+ min_y = min(min_y, y_data.min())
829
+
830
+ border_x = (max_x - min_x)*border/2
831
+ border_y = (max_y - min_y)*border/2
832
+ self.ax.set_xlim(min_x-border_x, max_x+border_x)
833
+ self.ax.set_ylim(min_y-border_y, max_y+border_y)
834
+ except:
835
+ #No graph, do nothing
836
+ pass
837
+
838
+ def rescale_xy(self, event = None):
839
+ x_min = self.x_min_all
840
+ x_max = self.x_max_all
841
+ x_range = (x_max -x_min)*0.05*np.array((-1,1))+np.array((x_min,x_max))
842
+ self.ax_Spectro.set_xlim(x_range)
843
+ if self.debug: print('Rescale x')
844
+ y_min = self.intensities.min()
845
+ y_max = self.intensities.max()
846
+ y_range = (y_max -y_min)*0.05*np.array((-1,1))+np.array((y_min,y_max))
847
+ self.ax_Spectro.set_ylim(y_range)
848
+ if self.debug: print('Rescale y')
849
+
850
+ def rescale_x(self):
851
+ x_min = self.x_min_all
852
+ x_max = self.x_max_all
853
+ x_range = (x_max -x_min)*0.05*np.array((-1,1))+np.array((x_min,x_max))
854
+ self.ax_Spectro.set_xlim(x_range)
855
+ if self.debug: print('Rescale x')
856
+
857
+ def rescale_y(self):
858
+ y_min = self.y_min_all
859
+ y_max = self.y_max_all
860
+ y_range = (y_max -y_min)*0.05*np.array((-1,1))+np.array((y_min,y_max))
861
+ self.ax.set_ylim(y_range)
862
+ self.canvas.draw()
863
+
864
+ if __name__ == "__main__":
865
+ app = QtWidgets.QApplication(sys.argv)
866
+ app.setStyleSheet("""
867
+ * {
868
+ font-size: 15px;
869
+ }
870
+ """)
871
+ #from OF_Model_11 import my_model
872
+ model = None
873
+ #window = Frame_1_graph(model)
874
+ #window = Fig_2_Commands(model)
875
+ #window = Fine_calib_Commands(model)
876
+ #window= Data_Table_Points(model)
877
+ #window = Frame_1_graph(model)
878
+ window = open_file_commands(model)
879
+ #window = show_text_file()
880
+ window.show()
881
+ sys.exit(app.exec())