SimVascular_report_PostProcess/functions.py

173 lines
7.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
from tkinter import Tk
from tkinter.filedialog import askopenfilename, asksaveasfile, askdirectory
import pandas as pd
import tkinter as tk
2020-07-17 02:30:27 +01:00
from statistics import mean
from scipy.signal import find_peaks
import matplotlib.transforms as mtransforms
2020-07-17 05:33:48 +01:00
def error_plot(folder,t_step,r_criteria,save_path):
# Load iterations and residual error
histor = folder + '/histor.dat'
input = open(histor, 'r')
output = open(folder + "/histor_better.dat", 'w')
output.writelines(line.strip() +'\n' for line in input)
input.close()
output.close()
error_info = pd.read_csv(folder + "/histor_better.dat", sep=' ', header=None, usecols=(0,1,2))
# Select only last iteration of residual error
error=[]
for n in range(1,error_info.shape[0]):
if (error_info[0][n]>error_info[0][n-1]):
error.append(error_info[2][n-1])
time = np.linspace(start = t_step, stop = len(error)*t_step, num = len(error))
2020-07-17 05:33:48 +01:00
# Liniar Scale
fig, ax = plt.subplots()
ax.plot(time,error)
ax.plot(time,r_criteria*np.ones(len(error)),'r')
ax.set(xlabel='Time steps', ylabel='Residual error',
title='Last nonlinear residual error for each time step')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
plt.show()
plt.savefig(save_path + '/Last_nonlin_res_error.pdf')
# Semilog scale
2020-07-17 05:33:48 +01:00
fig, ax = plt.subplots()
ax.semilogy(time,error)
ax.semilogy(time,r_criteria*np.ones(len(error)),'r')
ax.set(xlabel='Time steps', ylabel='Residual error',
title='Log - Last nonlinear residual error for each time step')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
plt.show()
plt.savefig(save_path + '/Log_Last_nonlin_res_error.pdf')
fig.savefig(save_path + '/Log_Last_nonlin_res_error.jpg',dpi=150)
2020-07-17 05:33:48 +01:00
def periodicity(project,folder,dt,T_cyc,n_cyc,save_path):
pressure = np.loadtxt(folder+'/PHistRCR.dat',skiprows=2,)
time = np.linspace(0,T_cyc*n_cyc,round(T_cyc/dt*n_cyc))
peak_P = []
peak_P_pos = []
Nc = round(T_cyc/dt)
for i in range(0,n_cyc):
peak_P.append(np.amax(pressure[i*Nc:Nc*(i+1),-1])/1333.22)
peak_P_pos.append(np.where(pressure[i*Nc:Nc*(i+1),-1] == np.amax(pressure[i*Nc:Nc*(i+1),-1]))[0][0]+Nc*i)
peak_Pdiff = [peak_P[n]-peak_P[n-1] for n in range(1,len(peak_P))]
peak_Pdiff = list(map(abs, peak_Pdiff))
fig, ax = plt.subplots()
2020-07-17 05:33:48 +01:00
ax.plot(time,pressure[:,-1]/1333.22,'b')
ax.plot(time[peak_P_pos], peak_P,'ro',label='Cylce pike')
ax.set(xlabel='time [s]', ylabel='Pressure [mmHg]',
2020-07-17 05:33:48 +01:00
title='Pressure at last outlet')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.legend(loc=0)
plt.show()
2020-07-17 05:33:48 +01:00
plt.savefig(save_path + '/periodicity.pdf')
fig.savefig(save_path + '/periodicity.jpg',dpi=150)
2020-07-17 05:33:48 +01:00
if (peak_Pdiff[-1]<=1):
print('The numerical simulation \'{0}\' has achieve periodicity!\nSystolic Blood Pressure (SBP):\nsecond-last cycle = {1:.2f} mmHg,\nlast cycle = {2:.2f} mmHg,\n\u0394mmHg = {3:.2f} mmHg'.format(project,peak_P[-2],peak_P[-1],peak_Pdiff[-1]))
# txt = ['The numerical simulation \'{0}\' has achieve periodicity!'.format(project), 'Systolic Blood Pressure (SBP):', 'Second-last cycle = {0:.2f} mmHg'.format(peak_P[-2]), 'Last cycle = {0:.2f} mmHg'.format(peak_P[-1]), 'Delta_mmHg = {0:.2f} mmHg'.format(peak_Pdiff[-1])]
txt = ['The numerical simulation \'{0}\' has achieve periodicity!'.format(project), 'Systolic Blood Pressure (SBP):','Second-last cycle = {0:.2f} mmHg - Last cycle = {1:.2f} mmHg - Delta_mmHg = {2:.2f} mmHg'.format(peak_P[-2],peak_P[-1],peak_Pdiff[-1])]
2020-07-17 05:33:48 +01:00
return txt
def pressure(folder,N_ts,T_cyc,dt,n_cyc,save_path):
2020-07-17 02:02:02 +01:00
pressure = np.loadtxt(folder+'/PHistRCR.dat',skiprows=2,)
Nc = round(T_cyc/dt)
time = np.linspace(0,T_cyc,Nc)
fig, ax = plt.subplots()
2020-07-17 02:30:27 +01:00
SBP = np.empty(pressure.shape[1])
DBP = np.empty(pressure.shape[1])
MBP = np.empty(pressure.shape[1])
2020-07-17 02:02:02 +01:00
for i in range(0,pressure.shape[1]):
ax.plot(time,pressure[N_ts-Nc:N_ts,i]/1333.22,label='ROI-'+str(i+2))
2020-07-17 02:30:27 +01:00
SBP[i] = (np.amax(pressure[N_ts-Nc:N_ts,i]/1333.22))
DBP[i] = (np.amin(pressure[N_ts-Nc:N_ts,i]/1333.22))
MBP[i] = (mean(pressure[N_ts-Nc:N_ts,i]/1333.22))
PP = SBP-DBP
2020-07-17 02:02:02 +01:00
ax.set(xlabel='time [s]', ylabel='Pressure [mmHg]',
2020-07-17 05:33:48 +01:00
title='Pressure at each outlet')
2020-07-17 02:02:02 +01:00
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.legend(loc=0)
plt.show()
2020-07-17 05:33:48 +01:00
plt.savefig(save_path + '/pressure.pdf')
fig.savefig(save_path + '/pressure.jpg',dpi=150)
2020-07-17 02:30:27 +01:00
return (DBP,MBP,SBP,PP)
2020-07-17 05:33:48 +01:00
def flow(folder,N_ts,T_cyc,dt,n_cyc,save_path):
flow = np.loadtxt(folder+'/QHistRCR.dat',skiprows=2,)
Nc = round(T_cyc/dt)
time = np.linspace(0,T_cyc,Nc)
fig, ax = plt.subplots()
Q = np.empty(flow.shape[1])
for i in range(0,flow.shape[1]):
ax.plot(time,flow[N_ts-Nc:N_ts,i],label='ROI-'+str(i+2))
Q[i] = (mean(flow[N_ts-Nc:N_ts,i]))
ax.set(xlabel='time [s]', ylabel='Flow [mL/s]',
2020-07-17 05:33:48 +01:00
title='Flow at each outlet')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.legend(loc=0)
plt.show()
2020-07-17 05:33:48 +01:00
plt.savefig(save_path + '/flow.pdf')
fig.savefig(save_path + '/flow.jpg',dpi=150)
return Q
2020-07-17 02:30:27 +01:00
2020-07-17 05:33:48 +01:00
def inlet_flow_waveform(project_folder,t_btw_rst,N_ts,dt,T_cyc,n_cyc,save_path):
x = np.loadtxt(project_folder+'/ROI-1.flow')
t = x[:,0]
Q = -x[:,1]
Nt_pts = np.linspace(t_btw_rst,N_ts,int(N_ts/t_btw_rst))
t_pts = Nt_pts*dt
# Put all the time values on a single cardiac cylce
for n in range(len(t_pts)):
tmp=divmod(t_pts[n],T_cyc)
t_pts[n]=tmp[1]
if round(tmp[1],3) == 0:
t_pts[n]=T_cyc
# Interpolate the flow rate to obtain the location of the point
Q_pts = np.interp(t_pts, t, Q)
fig, ax = plt.subplots()
ax.plot(t, Q, 'r')
2020-07-17 05:33:48 +01:00
ax.plot(t_pts, Q_pts, 'ob',label='Time steps saved')
trans_offset = mtransforms.offset_copy(ax.transData, fig=fig,
x=-0, y=0.15, units='inches')
ax.set(xlabel='Time [s]', ylabel='Flow Rate - Q [mL/s]',
2020-07-17 05:33:48 +01:00
title='Inlet Flow Rate Waveform')
ax.set_ylim([-10, 90])
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
# Adding label to the points
2020-07-17 03:34:00 +01:00
time = []
for i in range(0,np.unique(np.round(t_pts,3)).shape[0]):
time.append('$t_'+str(i+1)+'$')
for x, y, t in zip(t_pts[(-n_cyc-1):], Q_pts[(-n_cyc-1):], time):
2020-07-17 05:33:48 +01:00
plt.text(x, y, t, transform=trans_offset, fontsize=12)
ax.legend(loc=0)
plt.show()
2020-07-17 05:33:48 +01:00
plt.savefig(save_path + '/inlet_waveform.pdf')
fig.savefig(save_path + '/inlet_waveform.jpg',dpi=150)
print('{0} time steps saved, available to visualize in ParaView.'.format(np.unique(np.round(t_pts,3)).shape[0]))
txt = '{0} time steps saved, available to visualize in ParaView.'.format(np.unique(np.round(t_pts,3)).shape[0])
return txt
2020-07-17 02:02:02 +01:00