216 lines
7.8 KiB
Python
216 lines
7.8 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
|
||
|
||
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
|
||
}
|