AnalyseMorphologique/utils/data_processing/data_processing.py
2023-06-23 08:23:44 +00:00

216 lines
7.8 KiB
Python
Raw Permalink 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, raw_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 raw_data: 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/
:param V_scan: the volume given by the scanner software
: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
- H
- L
- l
- MI_l
- MI_p
- MI_mR
- MI_mH
- MI_mr_in
- V_scan
- R_V_scan
- S_V_scan
- Rayon hydraulique R_h
- HI
"""
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):
dist = de.get_distance_between_two_vertices(vertices[index], vertices[index+1])
l += dist
l += discrete_data["Discretisation(en mm)"][-1] /2 + discrete_data["Discretisation(en mm)"][0] /2
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 = raw_data["Z (en mm)"][-1] - raw_data["Z (en mm)"][0]
R_mean = de.get_mean(all_R)
R2_mean = de.get_mean([np.power(r,2) for r in all_R])
V = np.pi * R2_mean * H
S = 2 * np.pi * R_mean * H
update_progress_bar(30)
# Morphological indicators
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(discrete_data["Rayon moyen (en mm)"])
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
}