Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.0 #1

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/windows-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
run: |
pip install -r requirements.txt
pip install pyinstaller
- name: Build application and ru Inno Setup
- name: Build application and run Inno Setup
run: |
python -m PyInstaller --onefile --noconsole --icon="icon\app_icon.tiff" --name="ThermLUM" --uac-admin start_app.py
iscc ".\ThermLUM.iss"
Expand All @@ -31,8 +31,8 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: 1.0.0 #VERSION
release_name: Release 1.0.0 #VERSION
tag_name: 1.1.0 #VERSION
release_name: Release 1.1.0 #VERSION
draft: false
prerelease: false
- name: Upload Release Asset
Expand All @@ -46,7 +46,7 @@ jobs:
asset_name: ThermLUMsetup.exe
asset_content_type: application/x-msdownload

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: ThermLUMsetup.exe
path: ./dist/ThermLUMsetup.exe
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Byte-compiled / optimized / DLL files
*.py[cod]
*$py.class
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Translations
*.mo
*.pot
# Distribution / packaging
.Python
/build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# VS
.idea
*.xml
8 changes: 0 additions & 8 deletions .idea/.gitignore

This file was deleted.

2 changes: 1 addition & 1 deletion ThermLUM.iss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "ThermLUM"
#define MyAppVersion "1.0.0"
#define MyAppVersion "1.1.0"
#define MyAppPublisher "Multifunctional Luminescent Materials Group"
#define MyAppExeName "ThermLUM.exe"
#define MyAppAssocName MyAppName + " File"
Expand Down
31 changes: 0 additions & 31 deletions core.py

This file was deleted.

7 changes: 6 additions & 1 deletion creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# GNU General Public License for more details.
import pandas as pd
import h5py
from os import path
from os import path, remove
def new(file_path, hdf_name):
file_directory, file_name = path.split(file_path)
with open(file_path, "r") as file:
Expand Down Expand Up @@ -49,5 +49,10 @@ def new(file_path, hdf_name):
group.create_dataset(f'temperatures_{hdf_name}', data=temps)
hdf_file.close()

if path.exists(path.join(file_directory, f'description_{file_name.split('.')[0]}')):
remove(path.join(file_directory, f'description_{file_name.split('.')[0]}'))
if path.exists(path.join(file_directory, f'_temp_data)_{file_name.split('.')[0]}.csv')):
remove(path.join(file_directory, f'_temp_data)_{file_name.split('.')[0]}.csv'))

from thermmap_object import ThermMap
return ThermMap(hdf_file_path)
2 changes: 1 addition & 1 deletion fitting_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ def coth_vibration_error(x, delta0, ev, b, delta0_error, ev_error, b_error):
'Exponential decay': exponential_decay_error,
'coth': coth_vibration_error
}

#NEWLINE
115 changes: 96 additions & 19 deletions gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@

from PyQt6.QtWidgets import QDialog, QSpinBox, QDialogButtonBox, QLabel, QWidget, QVBoxLayout, \
QApplication, QMainWindow, QFileDialog, QHBoxLayout, QGridLayout, QAbstractSpinBox, QComboBox, \
QFormLayout, QDoubleSpinBox, QPushButton, QStackedLayout, QSizePolicy
QFormLayout, QDoubleSpinBox, QPushButton, QStackedLayout, QSizePolicy, QCheckBox, QButtonGroup, QGroupBox
from PyQt6.QtGui import QIcon
from PyQt6.QtCore import Qt


import matplotlib as mpl # import matplotlib after PyQt6
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
Expand Down Expand Up @@ -152,7 +154,7 @@ def __init__(self, thermmap, parent=None):
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)

layout_ribbon.addWidget(QLabel("To correctly determine error smooth data in a way that removes noise but do not obscure any peaks.\n Smoothing options of Savitzky-Goloy filter"), 0, 0)
layout_ribbon.addWidget(QLabel("To correctly determine error smooth data in a way that removes noise but do not obscure any peaks.\nSmoothing options of Savitzky-Goloy filter"), 0, 0)
layout_ribbon.addWidget(QLabel("Window length"), 1, 0)
layout_ribbon.addWidget(self.window_length_widget, 1, 1)
layout_ribbon.addWidget(QLabel("Polynomial order"), 2, 0)
Expand All @@ -162,7 +164,38 @@ def __init__(self, thermmap, parent=None):
layout_ribbon.addWidget(QLabel("Sum of all residuals should be as close to 0 as posible for correct error determination"), 4, 0)
layout_ribbon.addWidget(QLabel("Sum of all residuals:"), 5, 0)
layout_ribbon.addWidget(self.residula_widget, 5, 1)
layout_ribbon.addWidget(self.button_box, 6, 0, 6, 1)


layout_ribbon.addWidget(QLabel("Detector error's setettings:"), 6, 0)
# Constant error option
self.constant_detector_error_checkbox = QCheckBox('Constant error')
layout_ribbon.addWidget(self.constant_detector_error_checkbox, 7, 0)
self.constant_detector_error_spinbox = QSpinBox(
minimum=1,
maximum=1000000,
)
self.constant_detector_error_spinbox.setValue(250)
self.constant_detector_error_spinbox.setKeyboardTracking(False)
self.constant_detector_error_spinbox.setMinimumWidth(150)
self.constant_detector_error_spinbox.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
layout_ribbon.addWidget(self.constant_detector_error_spinbox, 7, 1)
self.constant_detector_error_checkbox.stateChanged.connect(lambda: self.handle_detector_checkbox(self.constant_detector_error_checkbox))

# Smooth error option
self.smoothed_detector_error_checkbox = QCheckBox('Determined from smoothing')
layout_ribbon.addWidget(self.smoothed_detector_error_checkbox, 8, 0)
self.smoothed_detector_error_checkbox.stateChanged.connect(lambda: self.handle_detector_checkbox(self.smoothed_detector_error_checkbox))


layout_ribbon.addWidget(QLabel("Function error's setettings:"), 9, 0)
function_error_group = QButtonGroup()
self.easy_function_error_checkbox = QCheckBox('Fit - exp diffrence error')
layout_ribbon.addWidget(self.easy_function_error_checkbox, 10, 0)

function_error_group.addButton(self.easy_function_error_checkbox)


layout_ribbon.addWidget(self.button_box, 11, 0, 11, 1)


layout_outer.addLayout(layout_plot, 0, 0)
Expand All @@ -172,6 +205,18 @@ def __init__(self, thermmap, parent=None):
self.update()
self.setLayout(layout_outer)

def handle_detector_checkbox(self, selected_checkbox):
# Uncheck other checkboxes
for checkbox in [self.constant_detector_error_checkbox, self.smoothed_detector_error_checkbox]:
if checkbox != selected_checkbox:
checkbox.blockSignals(True) # Temporarily block signals to prevent recursion
checkbox.setChecked(False)
checkbox.blockSignals(False) # Re-enable signals
if self.constant_detector_error_checkbox.isChecked():
self.constant_detector_error_spinbox.setEnabled(True)
else:
self.constant_detector_error_spinbox.setEnabled(False)

def update(self, _=None):
window_length = self.window_length_widget.value()
polyorder = self.polyorder_widget.value()
Expand Down Expand Up @@ -237,8 +282,6 @@ def __init__(self, *args, **kwargs):
filters, selectedFilter)

settings['recently_opened_folder'] = path.split(file_path)[0]
with open('./settings.json', 'r+') as settings_json:
settings_json.write(json.dumps(settings, indent=0))

self.thermmap = new(file_path, path.split(file_path)[1][:-4])
self.thermmap.get_data()
Expand Down Expand Up @@ -277,8 +320,10 @@ def __init__(self, *args, **kwargs):
self.normalization_line = None
self.fitting_plot = None
self.sensitivity_plot = None
self.error_bar_plot = None
self.temperature_err = None
self.error_bar_plot_detector = None
self.error_bar_plot_function = None
self.temperature_err_detector = None
self.temperature_err_function = None

self.cid1 = self.canvas.mpl_connect('button_press_event', self.on_click)
self.cid2 = self.canvas.mpl_connect('pick_event', self.on_pick)
Expand Down Expand Up @@ -319,6 +364,9 @@ def __init__(self, *args, **kwargs):
maximum=self.thermmap.data[-1, 0],
singleStep=self.thermmap.resolution
)
self.swap_widget = QPushButton('Swap')
self.swap_widget.clicked.connect(self.on_wavelength_switch)
layout_wavelengths_chooser.addRow(QLabel(''), self.swap_widget)
self.second_value_widget.setKeyboardTracking(False)
self.second_value_widget.setMinimumWidth(150)
self.second_value_widget.valueChanged.connect(self.on_second_value_changed)
Expand Down Expand Up @@ -534,6 +582,12 @@ def on_second_value_changed(self, value):
self.second_click = False
self.canvas.draw()
self.normalized_canvas.draw()

def on_wavelength_switch(self):
if (self.second_line_position is not None) and (self.first_line_position is not None):
_temp_value = self.first_value_widget.value()
self.first_value_widget.setValue(self.second_line_position)
self.second_value_widget.setValue(_temp_value)

def on_normalization_value_changed(self, value):
new_value = quantization_to_resolution(value, self.thermmap.resolution)
Expand Down Expand Up @@ -733,26 +787,43 @@ def start_fitting(self):
def determine_error(self):
dialog = ErrorDeterminingDialog(self.thermmap, self)
if dialog.exec() == QDialog.DialogCode.Accepted:
self.smoothed_data, self.smoothed_residual = dialog.smoothed_data, dialog.smoothed_residual
if dialog.smoothed_detector_error_checkbox.isChecked():
self.smoothed_data, self.smoothed_residual = dialog.smoothed_data, dialog.smoothed_residual

detector_err = self.thermometric_parameter * sqrt((self.thermmap.general_get_row_of_ydata(self.smoothed_residual, self.first_line_position) / self.thermmap.get_row_of_ydata(self.first_line_position))**2 +
detector_err = sqrt((self.thermmap.general_get_row_of_ydata(self.smoothed_residual, self.first_line_position) / self.thermmap.get_row_of_ydata(self.first_line_position))**2 +
(self.thermmap.general_get_row_of_ydata(self.smoothed_residual, self.second_line_position) / self.thermmap.get_row_of_ydata(self.second_line_position))**2)

# function_err = list(dict_of_fitting_errors_functions.values())[self.fitting_functions_layout.currentIndex()](self.thermometric_parameter, *self.fitted_output_parameters, *self.parameter_errors)
function_err = abs(self.thermometric_parameter - list(dict_of_fitting_functions.values())[self.fitting_functions_layout.currentIndex()](self.thermometric_parameter, *self.fitted_output_parameters))
elif dialog.constant_detector_error_checkbox.isChecked():
constant_err = dialog.constant_detector_error_spinbox.value()
detector_err = sqrt((constant_err / self.thermmap.get_row_of_ydata(self.first_line_position))**2 + (constant_err / self.thermmap.get_row_of_ydata(self.second_line_position))**2)
if dialog.easy_function_error_checkbox.isChecked():
# function_err = list(dict_of_fitting_errors_functions.values())[self.fitting_functions_layout.currentIndex()](self.thermometric_parameter, *self.fitted_output_parameters, *self.parameter_errors)
function_err = abs(self.thermometric_parameter - list(dict_of_fitting_functions.values())[self.fitting_functions_layout.currentIndex()](self.thermometric_parameter, *self.fitted_output_parameters)) / list(dict_of_fitting_functions.values())[self.fitting_functions_layout.currentIndex()](self.thermometric_parameter, *self.fitted_output_parameters)
else:
function_err = 0

total_err = sqrt(detector_err**2 + function_err**2)

self.temperature_err = (total_err / self.thermometric_parameter) * (1 / self.discontinuous_sensitivity)
percent_detector = detector_err / (detector_err + function_err)

self.temperature_err_detector = (total_err * percent_detector) * (1 / self.discontinuous_sensitivity)
self.temperature_err_function = (total_err * (1 - percent_detector)) * (1 / self.discontinuous_sensitivity)

if self.error_bar_plot is not None:
self.error_bar_plot[0].remove()
self.error_bar_plot = self.fitting_canvas.error_axes.bar(
if self.error_bar_plot_detector is not None:
self.error_bar_plot_detector[0].remove()
self.error_bar_plot_function[0].remove()
self.error_bar_plot_detector = self.fitting_canvas.error_axes.bar(
self.thermmap.temperatures,
self.temperature_err,
self.temperature_err_detector,
color='#E56B6F',
width=8
)
self.error_bar_plot_function = self.fitting_canvas.error_axes.bar(
self.thermmap.temperatures,
self.temperature_err_function,
color='#6D597A',
width=8,
bottom=self.temperature_err_detector
)
self.fitting_canvas.error_axes.set_ylim(0, 2)
self.fitting_canvas.error_axes.set_ylabel(r'Error / $\mathrm{K}$')
self.fitting_canvas.draw()
Expand All @@ -770,9 +841,10 @@ def export_data(self):
result_dict['Fit temperature / K'] = self.fit_x
result_dict['Fitted parameter'] = self.fitted_output_data
result_dict['Relative sensitivity / %K^(-1)'] = self.sensitivity
if self.temperature_err is not None:
if self.temperature_err_detector is not None:
result_dict['Error temperature / K'] = self.thermmap.temperatures
result_dict['Temperature error / K'] = self.temperature_err
result_dict['Temperature error (detector) / K'] = self.temperature_err_detector
result_dict['Temperature error (function) / K'] = self.temperature_err_function
for index, fitted_parameter in enumerate(signature(list(dict_of_fitting_functions.values())[self.fitting_functions_layout.currentIndex()]).parameters):
if index == 0:
continue
Expand All @@ -787,6 +859,11 @@ def export_data(self):
self.result.to_csv(filename)


def closeEvent(self, event):
with open('./settings.json', 'w') as settings_json:
settings_json.write(json.dumps(settings, indent=0))




def run_gui():
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ThermLUM",
"version": "1.0.0",
"version": "1.1.0",
"dependencies": {
}
}
2 changes: 1 addition & 1 deletion plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# GNU General Public License for more details.
import matplotlib.pyplot as plt
import numpy as np

#EGG

def luminescence_dt(data, temperatures, axes: plt.Axes, colormap):
counter = 0
Expand Down
13 changes: 7 additions & 6 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
h5py==3.11.0
h5py
matplotlib==3.8.0
numpy==2.1.2
pandas==2.2.3
PyQt6==6.7.1
PyQt6_sip==13.8.0
scipy==1.14.1
numpy
pandas
PyQt6
PyQt6_sip
scipy
requests
Loading
Loading