Setup and Import
f_user_input
Code
1function [settings, results, sb] = ... 2 f_user_input(model_folders, analysis_options, user_choices) 3% This function processes user input for model, analysis options, and 4% settings files, and returns settings, results, and sbTab data structures. 5% It utilizes helper functions to validate user input, apply settings, and 6% manage persistent variables. 7% 8% Inputs: 9% - model_folders: Model folders structure 10% - analysis_options: Array of available analysis options 11% - user_choices: Cell array of user input choices for model folder, 12% analysis, and settings 13% 14% Outputs: 15% - settings: Struct containing all settings for the chosen analysis 16% - results: Struct containing the results of the analysis 17% - sbTab: Struct containing SBtab data 18% 19% Used Functions: 20% - getValidInput: Validates user input for model folder, analysis option, 21% and settings file 22% - apply_settings: Updates settings based on chosen settings file and 23% checks for changes 24% - choose_options: Helps user choose valid options from available choices 25% - parse_choices: Presents list of choices to user and validates input 26% - compare_and_update: Checks if current and previous values are different 27% and clears functions if necessary 28% 29% Variables: 30% Loaded: 31% - None 32% 33% Initialized: 34% - results: Empty struct for storing analysis results 35% - settings: Empty struct for storing analysis settings 36% - sbTab: Empty struct for storing SBtab data 37% 38% Persistent: 39% - last_settings_file_text: Stores the last settings file text 40% - last_settings_file_date: Stores the last settings file date 41% - last_model_folder: Stores the last chosen model folder 42% - last_analysis_text: Stores the last chosen analysis option 43% - last_settings_file_text: Stores the last chosen settings file text 44% - last_SBtab_date: Stores the last SBtab date 45% - functions_cleared: Flag indicating if functions have been cleared or 46% not 47 48 49 50% Define persistent variables to store the last settings file text and 51% date. 52persistent last_settings_file_text 53persistent last_settings_file_date 54 55% Initialize the results, settings and sbTab variables. 56results = []; 57settings = []; 58sb = []; 59functions_cleared = 0; 60 61% Set model folder paths 62general_model_folder = model_folders.main + "Model/"; 63 64% Get the valid model folder based on user input. 65model_folder =... 66 getValidInput(general_model_folder, user_choices{1}, "model folder"); 67specific_model_folder = general_model_folder + model_folder; 68 69% Get the valid analysis option based on user input. 70analysis_text =... 71 getValidInput(analysis_options, user_choices{2}, "analysis option"); 72 73% Store the name of the chosen analysis in the settings struct 74settings.analysis = analysis_text; 75 76% Process user input for analysis options 1-5 and 8 77if any(contains(analysis_options([1:5, 8]), analysis_text)) 78 79 % Set settings folder path based on user input 80 settings_folder = specific_model_folder + "/Matlab/Settings/"; 81 settings_file_text =... 82 getValidInput(settings_folder, user_choices{3}, "settings file"); 83 84 % Apply settings and return the settings struct 85 [settings, last_settings_file_text, last_settings_file_date] = ... 86 apply_settings(settings, settings_folder, settings_file_text, ... 87 last_settings_file_date, last_settings_file_text, analysis_options, ... 88 analysis_text, specific_model_folder, functions_cleared, ... 89 model_folders); 90 91 % Process user input for analysis options 6-7 92elseif any(contains(analysis_options(6:7), analysis_text)) 93 94 % Set results folder path 95 results_folder = specific_model_folder + "/Matlab/Results"; 96 97 % Get the analysis to be reproduced based on user input. 98 last_choice = []; 99 prompt = "\nWhat analysis should be reproduced?\n"; 100 101 [r_analysis_text, ~] =... 102 choose_options(results_folder, prompt, last_choice); 103 104 specific_results_folder = results_folder + "/" + ... 105 r_analysis_text; 106 107 % Get the date of the original analysis based on user input. 108 last_choice = []; 109 prompt = "\nWhen was this analysis run originaly?\n"; 110 111 [r_analysis_date_text, ~] =... 112 choose_options(specific_results_folder, prompt, last_choice); 113 114 specific_results_folder_date = specific_results_folder + "/" + ... 115 r_analysis_date_text; 116 117 % Load the settings file and the SBtab struct 118 load(specific_results_folder_date + "/Analysis.mat", "settings", "sb") 119 120 % Set inport to false since we don't want to overwrite anything 121 settings.import = false; 122 123 % If the reproduction of an analysis is chosen, clear the functions 124 % because the settings most likely changed. 125 f_functions_to_clear() 126 127 % If the reproduction of the plots of an analysis is chosen, set the 128 % code to produce plots and load the results that were previously 129 % obtained. 130 if contains(analysis_options(7), analysis_text) 131 % Store the name of the chosen analysis in the settings struct 132 settings.analysis = analysis_text; 133 134 settings.plot = true; 135 load(specific_results_folder_date + "/Analysis.mat", "results") 136 end 137end 138 139% % Store the name of the chosen analysis in the settings struct 140% settings.analysis = analysis_text; 141 142% Set the chosen model folder in the settings struct 143settings.folder_model = model_folder; 144end 145 146function [settings, last_settings_file_text, last_settings_file_date] = ... 147 apply_settings(settings, settings_folder, settings_file_text, ... 148 last_settings_file_date, last_settings_file_text, analysis_options, ... 149 analysis_text, specific_model_folder, functions_cleared, model_folders) 150% Function apply_settings updates the settings based on the chosen settings 151% file and checks if any changes have been made to the settings file or the 152% SBtab since the last analysis 153 154persistent last_SBtab_date 155 156settings_file = strrep(settings_file_text, ".m", ""); 157% Add the default settings to the struct 158stg_add_default = eval("default_settings()"); 159 160% Iterate through the fields of the default settings struct and add them to 161% the settings struct 162f = fieldnames(stg_add_default); 163for i = 1:length(f) 164 settings.(f{i}) = stg_add_default.(f{i}); 165end 166 167% Add chosen settings to the struct overwriting defaults when appropriate 168[stg_add] = eval(settings_file + "()"); 169 170% Iterate through the fields of the chosen settings struct and add them to 171% the settings struct, overwriting the default values if necessary 172f = fieldnames(stg_add); 173for i = 1:length(f) 174 settings.(f{i}) = stg_add.(f{i}); 175end 176 177% Check if the date of the settings file changed, if so clear functions 178listing = dir(settings_folder); 179for n = 1:size(listing, 1) 180 if matches(settings_file_text, listing(n).name, "IgnoreCase", true) 181 settings_file_date = listing(n).date; 182 end 183end 184 185if isempty(last_settings_file_date) 186 settings.import = true; 187else 188 settings.import = false; 189end 190 191% Check if the date of the settings file changed, if so clear functions 192[last_settings_file_date, functions_cleared] = ... 193 compare_and_update(settings_file_date, last_settings_file_date, ... 194 functions_cleared); 195 196% Check if the name of the settings file changed, if so clear functions 197[last_settings_file_text, functions_cleared] = ... 198 compare_and_update(settings_file_text, last_settings_file_text, ... 199 functions_cleared); 200 201% Check if the date of the SBtab changed, if so clear functions 202listing = dir(specific_model_folder); 203for n = 1:size(listing, 1) 204 if matches(settings.sbtab_excel_name, listing(n).name, ... 205 "IgnoreCase", true) 206 sbtab_date = listing(n).date; 207 end 208end 209 210[last_SBtab_date, functions_cleared] = ... 211 compare_and_update(sbtab_date, last_SBtab_date, functions_cleared); 212 213if functions_cleared == 1 214 settings.import = true; 215end 216 217if contains(analysis_options(8), analysis_text) 218 settings.import = true; 219 settings.save_results = false; 220 settings.plot = false; 221end 222end 223 224function valid_input = getValidInput(options, user_choice, input_type) 225% Function getValidInput validates the user input for the model folder, 226% settings file, and analysis option 227 228persistent last_model_folder 229persistent last_analysis_text 230persistent last_settings_file_text 231 232valid_input = user_choice; 233 234% Check the validity of the input based on the input_type 235switch input_type 236 case "model folder" 237 238 % If the input is a valid model folder, return it 239 if isstring(user_choice) && isfolder(options + valid_input) 240 disp("The " + input_type + " chosen was: " + valid_input) 241 return; 242 % Otherwise, prompt the user to choose a valid one 243 else 244 disp("The chosen " + input_type + ... 245 " is not valid, please choose a valid " + input_type) 246 prompt = "What " + input_type + " should be used?\n"; 247 [valid_input, last_model_folder] = ... 248 choose_options(options, prompt, last_model_folder); 249 end 250 251 case "settings file" 252 % If the input is a valid settings file, return it 253 if isstring(user_choice) && isfile(options + valid_input) 254 disp("The " + input_type + " chosen was: " + valid_input) 255 return; 256 % Otherwise, prompt the user to choose a valid one 257 else 258 disp("The chosen " + input_type + ... 259 " is not valid, please choose a valid " + input_type) 260 prompt = "What " + input_type + " should be used?\n"; 261 [valid_input, last_settings_file_text] = ... 262 choose_options(options, prompt, last_settings_file_text); 263 end 264 case "analysis option" 265 % If the input is not a valid analysis, prompt the user to choose a 266 % valid analysis 267 if isstring(user_choice) || ~(user_choice >= 1) || ... 268 ~(user_choice <= 8) 269 disp("The chosen " + input_type + ... 270 " is not valid, please choose a valid " + input_type) 271 prompt = "What " + input_type + " should be used?\n"; 272 [valid_input, last_analysis_text] = ... 273 parse_choices(prompt, options, last_analysis_text); 274 % Otherwise, if the analysis is valid, return it 275 else 276 valid_input = options(user_choice); 277 disp("The " + input_type + " chosen was: " + valid_input) 278 end 279end 280end 281 282function [choice, last_choice] = ... 283 choose_options(folder, prompt, last_choice) 284% Function choose_options helps user to choose valid options from available 285% choices 286 287listing = dir(folder); 288 289% Remove unnecessary entries from the listing 290for n = size(listing, 1): -1: 1 291 if any(matches(listing(n).name, [".", "..", "Place models here.txt"])) 292 listing(n) = []; 293 end 294end 295 296% Create an options array containing the names of the valid choices 297for n = 1:size(listing, 1) 298 folder(n) = string(listing(n).name); 299end 300 301% Call parse_choices to handle user input 302[choice, last_choice] = parse_choices(prompt, folder, last_choice); 303end 304 305function [choice, last_choice] = ... 306 parse_choices(prompt, options, last_choice) 307% Function parse_choices presents a list of choices to the user and 308% validates their input, then returns the chosen option 309 310% Build the prompt string with the available options 311for n = 1:size(options, 2) 312 prompt = prompt + "\n" + n + ": " + options(n); 313end 314 315% If there's a last_choice, include it in the prompt as the default 316if ~isempty(last_choice) 317 if any(contains(options, last_choice)) 318 prompt = prompt + "\n\nPress enter to use " + last_choice; 319 else 320 last_choice = []; 321 end 322end 323 324prompt = prompt + "\n"; 325 326% Get userinput and handle it accordingly 327i = input(prompt); 328 329% If the user input is empty, set the choice to an empty array 330if isempty(i) 331 choice = []; 332 % If the user input is a valid index, set the choice to the 333 % corresponding option 334elseif i > 0 && i < size(options, 2) + 1 335 choice = options(i); 336 disp("The option chosen was: " + choice) 337 % If the user input is invalid, call parse_choices recursively with an 338 % updated prompt 339else 340 prompt = "Please choose from the provided options"; 341 [choice, last_choice] = parse_choices(prompt, options, last_choice); 342end 343 344% If the choice is empty and there's a last_choice, set the choice to 345% last_choice 346if isempty(choice) 347 if ~isempty(last_choice) 348 choice = last_choice; 349 disp("The option chosen was: " + last_choice) 350 else 351 prompt = "Please choose from the provided options"; 352 [choice, last_choice] = parse_choices(prompt, options, last_choice); 353 end 354else 355 last_choice = choice; 356end 357end 358 359function [previous, is_cleared] = ... 360 compare_and_update(current, previous, is_cleared) 361% Function compare_and_update checks if the current and previous values are 362% different and clears the functions if necessary 363 364% If there's a previous value, compare it with the current value 365if ~isempty(previous) 366 % If the current and previous values are different, clear functions if 367 % not already cleared 368 if ~contains(current, previous) 369 if is_cleared == false 370 disp("Settings file changed, clearing functions") 371 f_functions_to_clear() 372 is_cleared = true; 373 end 374 end 375end 376% Update the previous value to the current value 377previous = current; 378end
In this code, the main function f_user_input is responsible for processing user inputs related to model folder, analysis options, and settings file. Based on these inputs, the function returns the necessary settings, results, and SBtab data.
Inputs:
mmf: a struct containing the main folder path.
analysis_options: an array containing the available analysis options.
user_choices: a cell array containing user inputs for the model folder, analysis option, and settings file.
Outputs:
settings: a struct containing the necessary settings for the chosen analysis.
results: a struct containing the results (if any) of the chosen analysis.
sbTab: a struct containing the SBtab data (if any) associated with the chosen analysis.
The main function relies on several helper functions to process the user input, update settings, and handle user choices.
apply_settings: This function updates the settings based on the chosen settings file, and checks if any changes have been made to the settings file or SBtab since the last analysis.Inputs: settings, settings_folder, settings_file_text, last_settings_file_date, last_settings_file_text, analysis_options, analysis_text, specific_model_folder, functions_cleared
Outputs: settings, last_settings_file_text, last_settings_file_date
getValidInput: This function validates the user input for the model folder, settings file, and analysis option, and returns the valid input.Inputs: options, user_choice, input_type
Outputs: valid_input
choose_options: This function helps the user to choose valid options from available choices in a folder.Inputs: folder, prompt, last_choice
Outputs: choice, last_choice
parse_choices: This function presents a list of choices to the user, validates their input, and returns the chosen option.Inputs: prompt, options, last_choice
Outputs: choice, last_choice
compare_and_update: This function compares the current and previous values, and clears functions if necessary.Inputs: current, previous, is_cleared
Outputs: previous, is_cleared
The main function starts by initializing the results, settings, and sbTab variables, and setting the model folder paths. It then calls the getValidInput function to obtain valid user input for the model folder and analysis option. Depending on the user’s chosen analysis option, the code proceeds differently. For analysis options 1-5 and 8, the apply_settings function is called to update the settings. For analysis options 6-7, the function loads the settings file and SBtab struct from a previous analysis, and processes the user input accordingly. Finally, the chosen model folder is set in the settings struct, and the function returns the updated settings, results, and sbTab data.
f_import
Code
1function [settings, sb] = f_import(settings, model_folder) 2% Function f_import: Import a model from an SBtab file, generate model 3% files, and setup necessary inputs for experiments 4% 5% Inputs: 6% - settings: A struct containing settings for the model import process 7% - model_folder: A string specifying the folder where the model and 8% related files should be saved 9% 10% Outputs: 11% - settings: Updated struct with additional information about the number 12% of experiments and outputs 13% - sb: A struct containing data from the imported SBtab file 14% 15% Used Functions: 16% - f_excel_sbtab_importer: Converts an SBtab file into a .mat file and tsv 17% files 18% - f_generate_sbtab_struct: Generates a struct based on the SBtab and 19% updates settings with the number of experiments and outputs 20% - f_sbtab_to_model: Saves the model in .mat, .sbproj, and .xml formats, 21% and creates a data file with required settings for running the model in 22% various experimental settings 23% - f_setup_input: Generates code to load inputs for each experiment into a 24% .mat file and creates code to read these inputs during simulation 25% - f_build_model_exp: Creates .mat files for each experiment containing 26% rules, species, and parameters based on the SBtab for equilibrium, 27% default, and detailed simulation runs 28% 29% Variables: 30% Loaded: 31% - None 32% 33% Initialized: 34% - None 35% 36% Persistent: 37% - None 38 39disp("Generating model files and folder from SBtab") 40 41% Convert the SBtab file into a .mat file and tsv files 42f_excel_sbtab_importer(model_folder); 43 44% Creates a struct based on the SBtab that is used elswhere in the code and 45% also adds the number of experiments and outputs to the settings struct 46[settings, sb] = f_generate_sbtab_struct(settings, model_folder); 47 48% Save the model in .mat, .sbproj, and .xml formats, and create a data file 49% with the required settings for running the model in various experimental 50% settings defined in the SBtab 51f_sbtab_to_model(settings, sb, model_folder) 52 53% Generate code to load inputs for each experiment into a .mat file, and 54% create code to read these inputs during simulation, stored in the Input 55% functions folder 56f_setup_input(settings, model_folder) 57 58% Create three .mat files for each experiment containing the necessary 59% rules, species, and parameters based on the SBtab, for equilibrium, 60% default, and detailed simulation runs 61f_build_model_exp(settings, sb, model_folder) 62 63disp("Model files and folders generated successfully") 64end
Creates the necessary folders inside the model folder. Calls subfunctions that convert the SBtab from an Excel into MATLAB® files useful for the workflow, TSVs and a SBML.
f_excel_sbtab_importer
Code
1function f_excel_sbtab_importer(model_folders) 2% This function, f_excel_sbtab_importer, takes a model_folders structure as 3% input, which contains paths to the source Excel SBtab file and the 4% destination folders for the parsed data (MATLAB .mat file) and TSV files. 5% The function processes the Excel file with multiple sheets in the SBtab 6% format, imports the data from each sheet, replaces missing values with 7% empty spaces, and exports the processed data as .mat and TSV files. 8% 9% Inputs: 10% - model_folders: A structure containing the following fields: 11% - model.sbtab: Path to the source Excel SBtab file. 12% - model.data.sbtab: Path to the destination folder for the parsed .mat 13% file. 14% - model.tsv.model_name: Path to the destination folder for the TSV files. 15% 16% Outputs: - No direct output. The parsed data is saved as .mat and TSV 17% files in the specified folders. 18% 19% Functions called: 20% - impexp: This function is called for each sheet in the Excel SBtab file. 21% It imports the sheet's data, replaces missing values with empty spaces, 22% and exports the processed data as a TSV file. 23% - cell_write_tsv: This function writes the data in a cell array to a TSV 24% file, taking care of transposing the array and converting numeric values 25% to strings. 26% 27% Variables: 28% Loaded: 29% - Source_sbtab: Path to the source Excel SBtab file. 30% - Matlab_sbtab: Path to the destination folder for the parsed .mat file. 31% - sheets: Cell array containing the names of sheets in the Excel SBtab 32% file. 33% - sbtab_excel: A cell array containing the processed data for each sheet. 34% 35% Initialized: 36% - None 37% 38% Persistent: 39% - None 40 41 42% Get the folders for the model SBtab file and the destination for the 43% parsed data 44Source_sbtab = model_folders.model.sbtab; 45Matlab_sbtab = model_folders.model.data.sbtab; 46 47% Get the total number of sheets in the SBTAB 48sheets = sheetnames(Source_sbtab); 49 50% Attempt to run the import of sheets in parallel, depending on the version 51% of Excel being used, this may not work 52try 53 parfor i = 1:size(sheets, 1) 54 sbtab_excel{i} = impexp (i, model_folders); 55 end 56catch 57 for i = 1:size(sheets, 1) 58 sbtab_excel{i} = impexp (i, model_folders); 59 end 60end 61 62% Save the parsed SBTAB tables in .mat format 63save(Matlab_sbtab, 'sbtab_excel'); 64disp("SBtab with " + size(sheets, 1) + " sheets parsed successfully") 65end 66 67function sbtab_excel = impexp (i, model_folders) 68 69% Load the source SBTAB file and the folder to save the TSV files 70Source_sbtab = model_folders.model.sbtab; 71tsv_name_folder = model_folders.model.tsv.model_name; 72 73% Import the SBTAB sheet as a cell array 74sbtab_excel = readcell(Source_sbtab, 'sheet', i); 75 76% Replace missing values with empty spaces 77mask = cellfun(@ismissing, sbtab_excel, 'UniformOutput', false); 78mask = cellfun(@min, mask); 79mask = logical(mask); 80sbtab_excel(mask) = {[]}; 81 82% Get the name for the TSV file to be exported 83field = regexp(sbtab_excel{1, 2}, "TableName='[^']*'", 'match'); 84field = string(replace(field, ["TableName='", "'", " "], ["", "", "_"])); 85 86% Export the TSV file 87cell_write_tsv(tsv_name_folder + field + ".tsv", sbtab_excel) 88end 89 90function cell_write_tsv(filename, origCell) 91 92% Create a new version of the cell for reference 93modCell = origCell; 94 95% Find the indices of numeric cells 96iNum = cellfun(@isnumeric, origCell); 97 98% % Replace numeric cells with cell strings 99for n = 1:size(iNum, 1) 100 for m = 1:size(iNum, 2) 101 modCell(n, m) = cellstr(num2str(origCell{n, m})); 102 end 103end 104 105% Transpose the cell array to have the correct orientation 106modCell = transpose(modCell); 107 108% Create a format string for saving the TSV file 109[rNum, cNum] = size(origCell); 110frmt = repmat([repmat('%s\t', 1, cNum-1), '%s\n'], 1, rNum); 111fid = fopen(filename, 'wt'); 112 113% Save the TSV file using the format string 114fprintf(fid, frmt, modCell{:}); 115fclose(fid); 116end
Loads the information in the SBtab and creates a . mat file that contains the sbtab and TSVs corresponding to all the SBtab tabs.
Inputs - stg
Saves
.mat file containing the SBtab in the “Model/Data” folder
TSVs containing the SBtab in the “Model/tsv” folder
f_generate_sbtab_struct
Code
1function [stg, sb] = f_generate_sbtab_struct(stg, mmf) 2% This function is used to load an SBtab data file, convert the SBtab data 3% into a structure, and extract the number of experiments and outputs. The 4% function takes two input arguments, stg and mmf, and returns two output 5% arguments, the modified stg and the generated sb structure. The function 6% calls the helper function convert_sbtab_to_struct to convert the SBtab 7% data into a structure. The SBtab data file is loaded into the variable 8% sbtab_excel. 9% 10% Inputs: 11% - stg: An existing structure that will be updated with the number of 12% experiments and outputs. 13% - mmf: A structure containing the model information, including the SBtab 14% data file name. 15% 16% Outputs: 17% - stg: The updated structure containing the number of experiments 18% and outputs. 19% - sb: A structure generated from the SBtab data. 20% 21% Called functions: 22% - convert_sbtab_to_struct: A helper function that converts SBtab data 23% into a structure. 24% 25% Variables: 26% Loaded: 27% sbtab_excel: A variable that holds the loaded SBtab data from the 28% specified file. 29% 30% Initialized: 31% - None 32% 33% Persistent: 34% - None 35 36 37% Extract the sbtab file name from the mmf structure 38Matlab_sbtab = mmf.model.data.sbtab; 39 40% Check if the sbtab file exists 41if isfile(Matlab_sbtab) 42 43 % Load the sbtab data into a variable called 'sbtab_excel' 44 load(Matlab_sbtab, 'sbtab_excel'); 45 46 % Convert the sbtab data into a structure 47 sb = convert_sbtab_to_struct(sbtab_excel); 48 49 % Extract the number of experiments and outputs 50 stg.expn = size(sb.Experiments.ID, 1); 51 stg.outn = size(sb.Output.ID, 1); 52end 53end 54 55% Helper function that converts sbtab data into a structure 56function sb = convert_sbtab_to_struct(sbtab_excel) 57 58% Initialize an empty structure 59sb = struct(); 60 61% Loop through all columns in the sbtab data 62for col = 1:size(sbtab_excel, 2) 63 64 % Check if the first row of the column contains a table name 65 if ~isempty(sbtab_excel{1, col}{1, 2}) 66 67 % Extract the table name from the first row of the column 68 field =... 69 regexp(sbtab_excel{1, col}{1, 2}, ... 70 "TableName='([^']*)'", 'tokens'); 71 field = string(replace(field{1}, " ", "_")); 72 73 % Loop through all rows in the column 74 for row = 1:size(sbtab_excel{1, col}, 2) 75 76 % Check if the current row contains a subfield name 77 if ~isempty(sbtab_excel{1, col}{2, row}) 78 % Extract the subfield name from the current row 79 subfield = sbtab_excel{1, col}{2, row}; 80 subfield = regexprep(subfield, '[!>]', ''); 81 subfield = regexprep(subfield, '[:\s]', '_'); 82 83 % Extract the subfield values from the column 84 sb.(field).(subfield)(:, 1) = ... 85 sbtab_excel{1, col}(3:end, row)'; 86 87 % Remove empty values from the subfield 88 sb.(field).(subfield) = sb.(field).(subfield)... 89 (~cellfun('isempty', sb.(field).(subfield))); 90 end 91 end 92 end 93end 94end
Loads the SBtab saved in the .mat file and creates a MATLAB® struct that can be more easily parsed.
f_sbtab_to_model
Code
1function f_sbtab_to_model(stg, sb, mmf) 2% This function, f_sbtab_to_model, converts an SBtab data structure into a 3% model format that can be used for simulations and analysis. It then saves 4% the model in .mat, .sbproj, and .xml formats for future use. The function 5% also processes experimental settings defined in the SBtab data structure, 6% adding compartments, species, parameters, reactions, expressions, inputs, 7% constants, and boundary conditions to the model. 8% 9% Inputs: 10% - stg: Settings structure containing configuration information 11% - sb: SBtab data structure containing information about species, 12% reactions, compartments, and parameters 13% - mmf: Model management files structure containing the paths to save the 14% model 15% 16% Outputs: 17% - No direct outputs, but the function saves the model in .mat, .sbproj, 18% and .xml formats 19% 20% Used Functions: 21% - add_reactions_to_model: Adds reactions from the SBtab data structure to 22% the model object 23% - set_boundary_Condition: Sets boundary conditions for the model 24% - add_expressions_to_model: Adds expressions from the SBtab data 25% structure to the model object 26% - add_inputs_to_model: Adds inputs from the SBtab data structure to the 27% model object 28% - add_constants_to_model: Adds constants from the SBtab data structure to 29% the model object 30% - process_experiments: Processes experimental data from the SBtab data 31% structure 32% 33% Variables 34% Loaded: 35% - sbtab.species: Species related data from the SBtab data structure 36% - sbtab.defpar: Default parameter related data from the SBtab data 37% structure 38% - sbtab.sim_time: Simulation time extracted from the SBtab data structure 39% 40% Initialized: 41% - modelobj: Initialized model object 42% - compobj: Initialized compartment object 43% 44% Persistent: 45% - None 46 47% Initialize the model object and compartment object 48modelobj = sbiomodel(stg.name); 49compobj = []; 50 51% Combine species related data into sbtab.species 52sbtab.species = ... 53 [sb.Compound.Name, sb.Compound.InitialValue, sb.Compound.IsConstant, ... 54 sb.Compound.Unit, sb.Compound.Location]; 55% Combine default parameter related data into sbtab.defpar 56sbtab.defpar = ... 57 [sb.Parameter.Comment, sb.Parameter.Value_linspace, sb.Parameter.Unit]; 58 59% Add compartments to the model Iterate through each compartment in the 60% SBtab data structure and add it to the model 61for n = 1:size(sb.Compartment.ID, 2) 62 compobj{n} = addcompartment(modelobj, sb.Compartment.Name{n}); 63 set(compobj{n}, 'CapacityUnits', sb.Compartment.Unit{n}); 64 set(compobj{n}, 'Value', sb.Compartment.Size{n}); 65end 66 67% Add species to the compartments Iterate through each species in the SBtab 68% data structure and add it to the appropriate compartment 69for n = 1:size(sbtab.species, 1) 70 compartment_number_match = ... 71 find_compartment_number(compobj, sb.Compound.Location{n}); 72 addspecies (compobj{compartment_number_match}, sb.Compound.Name{n}, ... 73 sb.Compound.InitialValue{n}, ... 74 'InitialAmountUnits', sb.Compound.Unit{n}); 75end 76 77% Add species to the compartments Iterate through each species in the SBtab 78% data structure and add it to the appropriate compartment 79for n = 1:size(sbtab.defpar, 1) 80 addparameter(modelobj, sb.Parameter.Name{n}, ... 81 sb.Parameter.Value_linspace{n}, 'ValueUnits', ... 82 sb.Parameter.Unit{n}, 'Notes', sb.Parameter.Comment{n}); 83end 84 85% Add reactions, expressions, inputs, constants, and boundary conditions to 86% the model 87modelobj = add_reactions_to_model(sb, modelobj); 88modelobj = set_boundary_Condition(sb, modelobj); 89modelobj = add_expressions_to_model(sb, modelobj); 90modelobj = add_inputs_to_model(sb, modelobj); 91modelobj = add_constants_to_model(sb, modelobj); 92 93% Extract simulation time from the SBtab data structure 94sbtab.sim_time = [sb.Experiments.Sim_Time{:}]; 95% Process experimental data from the SBtab data structure 96[sbtab, Data] = process_experiments(sb, sbtab); 97 98% Save the model in .mat, .sbproj, and .xml formats 99sbproj_model = mmf.model.data.sbproj_model; 100matlab_model = mmf.model.data.mat_model; 101data_model = mmf.model.data.data_model; 102xml_model = mmf.model.data.xml_model; 103 104sbiosaveproject(sbproj_model, 'modelobj') 105save(matlab_model, 'modelobj') 106save(data_model, 'Data', 'sbtab', 'sb') 107sbmlexport(modelobj, xml_model) 108end 109 110function modelobj = add_constants_to_model(sb, modelobj) 111% This function adds constants from sb to the given model object. This 112% function checks if the sb structure has a "Constant" field, and if so, 113% iterates through the constants and adds them as parameters to the model 114% object. 115 116% Check if the sb object has a "Constant" field 117if isfield(sb, "Constant") 118 % Iterate through the constants and add them to the model object 119 for m = 1:size(sb.Constant.ID, 1) 120 addparameter(modelobj, char(sb.Constant.Name(m)), ... 121 str2double(string(sb.Constant.Value{m})), ... 122 'ValueUnits', sb.Constant.Unit{m}); 123 end 124end 125end 126 127function modelobj = add_inputs_to_model(sb, modelobj) 128% This function adds inputs from sb to the given model object. This 129% function checks if the sb structure has an "Input" field, and if so, 130% iterates through the inputs and adds them as parameters, species, and 131% rules to the model object according to the input properties. 132 133% Check if the sb structure contains the 'Input' field 134if isfield(sb, "Input") 135 % Iterate through all inputs 136 for m = 1:size(sb.Input.ID, 1) 137 % Check if the input contains the 'Formula' field 138 if isfield(sb.Input, 'Formula') 139 % If the input formula is a double, add it as a species 140 if isa(sb.Input.Formula{m}, 'double') 141 addspecies (modelobj, char(sb.Input.Name(m)), ... 142 str2double(string(sb.Input.DefaultValue{m})), ... 143 'InitialAmountUnits', sb.Input.Unit{m}); 144 % Otherwise, try adding it as a species with initial amount 145 % 0 146 else 147 try 148 addspecies (modelobj, char(sb.Input.Name(m)), 0, ... 149 'InitialAmountUnits', sb.Input.Unit{m}); 150 catch 151 end 152 % Add a rule for the species using the input formula 153 addrule(modelobj, char({convertStringsToChars(... 154 string(sb.Input.Location{m}) + "." + ... 155 string(sb.Input.Name{m}) + " = " + ... 156 string(sb.Input.DefaultValue{m}))}), ... 157 'repeatedAssignment'); 158 end 159 else 160 % If no 'Formula' field, add the input as a parameter 161 addparameter(modelobj, char(sb.Input.Name(m)), ... 162 str2double(string(sb.Input.DefaultValue{m})), ... 163 'ValueUnits', sb.Input.Unit{m}); 164 end 165 end 166end 167end 168 169function compartment_number = find_compartment_number(compobj, location) 170% This function finds the compartment number in compobj corresponding to 171% the given location. This function iterates through all compartments in 172% compobj and returns the index of the compartment whose name matches the 173% given location. 174 175% Iterate through all compartments 176for m = 1:size(compobj, 2) 177 % Check if the current compartment's name matches the given location 178 if strcmp(compobj{m}.Name, location) 179 % If it matches, return the index and break the loop 180 compartment_number = m; 181 break; 182 end 183end 184end 185 186function [sbtab, Data] = process_experiments(sb, sbtab) 187% This function processes experiments from sb and stores data in sbtab and 188% Data. This function extracts relevant data from sb, a structured 189% representation of an SBML model, and stores it in sbtab, a structured 190% representation of an SBtab file, and Data structures, used for further 191% analysis and processing. 192 193% Initialize species_inp_indices to store the indices of species present in 194% sb.Experiments 195species_inp_indices = {}; 196% Iterate through sb.Compound.ID to find species present in sb.Experiments 197for n = 1:size(sb.Compound.ID, 1) 198 field_name = "S" + (n - 1); 199 % Check if sb.Experiments has the field specified in field_name 200 if isfield(sb.Experiments, field_name) 201 species_inp_indices{end + 1, 1} = n; 202 end 203end 204 205% Iterate through sb.Experiments.ID to process each experiment 206for n = 1:size(sb.Experiments.ID, 1) 207 start_amount = cell(1, size(species_inp_indices, 1)); 208 n_start_amount = 0; 209 n_input_time = 0; 210 n_input = 0; 211 n_output = 0; 212 213 214 % Check if sb.Experiments has a Normalize field, and store it in 215 % sbtab.datasets(n).Normalize 216 if isfield(sb.Experiments, "Normalize") 217 if sb.Experiments.Normalize{n} ~= 0 218 sbtab.datasets(n).Normalize = sb.Experiments.Normalize{n}; 219 else 220 sbtab.datasets(n).Normalize = []; 221 end 222 else 223 sbtab.datasets(n).Normalize = []; 224 end 225 226 % Retrieve the Time data for the current experiment and store it in 227 % Data(n).Experiment.t 228 experiment_field_name = "E" + (n - 1); 229 if isfield(sb.(experiment_field_name), "Time") 230 Data(n).Experiment.t = ... 231 transpose([sb.(experiment_field_name).Time{:}]); 232 end 233 234 % Process input species data for the current experiment 235 experiment_input_field_name = "E" + (n - 1) + "I"; 236 start_amount_name = cell(1, size(species_inp_indices, 1)); 237 for m = 1:size(sb.Compound.ID, 1) 238 field_name = "S" + (m - 1); 239 if isfield(sb.Experiments, field_name) 240 n_start_amount = n_start_amount + 1; 241 start_amount{n_start_amount} = sb.Experiments.(field_name)(n); 242 start_amount_name{n_start_amount} = sb.Compound.Name(m); 243 end 244 % Retrieve input time data for the current experiment and species 245 if isfield(sb.(experiment_input_field_name), ... 246 "Input_Time_S" + (m - 1)) 247 n_input_time = n_input_time + 1; 248 sbtab.datasets(n).input_time{1, n_input_time} = ... 249 [sb.(experiment_input_field_name).("Input_Time_S" + ... 250 (m - 1)){:}]; 251 end 252 % Retrieve input value data for the current experiment and species 253 if isfield(sb.(experiment_input_field_name), "S" + (m - 1)) 254 n_input = n_input + 1; 255 sbtab.datasets(n).input_value{1, n_input} = ... 256 [sb.(experiment_input_field_name).("S" + (m - 1)){:}]; 257 sbtab.datasets(n).input{n_input} = char("S" + (m - 1)); 258 end 259 end 260 261 % Process output data for the current experiment 262 for m = 1:size(sb.Output.ID, 1) 263 if isfield(sb.(experiment_field_name), "Y" + (m - 1)) 264 n_output = n_output + 1; 265 % Retrieve output values for the current experiment and output 266 Data(n).Experiment.x(:, n_output) = ... 267 [sb.(experiment_field_name).("Y" + (m - 1)){:}]; 268 % Retrieve standard deviation of output values for the current 269 % experiment and output 270 Data(n).Experiment.x_SD(:, n_output) = .... 271 [sb.(experiment_field_name).("SD_Y" + (m - 1)){:}]; 272 % Store output related information in sbtab.datasets(n) 273 sbtab.datasets(n).output{n_output} = sb.Output.Name(m); 274 sbtab.datasets(n).output_value{n_output} = ... 275 {convertStringsToChars(... 276 strrep(string(sb.Output.Location{m}) + "." + ... 277 string(sb.Output.Name{m}) + " = " + ... 278 string(sb.Output.Formula{m}), 'eps', '0.0001'))}; 279 sbtab.datasets(n).output_unit{n_output} = sb.Output.Unit{m}; 280 sbtab.datasets(n).output_name{n_output} = sb.Output.Name(m); 281 sbtab.datasets(n).output_ID{n_output} = sb.Output.ID(m); 282 sbtab.datasets(n).output_location{n_output} = ... 283 sb.Output.Location(m); 284 end 285 end 286 % Store output count and start amount information in sbtab.datasets(n) 287 sbtab.datasets(n).stg.outnumber = n_output; 288 sbtab.datasets(n).start_amount = cat(2, start_amount_name(:), ... 289 transpose([start_amount{:}]), species_inp_indices); 290end 291end 292 293 294function model_obj = add_expressions_to_model(sb, model_obj) 295% This function adds expressions to the given model object by iterating 296% through sb.Expression fields and populating the model object with 297% parameters, species, and rules according to the expression properties 298 299% Check if the sb structure contains the 'Expression' field 300if isfield(sb, "Expression") 301 % Iterate through all expressions 302 for m = 1:size(sb.Expression.ID, 1) 303 % Check if the expression contains the 'Formula' field 304 if isfield(sb.Expression, 'Formula') 305 % If the expression formula is a double, add it as a species 306 if isa(sb.Expression.Formula{m}, 'double') 307 addspecies (model_obj, char(sb.Expression.Name(m)), ... 308 str2double(string(sb.Expression.Formula{m})), ... 309 'InitialAmountUnits', sb.Expression.Unit{m}); 310 % Otherwise, try adding it as a species with initial amount 311 % 0 312 else 313 try 314 addspecies (model_obj, char(sb.Expression.Name(m)), 0, ... 315 'InitialAmountUnits', sb.Expression.Unit{m}); 316 catch 317 end 318 % Add a rule for the species using the expression formula 319 addrule(model_obj, char({convertStringsToChars(... 320 string(sb.Expression.Location{m}) + "." + ... 321 string(sb.Expression.Name{m}) + " = " + ... 322 string(sb.Expression.Formula{m}))}), ... 323 'repeatedAssignment'); 324 end 325 else 326 % If no 'Formula' field, add the expression as a parameter 327 addparameter(model_obj, char(sb.Expression.Name(m)), ... 328 str2double(string(sb.Expression.DefaultValue{m})), ... 329 'ValueUnits', sb.Expression.Unit{m}); 330 end 331 end 332end 333end 334 335function model_obj = add_reactions_to_model(sb, model_obj) 336 337num_reactions = size(sb.Reaction.ID, 1); 338num_compounds = size(sb.Compound.Name, 1); 339 340% Add reactions to the model 341for reaction_idx = 1:num_reactions 342 343 is_reversible = sb.Reaction.IsReversible{reaction_idx}; 344 reaction_formula = sb.Reaction.ReactionFormula{reaction_idx}; 345 location = sb.Reaction.Location{reaction_idx}; 346 347 % Determine reaction reversibility and modify reaction_name accordingly 348 if ischar(is_reversible) 349 if contains(is_reversible, "true", 'IgnoreCase', true) 350 arrow = ' <-> '; 351 else 352 arrow = ' -> '; 353 end 354 else 355 if is_reversible 356 arrow = ' <-> '; 357 else 358 arrow = ' -> '; 359 end 360 end 361 reaction = strrep(reaction_formula, '<=>', arrow); 362 % Add compartment location to the reaction name 363 for compound_idx = 1:num_compounds 364 compound_name = string(sb.Compound.Name{compound_idx}); 365 reaction = insertBefore(string(reaction), " " + compound_name, ... 366 " " + location); 367 end 368 369 % Remove extra locations that were added when patterns get recognized 370 % twice because we are not matching properly 371 while contains(reaction, location + " " + location) 372 reaction = strrep(reaction, location + " " + location, " " + ... 373 location); 374 end 375 376 % Remove unnecessary spaces and characters 377 while contains(reaction, " ") 378 reaction = strrep(reaction, " ", " "); 379 end 380 381 % Replace the space between the location and the species with a dot 382 reaction = strrep(reaction, ... 383 location + " ", location + "."); 384 385 % Add the location to the first species of the reaction 386 reaction = location + "." + reaction; 387 388 % Add the reaction to the model 389 reaction_object = addreaction(model_obj, reaction); 390 set(reaction_object, 'ReactionRate', ... 391 sb.Reaction.KineticLaw{reaction_idx}); 392end 393end 394 395function model_obj = set_boundary_Condition(sb, model_obj) 396% This function sets the boundary conditions for the species in a model 397% object based on information in the sb structure. 398 399% Loop over each compound in the sb structure 400for n = 1:size(sb.Compound.ID, 1) 401 402 % Extract information about the boundary condition for the current 403 % compound 404 assignment = sb.Compound.Assignment{n}; 405 interpolation = sb.Compound.Interpolation{n}; 406 is_constant = sb.Compound.IsConstant{n}; 407 408 % Determine whether the current compound has a boundary condition set 409 if ischar(assignment) && contains(lower(assignment), "true") 410 % If the assignment field is the string "true", set the boundary 411 % condition to 1 412 Boundary_Condition = 1; 413 elseif isnumeric(assignment) && assignment == 1 414 % If the assignment field is the number 1, set the boundary 415 % condition to 1 416 Boundary_Condition = 1; 417 elseif assignment 418 Boundary_Condition = 1; 419 elseif ischar(interpolation) && contains(lower(interpolation), "true") 420 % If the interpolation field is the string "true", set the boundary 421 % condition to 1 422 Boundary_Condition = 1; 423 elseif isnumeric(interpolation) && interpolation == 1 424 % If the interpolation field is the number 1, set the boundary 425 % condition to 1 426 Boundary_Condition = 1; 427 elseif interpolation 428 Boundary_Condition = 1; 429 elseif ischar(is_constant) && contains(lower(is_constant), "true") 430 % If the is_constant field is the string "true", set the boundary 431 % condition to 1 432 Boundary_Condition = 1; 433 elseif isnumeric(is_constant) && is_constant == 1 434 % If the is_constant field is the number 1, set the boundary 435 % condition to 1 436 Boundary_Condition = 1; 437 elseif is_constant 438 Boundary_Condition = 1; 439 else 440 % If none of the fields indicate a boundary condition, set the 441 % boundary condition to 0 442 Boundary_Condition = 0; 443 end 444 445 model_obj.species(n).BoundaryCondition = Boundary_Condition; 446end 447end
This function, f_sbtab_to_model, converts an SBtab data structure into a model format that can be used for simulations and analysis. It then saves the model in .mat, .sbproj, and .xml formats for future use. The function also processes experimental settings defined in the SBtab data structure, adding compartments, species, parameters, reactions, expressions, inputs, constants, and boundary conditions to the model.
Inputs
stg: A structure containing the settings for the model conversion.
sb: An SBtab data structure containing the model data.
mmf: A structure containing the file names for saving the model in different formats.
Outputs
The function saves the generated model in .mat, .sbproj, and SBML(.xml) formats.
Functions called:
addcompartment: Adds a compartment to the SimBiology model object.
addspecies: Adds a species to a specific compartment within the model.
addparameter: Adds a parameter to the model, including its value, unit, and associated notes.
find_compartment_number: Locates the index of the compartment based on its name within the compobj cell array.
add_reactions_to_model: Adds reactions to the model by processing the reaction-related data in the SBtab data structure.
set_boundary_Condition: Sets the boundary conditions for the model using the information provided in the SBtab data structure.
add_expressions_to_model: Adds algebraic expressions to the model using the information provided in the SBtab data structure.
add_inputs_to_model: Adds input variables to the model using the information provided in the SBtab data structure.
add_constants_to_model: Adds constant variables to the model using the information provided in the SBtab data structure.
process_experiments: Processes experimental data from the SBtab data structure and returns the updated SBtab and a Data structure containing the processed experimental data.
sbiosaveproject: Saves the SimBiology model object as an .sbproj file.
save: Saves the SimBiology model object as a .mat file, and the experimental data as a separate .mat file.
sbmlexport: Exports the SimBiology model object as an .xml file in the Systems Biology Markup Language (SBML) format.
Loaded variables:
modelobj: A SimBiology model object.
compobj: A cell array containing compartment objects.
sbtab.species: A table containing species-related data.
sbtab.defpar: A table containing default parameter-related data.
sbtab.sim_time: A table containing simulation time data.
Data: A structure containing processed experimental data.
sbproj_model, matlab_model, data_model, xml_model: Variables for saving the model in .sbproj, .mat, SBML(.xml) formats, and the experimental data(file), respectively.
f_setup_input
Code
1function f_setup_input(stg, mmf) 2% The f_setup_input function is designed to generate code for loading 3% experiment inputs into a .mat file and create code to read these inputs 4% during the simulation of the experiments. The generated code is stored in 5% the "Input_functions" folder. 6% 7% Inputs: 8% - stg: A structure containing information about the simulation settings. 9% - mmf: A structure containing information about the model, including the 10% model data, main folder, and input functions. 11% 12% Outputs: 13% - This function creates input function files and an input creator 14% function file in the "Input_functions" folder. The input functions are 15% used to calculate input values based on the simulation time, while the 16% input creator function is used to create input data from the 17% sbtab.datasets. 18% 19% Used Functions : 20% - template1: Generates code for input functions. 21% - template2: Generates code for the first input of the first experiment 22% in the input creator function. 23% - template3: Generates code for the rest of the inputs in the input 24% creator function. 25% 26% Loaded Variables: 27% - matlab_model: Loaded from mmf.model.data.mat_model. 28% - data_model: Loaded from mmf.model.data.data_model. 29% - inp_model_data: Loaded from mmf.model.data.input_model_data. 30% - Model_folder: Loaded from mmf.model.main. 31% - model_input: Loaded from mmf.model.input_functions.input. 32% - sbtab: Loaded from the data_model file. 33% - modelobj: Loaded from the matlab_model file. 34 35 36% Load required data from mmf.model.data: 37matlab_model = mmf.model.data.mat_model; 38data_model = mmf.model.data.data_model; 39inp_model_data = mmf.model.data.input_model_data; 40Model_folder = mmf.model.main; 41model_input = mmf.model.input_functions.input; 42 43% Load the sbtab and modelobj variables from the respective files: 44load(data_model, 'sbtab') 45load(matlab_model, 'modelobj'); 46 47% Iterate over the experiments and their inputs to generate input functions 48% and an input creator function: 49for Exp_n = 1:size(sbtab.datasets, 2) 50 for index = 1:size(sbtab.datasets(Exp_n).input, 2) 51 % If input size is larger than 100, generate input function file 52 % for each input 53 if size(sbtab.datasets(Exp_n).input_value{index}, 2) > 100 54 55 % Generate input names by replacing "." with an empty string, 56 % and concatenating the "X", "T", "h1", and "h2" suffixes: 57 input_name = strrep(modelobj.species(1 + str2double(strrep(... 58 sbtab.datasets(Exp_n).input(index), 'S', ''))).name, ".", ""); 59 input_X = input_name + "X"; 60 input_T = input_name + "T"; 61 input_h1 = input_name + "h1"; 62 input_h2 = input_name + "h2"; 63 input_h3 = input_name + "h3"; 64 65 % Create a new .m file for each input and write the generated 66 % code to that file, based on the template1() function: 67 fullFileName = sprintf('%s.m', ... 68 model_input + Exp_n + "_" + input_name ); 69 70 fileID = fopen(fullFileName, 'wt'); 71 72 inp_str = template1(); 73 inp_str = replace(inp_str, ... 74 ["SBtab_name", "Exp_n", "input_name", ... 75 "input_X", "input_T", "input_h1", "input_h2", "input_h3", "inp_model_data", ... 76 "sbtab.sim_time(Exp_n)"], [stg.name, Exp_n, ... 77 input_name, input_X, input_T, input_h1, ... 78 input_h2, input_h3, inp_model_data, ... 79 sbtab.sim_time(Exp_n)]); 80 81 fprintf(fileID, inp_str); 82 fclose(fileID); 83 end 84 end 85end 86 87% Create the input creator function file: 88fullFileName = sprintf('%s.m', model_input + "_creator" ); 89fileID = fopen(fullFileName, 'wt'); 90 91% Write the content of the input creator function: 92fprintf(fileID, "function " + stg.name + "_input_creator(~)\n"); 93helper = 0; 94for Exp_n = 1:size(sbtab.datasets, 2) 95 for index =1:size(sbtab.datasets(Exp_n).input, 2) 96 if size(sbtab.datasets(Exp_n).input_value{index}, 2) > 100 97 input_name = strrep(modelobj.species(1 + str2double(strrep(... 98 sbtab.datasets(Exp_n).input(index), 'S', ''))).name, ".", ""); 99 if helper == 0 100 helper = 1; 101 helper2 = Exp_n; 102 end 103 % Write code to the input creator function file, using either 104 % template2() or template3() functions: 105 if index == 1 && Exp_n == helper2 106 fprintf(fileID, "load('" + data_model + "', 'sbtab');\n"); 107 inp_creator_str = template2(); 108 inp_creator_str = replace(inp_creator_str, ... 109 ["Exp_n", "input_name", "index", "inp_model_data"], ... 110 [Exp_n, input_name, index, inp_model_data]); 111 else 112 inp_creator_str = template3(); 113 inp_creator_str = replace(inp_creator_str, ... 114 ["Exp_n", "input_name", "index", "inp_model_data"], ... 115 [Exp_n, input_name, index, inp_model_data]); 116 end 117 fprintf(fileID, inp_creator_str); 118 end 119 end 120end 121fprintf(fileID, "end\n"); 122fclose(fileID); 123 124eval(stg.name + "_input_creator()"); 125end 126 127% The template1() function generates the code for the input functions, 128% which calculate the input based on the simulation time. 129function inp_str = template1() 130inp_str =... 131 "function thisAmp = SBtab_name_inputExp_n_input_name(times)\n" + ... 132 "persistent input_X\n" + ... 133 "persistent input_T\n" + ... 134 "persistent input_h1\n" + ... 135 "persistent input_h2\n" + ... 136 "if isempty(input_X)\n" + ... 137 "Data = coder.load('inp_model_data', 'expExp_n_input_name');\n" + ... 138 "input_X = Data.expExp_n_input_name(:, 2);\n" + ... 139 "input_T = Data.expExp_n_input_name(:, 1);\n" + ... 140 "input_h2 = input_T(2)-input_T(1);\n" + ... 141 "input_h1 = 1;\n" + ... 142 "thisAmp = input_X(1);\n" + ... 143 "elseif times <= 0\n" + ... 144 "thisAmp = input_X(1);\n" + ... 145 "elseif times >= 20\n" + ... 146 "thisAmp = input_X(end);\n" + ... 147 "else\n" + ... 148 "while times > input_T(input_h1)\n" + ... 149 "input_h1 = input_h1 + 1;\n" + ... 150 "end\n" + ... 151 "while times < input_T(input_h1-1)\n" + ... 152 "input_h1 = input_h1-1;\n" + ... 153 "end\n" + ... 154 "input_h3 = (input_T(input_h1)-times)/input_h2;\n" + ... 155 "thisAmp = input_X(input_h1-1)*input_h3 + input_X(input_h1)*(1-input_h3);\n" + ... 156 "end\n" + ... 157 "end"; 158end 159 160% The template2() function generates the code for the first input of the 161% first experiment in the "_input_creator()" function. 162function inp_creator_str = template2() 163inp_creator_str = ... 164 "expExp_n_input_name(:, 1) = sbtab.datasets(Exp_n).input_time{index};\n" + ... 165 "expExp_n_input_name(:, 2) = sbtab.datasets(Exp_n).input_value{index};\n" + ... 166 "save('inp_model_data', 'expExp_n_input_name');\n"; 167end 168 169% The template3() function generates the code for the rest of the inputs in 170% the "_input_creator()" function. 171function inp_creator_str = template3() 172inp_creator_str = ... 173 "expExp_n_input_name(:, 1) = sbtab.datasets(Exp_n).input_time{index};\n" + ... 174 "expExp_n_input_name(:, 2) = sbtab.datasets(Exp_n).input_value{index};\n" + ... 175 "save('inp_model_data', 'expExp_n_input_name', '-append');\n"; 176end
The f_setup_input function is designed to generate code for loading experiment inputs into a .mat file and create code to read these inputs during the simulation of the experiments. The generated code is stored in the “Input_functions” folder.
- param stg:
A structure containing information about the simulation settings.
- type stg:
structure
- param mmf:
A structure containing information about the model, including the model data, main folder, and input functions.
- type mmf:
structure
- return:
This function creates input function files and an input creator function file in the “Input_functions” folder. The input functions are used to calculate input values based on the simulation time, while the input creator function is used to create input data from the sbtab.datasets.
- rtype:
None
The function calls the following helper functions:
template1: Generates code for input functions.
template2: Generates code for the first input of the first experiment in the input creator function.
template3: Generates code for the rest of the inputs in the input creator function.
The function loads the following variables:
matlab_model: Loaded from mmf.model.data.mat_model.
data_model: Loaded from mmf.model.data.data_model.
inp_model_data: Loaded from mmf.model.data.input_model_data.
Model_folder: Loaded from mmf.model.main.
model_input: Loaded from mmf.model.input_functions.input.
sbtab: Loaded from the data_model file.
modelobj: Loaded from the matlab_model file.
f_build_model_exp
Code
1function f_build_model_exp(stg, sb, mmf) 2% This function generates .mat files for equilibrium and proper simulation 3% runs for a set of experiments. It reads experiment settings from an sbtab 4% structure, configures the simulation settings, processes input and output 5% species, and saves the resulting .mat files. 6% 7% Inputs: 8% - stg: A structure containing settings for the simulations, including 9% maximum wall clock time, stop times, dimensional analysis, unit 10% conversion, tolerances, step sizes, and time units. 11% - sb: An sbtab structure containing information about experiments, such 12% as output values, output species, output units, input times, input 13% values, and input species. 14% - mmf: A model management framework structure containing the data and mat 15% models, which include data_model, mat_model, model_exp_eq, 16% model_exp_default, and model_exp_detail. 17% 18% Outputs: 19% - Equilibrium and proper simulation run .mat files for each experiment, 20% saved with filenames based on model_exp_eq, model_exp_default, and 21% model_exp_detail. 22% 23% Called Functions: 24% - getconfigset: Retrieves the configuration set object from a SimBiology 25% model. 26% - copyobj: Creates a copy of a SimBiology model object. 27% - set: Sets properties of a SimBiology object. 28% - load: Loads variables from .mat files. 29% - save: Saves variables to .mat files. 30% - addspecies: Adds species to a SimBiology model compartment. 31% - addrule: Adds rules to a SimBiology model. 32% - addparameter: Adds parameters to a SimBiology model. 33% - addevent: Adds events to a SimBiology model. 34% 35% Variables: 36% Loaded: 37% - data_model: File path of the data_model .mat file containing Data and 38% sbtab. 39% - mat_model: File path of the mat_model .mat file containing the 40% SimBiology model object. 41% - model_exp_eq: File path prefix for saving equilibrium simulation run 42% .mat files. 43% - model_exp_default: File path prefix for saving proper simulation run 44% .mat files. 45% - model_exp_detail: File path prefix for saving detailed simulation run 46% .mat files. 47% - Data: Data structure containing experiment time points. 48% - sbtab: sbtab structure containing experiment settings and information. 49% - modelobj: SimBiology model object loaded from the mat_model file. 50% 51% Initialized: 52% - None 53% 54% Persistent: 55% - None 56% 57% Notes: 58% - The function iterates through all experiments, configuring simulation 59% settings and processing species for each experiment, then saves the 60% corresponding .mat files. 61 62% Load data_model and mat_model files 63data_model = mmf.model.data.data_model; 64mat_model = mmf.model.data.mat_model; 65model_exp_eq = mmf.model.data.model_exp.equilibration; 66model_exp_default = mmf.model.data.model_exp.default; 67model_exp_detail = mmf.model.data.model_exp.detail; 68 69% Load Data and modelobj from data_model and mat_model files 70load(data_model, 'Data', 'sbtab') 71load(mat_model, 'modelobj'); 72 73% Initialize model_run and configsetObj arrays 74model_run = cell(size(sb.Experiments.ID, 1), 1); 75configsetObj = cell(size(sb.Experiments.ID, 1), 1); 76 77% Loop through all experiments 78for number_exp = 1:size(sb.Experiments.ID, 1) 79 80 % Load sbtab dataset information 81 output_value = sbtab.datasets(number_exp).output_value; 82 output = sbtab.datasets(number_exp).output; 83 output_unit = sbtab.datasets(number_exp).output_unit; 84 input_time = sbtab.datasets(number_exp).input_time; 85 input_value = sbtab.datasets(number_exp).input_value; 86 input_species = sbtab.datasets(number_exp).input; 87 88 % Initialize model and configuration set objects for the current 89 % experiment 90 model_run{number_exp} = copyobj(modelobj); 91 configsetObj{number_exp} = getconfigset(model_run{number_exp}); 92 93 % Configure simulation settings for the equilibrium simulation run 94 set(configsetObj{number_exp}, 'MaximumWallClock', 0.2); 95 set(configsetObj{number_exp}, 'StopTime', stg.eqt); 96 set(configsetObj{number_exp}.CompileOptions, ... 97 'DimensionalAnalysis', stg.dimenanal); 98 set(configsetObj{number_exp}.CompileOptions, ... 99 'UnitConversion', stg.UnitConversion); 100 set(configsetObj{number_exp}.SolverOptions, ... 101 'AbsoluteToleranceScaling', stg.abstolscale); 102 set(configsetObj{number_exp}.SolverOptions, ... 103 'RelativeTolerance', stg.reltol); 104 set(configsetObj{number_exp}.SolverOptions, ... 105 'AbsoluteTolerance', stg.abstol); 106 set(configsetObj{number_exp}.SolverOptions, ... 107 'AbsoluteToleranceStepSize', stg.abstolstepsize_eq); 108 helper = [0,10 .^ (-20: 0.01: log10(stg.eqt))]; 109 if helper(end) ~= stg.eqt 110 helper = [helper,stg.eqt]; 111 end 112 113 set(configsetObj{number_exp}.SolverOptions, 'OutputTimes', ... 114 helper); 115 set(configsetObj{number_exp}, 'TimeUnits', stg.simtime); 116 set(configsetObj{number_exp}.SolverOptions, 'MaxStep', stg.maxstepeq); 117 118 % Save equilibrium simulation run .mat file 119 model_exp = model_run{number_exp}; 120 config_exp = configsetObj{number_exp}; 121 save(model_exp_eq + number_exp + ".mat", 'model_exp', 'config_exp') 122 sbiosaveproject(model_exp_eq + number_exp, 'modelobj') 123 124 % Update simulation settings for the proper simulation run 125 set(configsetObj{number_exp}, 'MaximumWallClock', stg.maxt); 126 set(configsetObj{number_exp}, 'StopTime', sbtab.sim_time(number_exp)); 127 set(configsetObj{number_exp}.SolverOptions, 'OutputTimes', ... 128 Data(number_exp).Experiment.t); 129 set(configsetObj{number_exp}.SolverOptions, 'MaxStep', stg.maxstep); 130 131 % Process output species. Adds output species and rules 132 for n = 1:size(output, 2) 133 % Check if output species exist in the model 134 m = 0; 135 for k = 1:size(model_run{number_exp}.species, 1) 136 if model_run{number_exp}.species(k).name == ... 137 string(output{1, n}) 138 model_run{number_exp}.species(k).BoundaryCondition = 1; 139 m = 1; 140 end 141 end 142 % If output species does not exist, add it to the model 143 if m == 0 144 if strcmp( output_unit{1, n}, 'dimensionless' ) 145 warning('off', 'SimBiology:InvalidSpeciesInitAmtUnits') 146 else 147 warning('on', 'SimBiology:InvalidSpeciesInitAmtUnits') 148 end 149 addspecies (model_run{number_exp}.Compartments(1), ... 150 char(output{1, n}), 0, ... 151 'InitialAmountUnits', output_unit{1, n}); 152 end 153 % Add repeated assignment rule for output species 154 addrule(model_run{number_exp}, char(output_value{1, n}), ... 155 'repeatedAssignment'); 156 end 157 158 % Process input species. Adds input species and rules, either as events 159 % or repeated assignments 160 for j = 1:size(input_species, 2) 161 162 input_indexcode = str2double(strrep(input_species(j), 'S', '')); 163 input_name = string(model_run{number_exp}.species(1 + ... 164 input_indexcode).name); 165 166 % If the input time is less than 100, add events 167 if size(input_time{j}, 2) < 100 168 169 model_run{number_exp}.species(... 170 1 + input_indexcode).BoundaryCondition = 1; 171 for n = 1:size(input_time{j}, 2) 172 if ~isnan(input_time{j}(n)) 173 174 % Add parameters for time and input values 175 addparameter(model_run{number_exp}, ... 176 char("time_event_t_" + j + "_" + n), ... 177 str2double(string(input_time{j}(n))), ... 178 'ValueUnits', char(stg.simtime)); 179 180 addparameter(model_run{number_exp}, ... 181 char("time_event_r_" + j + "_" + n), ... 182 str2double(string(input_value{j}(n))), ... 183 'ValueUnits', ... 184 char(model_run{number_exp}.species(1 + ... 185 input_indexcode).InitialAmountUnits)); 186 187 % Add event for input species 188 addevent(model_run{number_exp}, ... 189 char("time>=time_event_t_" + j + "_" + n), ... 190 cellstr( ... 191 sbtab.datasets(number_exp).output_location{1} + ... 192 "." + input_name + ... 193 " = time_event_r_" + j + "_" + n)); 194 end 195 end 196 else 197 % If the input time is greater than or equal to 100, add 198 % repeated assignment rule 199 addrule(model_run{number_exp}, char(sbtab.datasets(... 200 number_exp).output_location{1} + "." + input_name + ... 201 "=" + string(model_run{number_exp}.name) + "_input" + ... 202 number_exp + "_" + input_name + "(time)"), ... 203 'repeatedAssignment'); 204 end 205 end 206 207 % Save proper simulation run .mat file (default) 208 model_exp = model_run{number_exp}; 209 config_exp = configsetObj{number_exp}; 210 save(model_exp_default + number_exp + ".mat", ... 211 'model_exp', 'config_exp') 212 sbiosaveproject(model_exp_default + number_exp, 'model_exp') 213 214 215 % Update simulation settings for detailed simulation run 216 set(configsetObj{number_exp}.SolverOptions, 'OutputTimes', []); 217 set(configsetObj{number_exp}.SolverOptions, ... 218 'MaxStep', stg.maxstepdetail); 219 220 % Save detailed simulation run .mat file 221 model_exp = model_run{number_exp}; 222 config_exp = configsetObj{number_exp}; 223 save(model_exp_detail + number_exp + ".mat", 'model_exp', 'config_exp') 224 225end 226end
Creates two .mat files for each experiment, one for the equilibrium simulation run and one for the proper simulation. These files have all the added rules, species and parameters needed depending on the inputs and outputs specified on the SBtab.
Inputs - stg, sb
Saves - Ready to run models
Function: f_build_model_exp Description: This function creates two .mat files for each experiment: one for the equilibrium simulation run and one for the proper run. The .mat files contain necessary rules, species, and parameters based on the inputs and outputs specified in the sbtab. The function also configures simulation settings for the equilibrium and proper simulation runs, processes output and input species, and saves the .mat files for each experiment.
Inputs: - stg: A structure containing settings for the simulations - sb: An sbtab structure containing information about experiments - mmf: A model management framework structure containing the data and mat models
Outputs: - .mat files for equilibrium and proper runs for each experiment
Called Functions: - getconfigset - copyobj - set - load - save - addspecies - addrule - addparameter - addevent
Loaded Variables: - data_model - mat_model - model_exp_eq - model_exp_default - model_exp_detail - Data - sbtab - modelobj
Notes: - The function has a loop that iterates through all experiments and saves the corresponding .mat files.
Usage example:
% Initialize stg, sb, and mmf structures
stg = ...
sb = ...
mmf = ...
% Call the f_build_model_exp function
f_build_model_exp(stg, sb, mmf);
This will create .mat files for equilibrium and proper runs for each experiment based on the information provided in the stg, sb, and mmf structures. The function f_build_model_exp processes the input structures stg, sb, and mmf to create .mat files for each experiment. The stg structure contains simulation settings such as time units, maximum wall clock, and tolerances. The sb structure contains information about the experiments, while the mmf structure contains data and mat models.
The function loads data from the data_model and mat_model files and initializes arrays for model_run and configsetObj. It then iterates through all experiments, configuring the simulation settings for both the equilibrium and proper simulation runs.
For each experiment, the function processes the output species, adding them to the model if they don’t already exist and setting up the appropriate rules. It then processes the input species, adding them either as events or repeated assignments based on the input time.
Finally, the function saves the .mat files for each experiment, creating separate files for the equilibrium, proper (default), and detailed simulation runs.