123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- import numpy as np
- import matplotlib.pyplot as plt
- import os
- import cModel
- import time
- import pdfkit
- import tempfile
- import runSolver
- import io
- import importlib
- #Nariše graf iz IVP modelov
- importlib.reload(cModel)
- importlib.reload(runSolver)
- def getModel(solution, modelName):
- """
- Load and parse the model from the given solution dictionary using the modelName.
- """
- Q = solution[modelName] # Retrieve the solution dictionary for the specified model
- model = cModel.model() # Create an instance of the cModel class
- setupFile = Q['setup'] # Get the setup file path from the solution
- modelFile = Q['model'] # Get the model file path from the solution
- parameterFile = Q['parameters'] # Get the parameter file path from the solution
- print('modelFile: {} {}'.format(modelFile, os.path.isfile(modelFile))) # Print the model file path and its existence status
- print('parameterFile: {} {}'.format(parameterFile, os.path.isfile(parameterFile))) # Print the parameter file path and its existence status
- model.parse(modelFile, parameterFile) # Parse the model file with the given parameters
- return model # Return the loaded model
- def mergeSolutions(seq):
- """
- Merge multiple solution dictionaries into a single dictionary.
- """
- out = {}
- for v in ['t', 'sol', 'se', 'qt', 'sOut']: # Merge arrays from each solution
- out[v] = np.concatenate([x[v] for x in seq])
- for v in ['lut', 'lutSE', 'setup', 'model', 'parameters', 'qt', 'sOut']: # Use data from the last solution for these keys
- out[v] = seq[-1][v]
- return out # Return the merged dictionary
- # Define paths
- fh = os.path.expanduser('~')
- # Define job configurations for loading
- job_configs = {
- 'cDiazepam_IVP': {
- 'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepam_IVP')
- },
- 'cDiazepam1_IVP': {
- 'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepam1_IVP')
- },
- 'cDiazepamF_IVP': {
- 'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepamF_IVP')
- },
- 'cDiazepamB_IVP': {
- 'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepamB_IVP')
- }
- }
- # Load and merge solutions
- solution = {}
- for modelName, job in job_configs.items():
- seq = [runSolver.loadSolutionFromDir(job['jobDir'], True)]
- solution[modelName] = mergeSolutions(seq)
- def analyze_model(model, setup):
- """
- Perform matrix operations and print results.
- """
- tscale = runSolver.getScale(setup) # Get the time scale from the setup
- print(f'tscale={tscale}') # Print the time scale
- model.inspect() # Inspect the model
-
- print("***********done************")
- print(model.M(1).shape) # Print the shape of the matrix from the model
- print(model.m) # Print the model parameters
- nt = setup['nt'] # Number of time points
- qtmax = 1 # Maximum time (minute)
- qt = np.linspace(0, qtmax, nt) # Generate time points
- par = 'venousInput' # Parameter to plot
- # Plot parameters
- try:
- hw = model.get(par) # Get the parameter from the model
- print(hw) # Print the parameter information
- ht = [10 * hw['value'](x) for x in qt] # Calculate parameter values over time
- plt.plot(qt / tscale, ht) # Plot the parameter values
- except (KeyError, TypeError): # Handle errors if the parameter is not found
- print(f'Troubles getting {par}')
- pass
- # Measure performance of matrix operations
- start_time = time.time() # Record start time
- for i in range(100000): # Perform matrix operations 100,000 times
- model.M(1e7) # Call the matrix operation
- end_time = time.time() # Record end time
- print('Time: {:.3f} s'.format(end_time - start_time)) # Print elapsed time
- fM = model.M(0) # Get the matrix from the model
- print('Rank: {}/{}'.format(np.linalg.matrix_rank(fM), fM.shape)) # Print the rank of the matrix
- np.set_printoptions(suppress=True, precision=2, linewidth=150) # Set NumPy print options
- print(f'{fM}') # Print the matrix
- v, Q = np.linalg.eig(fM) # Perform eigenvalue decomposition
- np.set_printoptions(suppress=False) # Reset NumPy print options
- print(Q[:, 2:4]) # Print selected eigenvectors
- Q1 = np.linalg.inv(Q) # Calculate the inverse of the eigenvector matrix
- D = np.diag(v) # Create a diagonal matrix of eigenvalues
- t = np.linspace(0, 100, 101) # Generate time points for plotting
- fy = [model.u(x)[14] for x in t] # Calculate model output over time
- print('{} {}'.format(len(fy), len(t))) # Print lengths of output and time points
- plt.figure() # Create a new figure
- plt.plot(fy) # Plot the model output
- fu = model.u(0) # Get the model output at time 0
- print(Q1 @ fu) # Print the result of the matrix multiplication
- def plot_results(solution, modelName):
- """
- Plot results for the specified model from the solution.
- """
- model = getModel(solution, modelName) # Load the model
- setup = solution[modelName]['setup'] # Get the setup from the solution
- tscale = runSolver.getScale(setup) # Get the time scale
- print(f'tscale={tscale}') # Print the time scale
- model.inspect() # Inspect the model
- name = ['venous', 'adipose', 'brain', 'heart', 'kidney', 'liver', 'lung', 'muscle', 'skin', 'stomach', 'splanchnic', 'excrement'] # Compartment names
- tmax = solution[modelName]['t'][-1] # Get the maximum time from the solution
- # Define colors and shading for models
- models = {
- 'cDiazepam_IVP': {'color': 'orange', 'shadeColor': 'red'},
- 'cDiazepamF_IVP': {'color': 'blue', 'shadeColor': 'green'},
- 'cDiazepam1_IVP': {'color': 'black', 'shadeColor': 'yellow'},
- 'cDiazepamB_IVP': {'color': 'purple', 'shadeColor': 'gold'}
- }
- fig, axs = plt.subplots(4, 3, figsize=(15, 20)) # Create a grid of subplots
- for i in range(len(name)): # Loop over each compartment
- row = i // 3 # Determine row index
- col = i % 3 # Determine column index
- ax = axs[row, col] # Get the subplot
- for m in models: # Loop over each model
- fM = models[m] # Get model configuration
- Q = solution[m] # Get solution for the model
- v = name[i] # Get the compartment name
- try:
- j = Q['lut'][v] # Get the index for the compartment
- except KeyError:
- try:
- v1 = alias[v] # Handle alias if needed
- j = Q['lut'][v1] # Get the index for the alias
- except KeyError:
- print(f'No data for {v}/{v1}') # Print error if compartment not found
- continue
- fy = Q['sol'][:, j] # Get the solution for the compartment
- fe = Q['se'][:, j] # Get the standard error for the compartment
- t = Q['t'] # Get the time points
- # Plot the mean values and confidence intervals
- ax.plot(t / tscale, fy, color=fM['color'], label=f'{m} Mean')
- ax.fill_between(t / tscale, fy - fe, fy + fe, color=fM['shadeColor'], alpha=0.1) # Shaded area for confidence intervals
- ax.plot(t / tscale, fy - fe, color=fM['shadeColor'], linewidth=1, alpha=0.2) # Lower bound
- ax.plot(t / tscale, fy + fe, color=fM['shadeColor'], linewidth=1, alpha=0.2) # Upper bound
- # Find the maximum y-value including confidence intervals
- max_y_value = max(np.max(fy + fe), np.max(fy - fe))
- ax.set_ylim([0, min(max_y_value, 10000)]) # Set y-axis limit to max value or 5500, whichever is smaller
- ax.set_xlim([0, 1.1 * tmax / tscale]) # Set x-axis limits
- ax.set_xlabel(setup['tUnit']) # Set x-axis label
- ax.set_title(name[i]) # Set plot title
- ax.legend() # Add legend
- output_file = os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'results', 'plot.png') # Define output file path
- plt.savefig(output_file) # Save the plot to file
- plt.show() # Display the plot
- def main():
- """
- Main function to load data, analyze model, and plot results.
- """
- fh = os.path.expanduser('~') # Define file path root
- # Define job configurations for loading
- job_configs = {
- 'cDiazepam_IVP': {
- 'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepam_IVP')
- },
- 'cDiazepam1_IVP': {
- 'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepam1_IVP')
- },
- 'cDiazepamF_IVP': {
- 'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepamF_IVP')
- },
- 'cDiazepamB_IVP': {
- 'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepamB_IVP')
- }
- }
- # Load and merge solutions
- solution = {}
- for modelName, job in job_configs.items():
- seq = [runSolver.loadSolutionFromDir(job['jobDir'], True)] # Load solution from directory
- solution[modelName] = mergeSolutions(seq) # Merge solutions
- # Capture print output
- output_stream = io.StringIO()
- analyze_model(getModel(solution, 'cDiazepamF_IVP'), solution['cDiazepamF_IVP']['setup']) # Analyze the model
- analysis_results = analyze_model(getModel(solution, 'cDiazepamF_IVP'), solution['cDiazepamF_IVP']['setup'])
- plot_results(solution, 'cDiazepamF_IVP') # Plot the results
-
- if __name__ == "__main__":
- main() # Execute the main function
|