SimVascular_report_PostProcess/functions.py

155 lines
5.6 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
def error_plot(folder,t_step,r_criteria,save):
# 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))
# Plots of interest
# Liniar Scale
plt.figure()
plt.plot(time,error)
plt.plot(time,r_criteria*np.ones(len(error)),'r')
plt.ylabel('Residual error')
plt.xlabel('Time steps')
plt.title('Last nonlinear residual error for each time step')
plt.grid(True)
if save: plt.savefig(plt_folder + case + '_Last_nonlin_res_error.pdf')
# Semilog scale
plt.figure()
plt.semilogy(time,error)
2020-07-17 02:02:02 +01:00
plt.semilogy(time,r_criteria*np.ones(len(error)),'r')
plt.ylabel('Residual error')
plt.xlabel('Time steps')
plt.title('Log - Last nonlinear residual error for each time step')
plt.grid(True)
if save: plt.savefig(plt_folder + case + '_Log_Last_nonlin_res_error.pdf')
def periodicity(project,folder,dt,T_cyc,n_cyc):
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()
ax.plot(time,pressure[:,-1]/1333.22)
ax.plot(time[peak_P_pos], peak_P,'ro',label='Cylce pike')
ax.set(xlabel='time [s]', ylabel='Pressure [mmHg]',
title='Pressure @ last outlet')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.legend(loc=0)
plt.show()
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]))
2020-07-17 02:02:02 +01:00
def pressure(folder,N_ts,T_cyc,dt,n_cyc):
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]',
title='Pressure @ each outlet')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.legend(loc=0)
plt.show()
2020-07-17 02:30:27 +01:00
return (DBP,MBP,SBP,PP)
def flow(folder,N_ts,T_cyc,dt,n_cyc):
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]',
title='Flow @ each outlet')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.legend(loc=0)
plt.show()
return Q
2020-07-17 02:30:27 +01:00
def inlet_flow_waveform(project_folder,t_btw_rst,N_ts,dt,T_cyc,n_cyc):
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')
ax.plot(t_pts, Q_pts, 'ob')
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]',
title='Inlet Flow rate Waveform - 1 cycle')
ax.set_ylim([-10, 90])
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
# Adding label to the points
time = ['$t_1$', '$t_2$', '$t_3$', '$t_4$', '$t_5$', '$t_6$']
for x, y, t in zip(t_pts[(-n_cyc-1):], Q_pts[(-n_cyc-1):], time):
plt.text(x, y, t, transform=trans_offset, fontsize=12)
plt.show()
2020-07-17 02:02:02 +01:00