AnalyseMorphologique/utils/data_processing/data_processing.py
Djalim Simaila 70b4e11b62 🚀 feat(README.md): add support for .stl file format
🐛 fix(data_processing.py): fix typo in advanced data keys and add R_max to advanced data
 feat(MainWindow.py): add support for exporting advanced data to a text file
🎨 style(MainWindow.ui, UI_MainWindow.py): change the display of advanced data labels to use <R> instead of 〈R〉 and σ<R> instead of σ〈R〉
The README.md file now reflects the fact that the tool can now read .stl files. The advanced data keys in data_processing.py have been fixed to use the correct symbols and R_max has been added to the advanced data. The MainWindow.py now allows the user to export the advanced data to a text file. The display of advanced data labels in MainWindow.ui and UI_MainWindow.py has been changed to use <R> instead of 〈
2023-05-15 13:42:46 +02:00

193 lines
7.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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
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
- theta (en rad) : list of theta 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)",
"theta (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["theta (en rad)"].append(round(de.get_theta_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, V_scan = 0, update_progress_bar= progressbar_placeholder)->dict:
"""
Calculates morphological indicators from the given discrete data
:param discrete_data: 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
:param update_progress_bar: Function to update the progress bar
:return: dict with the following keys:
- Tortuosite
- Volume en mm3
- Surface en mm2
- Moyenne des rayons moyens <R>
- Ecart-type des rayons moyens σ_<R>
- σ_<R>^tot
- MI_l
- MI_p
- Rayon hydraulique R_h
"""
all_R = discrete_data["Rayon moyen (en mm)"]
# 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 index in range(len(vertices)-1):
l += de.get_distance_between_two_vertices(vertices[index], vertices[index+1])
L = de.get_distance_between_two_vertices(vertices[0], vertices[-1]) + discrete_data["Discretisation(en mm)"][-1] /2 + discrete_data["Discretisation(en mm)"][0] /2
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]
R2_mean = de.get_mean([np.power(r,2) for r in all_R])
V = np.pi * R2_mean * H
S = 2 * np.pi * R2_mean * H
update_progress_bar(30)
# Morphological indicators
R_mean = de.get_mean(all_R)
R_mean_std = de.get_standard_deviation(all_R)
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
R_max = max(all_R)
R_in = 40
MI_mR = R_max/R_mean
MI_mH = R_max/H
MI_mr_in = R_max/R_in
R_V_scan = np.sqrt(V_scan/np.pi*H)
S_V_scan = 2 * np.sqrt(np.pi * H * V_scan)
R_h = R2_mean/ R_mean
HI = R_mean * R_V_scan / R2_mean
update_progress_bar(100)
return {
"Tortuosité":T,
"Volume en mm3":V,
"Surface en mm2":S,
"<R>":R_mean,
"<R²>":R2_mean,
"σ_<R>":R_mean_std,
"σ_<R>^tot":sigma_r_tot,
"H": H,
"L": L,
"l":l,
"MI_l":MI_l,
"MI_p":MI_p,
"R_max":R_max,
"MI_mR":MI_mR,
"MI_mH":MI_mH,
"MI_mR_in":MI_mr_in,
"V_scan":V_scan,
"R_V_scan":R_V_scan,
"S_V_scan":S_V_scan,
"Rayon hydraulique R_h":R_h,
"HI":HI
}