# This script calculates the bond graph parameters for the SERCA model of # Tran et al. (2009) by using the kinetic parameters and stoichiometric # matrix. # translated from MATLAB to Python by SF using Pan's original code import os import csv import json import math import numpy as np import sympy from scipy.linalg import null_space from kinetic_parameters_SERCA import kinetic_parameters def read_IDs(path): data = [] with open(path,'r') as f: reader = csv.reader(f) for row in reader: data.append(row[0]) f.close() return data def load_matrix(stoich_path): matrix = [] with open(stoich_path,'r') as f: reader = csv.reader(f,delimiter=',') for row in reader: matrix.append([int(r) for r in row]) f.close() return matrix if __name__ == "__main__": ## booleans write_parameters_file = True include_constraints = True ## Set directories current_dir = os.getcwd() data_dir = current_dir + '\data' output_dir = current_dir + '\output' modname = os.path.dirname(current_dir).split('\\')[-1].split('_')[-1] ## Define the volumes of each compartment (units pL) W_i = 38.0 # Intracellular volume W_sr = 2.28 # SR volume W_isr = W_i + W_sr # Intracellular volume + SR volume V = dict() V['V_myo'] = W_i V['V_SR'] = W_sr V['V_ISR'] = W_isr ## Load forward matrix stoich_path = data_dir + '\\all_forward_matrix.txt' N_f = load_matrix(stoich_path) ## Load reverse matrix stoich_path = data_dir + '\\all_reverse_matrix.txt' N_r = load_matrix(stoich_path) N_fT = np.transpose(N_f) N_rT = np.transpose(N_r) ## Calculate stoichiometric matrix N = [[N_r[j][i] - N_f[j][i] for i in range(len(N_f[0]))] for j in range(len(N_f))] N_T = [[N_rT[j][i] - N_fT[j][i] for i in range(len(N_fT[0]))] for j in range(len(N_fT))] num_rows = len(N) num_cols = len(N[0]) dims = dict() dims['num_rows'] = num_rows dims['num_cols'] = num_cols I = np.identity(num_cols) M = np.append(np.append(I, N_fT,1), np.append(I, N_rT,1),0) [k_kinetic, N_cT, K_C, W] = kinetic_parameters(M, True, dims, V) if not include_constraints: N_cT = [] try: M = np.append(M, N_cT,0) k = np.append(k_kinetic, K_C, 0) except: k = k_kinetic # FIND PARAMETERS HERE lambda_expo = np.matmul(np.linalg.pinv(M), [math.log(ik) for ik in k]) lambdaW = [math.exp(l) for l in lambda_expo] # Check that kinetic parameters are reproduced by bond graph parameters k_est = np.matmul(M,[math.log(k) for k in lambdaW]) k_est = [math.exp(k) for k in k_est] diff = [(k[i] - k_est[i])/k[i] for i in range(len(k))] error = np.sum([abs(d) for d in diff]) # Check that there is a detailed balance constraint Z = null_space(np.transpose(M)) N_rref = sympy.Matrix(N).rref() R_mat = null_space(N) kf = k_kinetic[:num_cols] kr = k_kinetic[num_cols:] K_eq = [kf[i]/kr[i] for i in range(len(kr))] zero_est = np.matmul(np.transpose(R_mat),K_eq) zero_est_log = np.matmul(np.transpose(R_mat),[math.log(k) for k in K_eq]) lambdak = [lambdaW[i]/W[i] for i in range(len(W))] kappa = lambdak[:len(N[0])] K = lambdak[len(N[0]):] rxnID = read_IDs('data\\rxnID.txt') Kname = read_IDs('data\\Kname.txt') # ### print outputs ### for ik in range(len(kappa)): print('var kappa_%s: fmol_per_sec {init: %g, pub: out};' %(rxnID[ik],kappa[ik])) for ik in range(len(Kname)): print('var K_%s: per_fmol {init: %g, pub: out};' %(Kname[ik],K[ik])) file = open(output_dir + '/all_parameters_out.json', 'w') data = { "K": K, "kappa": kappa, "k_kinetic": k_kinetic } json.dump(data, file)