🚀 feat(MainWindow.py): add support for calculating advanced data in a separate thread 🚀 feat(AdvancedDataWorker.py): add worker to calculate advanced data in a thread The `get_advanced_data` function was added to calculate advanced data from the discrete data. The `process_advanced_data` function was added to the `MainWindow` class to start a thread to calculate the advanced data. The `AdvancedDataWorker` class was added to calculate the advanced data in a separate thread. This allows the application to be more responsive and not freeze while the advanced data is being calculated.
135 lines
5.5 KiB
Python
135 lines
5.5 KiB
Python
"""
|
|
Created on Mon Apr 24 2023
|
|
@name: data_processing.py
|
|
@desc: A module to process the data
|
|
@auth: Djalim Simaila
|
|
@e-mail: djalim.simaila@inrae.fr
|
|
"""
|
|
from utils.math import data_extraction as de
|
|
import numpy as np
|
|
from utils.files.input import ScannedObject
|
|
from utils.settings.SettingManager import SettingManager
|
|
|
|
def progressbar_placeholder(percent:int):
|
|
"""
|
|
This function is a placeholder for a progressbar function
|
|
"""
|
|
|
|
def get_raw_data(obj:ScannedObject, ndigits:int,delta_z:float=1,update_progress_bar = progressbar_placeholder)->dict:
|
|
"""
|
|
Calculates data from the given object
|
|
|
|
:param obj: Object to analyse
|
|
:param ndigits: Number of digits to keep after the comma
|
|
:param delta_z: Delta z to use for the discretisation
|
|
:param update_progress_bar: Function to update the progress bar
|
|
:return: dict(str:list) with the following keys:
|
|
- X (en mm) : list of x values
|
|
- Y (en mm) : list of y values
|
|
- Z (en mm) : list of z values
|
|
- teta (en rad) : list of teta values
|
|
- rayon (en mm) : list of radius values
|
|
- Xi-Xmoy : list of Xi-Xmoy values
|
|
- Yi-Ymoy : list of Yi-Ymoy values
|
|
"""
|
|
|
|
# Create the data dict
|
|
colones = ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"]
|
|
data = {}
|
|
for colone in colones:
|
|
data[colone] = []
|
|
|
|
# Get the discrete vertices
|
|
discrete_vertices = obj.get_discrete_vertices(delta_z)
|
|
progress = 0
|
|
|
|
# Calculate the data for each discrete vertex
|
|
for discrete_values in discrete_vertices:
|
|
mean_x ,mean_y, mean_z = de.get_x_y_z_mean(discrete_values)
|
|
for x,y,z in discrete_values:
|
|
data["X (en mm)"].append(round(x, ndigits))
|
|
data["Y (en mm)"].append(round(y, ndigits))
|
|
data["Z (en mm)"].append(round(z, ndigits))
|
|
data["teta (en rad)"].append(round(de.get_teta_from_x_y(x,y,mean_x,mean_y), ndigits))
|
|
data["rayon (en mm)"].append(round(de.get_radius_from_x_y(x,y,mean_x,mean_y), ndigits))
|
|
data["Xi-Xmoy"].append(round(x-mean_x, ndigits))
|
|
data["Yi-Ymoy"].append(round(y-mean_y, ndigits))
|
|
update_progress_bar(int(progress/len(discrete_vertices)*100))
|
|
progress += 1
|
|
return data
|
|
|
|
def get_discrete_data(obj:ScannedObject, ndigits:int, delta_z:float=1, update_progress_bar= progressbar_placeholder)->dict:
|
|
"""
|
|
Calculates data from the given object
|
|
|
|
:param obj: Object to analyse
|
|
:param ndigits: Number of digits to keep after the comma
|
|
:param delta_z: Delta z to use for the discretisation
|
|
:param update_progress_bar: Function to update the progress bar
|
|
:return: dict(str:list) with the following keys:
|
|
- X moy (en mm) : list of x mean values
|
|
- Y moy (en mm) : list of y mean values
|
|
- Z moy (en mm) : list of z mean values
|
|
- Rayon moyen (en mm) : list of mean radius values
|
|
- Rayon ecart type (en mm) : list of radius standard deviation values
|
|
"""
|
|
# Create the data dict
|
|
colones = ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Discretisation(en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"]
|
|
data = {}
|
|
for colone in colones:
|
|
data[colone] = []
|
|
|
|
# Get the discrete vertices
|
|
discrete_vertices = obj.get_discrete_vertices(delta_z)
|
|
progress = 0
|
|
for discrete_values in discrete_vertices:
|
|
x,y,z = de.get_x_y_z_mean(discrete_values)
|
|
data["X moy (en mm)"].append(round(x, ndigits))
|
|
data["Y moy (en mm)"].append(round(y, ndigits))
|
|
data["Z moy (en mm)"].append(round(z, ndigits))
|
|
first = discrete_values[0]
|
|
last = discrete_values[-1]
|
|
data["Discretisation(en mm)"].append(round(last[2]-first[2],ndigits))
|
|
data["Rayon moyen (en mm)"].append(round(de.get_mean_radius(discrete_values), ndigits))
|
|
data["Rayon ecart type (en mm)"].append(round(de.get_radius_std(discrete_values), ndigits))
|
|
update_progress_bar(int(progress/len(discrete_vertices)*100))
|
|
progress += 1
|
|
return data
|
|
|
|
def get_advanced_data(discrete_data:dict, update_progress_bar= progressbar_placeholder):
|
|
"""
|
|
"""
|
|
# Tortusity
|
|
l = 0
|
|
L = 0
|
|
vertices = list(zip(discrete_data["X moy (en mm)"], discrete_data["Y moy (en mm)"], discrete_data["Z moy (en mm)"]))
|
|
for i in range(len(vertices)-1):
|
|
l += de.get_distance_between_two_vertices(vertices[i], vertices[i+1])
|
|
L = de.get_distance_between_two_vertices(vertices[0], vertices[-1])
|
|
T = l/L
|
|
update_progress_bar(10)
|
|
# Volume and surface
|
|
H = discrete_data["Z moy (en mm)"][-1] - discrete_data["Z moy (en mm)"][0]
|
|
R = de.get_mean([np.power(r,2) for r in discrete_data["Rayon moyen (en mm)"]])
|
|
V = np.pi * R * H
|
|
S = 2 * np.pi * R * H
|
|
update_progress_bar(30)
|
|
#
|
|
R_mean = de.get_mean(discrete_data["Rayon moyen (en mm)"])
|
|
R_mean_std = de.get_standard_deviation(discrete_data["Rayon moyen (en mm)"])
|
|
mean_sigma_r_squared = de.get_mean([np.power(r,2) for r in discrete_data["Rayon ecart type (en mm)"]])
|
|
sigma_r_tot = np.sqrt(np.power(R_mean_std,2) + mean_sigma_r_squared )
|
|
MI_l = R_mean_std/R_mean
|
|
MI_p = np.sqrt(mean_sigma_r_squared)/R_mean
|
|
update_progress_bar(100)
|
|
return {
|
|
"Tortuosité":T,
|
|
"Volume":V,
|
|
"Surface":S,
|
|
"Moyenne des rayons moyens":R_mean,
|
|
"Ecart-type des rayons moyens":R_mean_std,
|
|
"Sigma r tot":sigma_r_tot,
|
|
"MI_l":MI_l,
|
|
"MI_p":MI_p
|
|
}
|