Tutorial 3. Simulate a 1D NMR titration series
by Evgenii Kovrigin, 05/17/2011
In this tutorial we will create a series of line shapes corresponding to an NMR titration experiment (gradual addition of a ligand to the receptor).
Contents
Clean up workspace (to avoid unwanted effects of old variable assignments)
close all clear all
CREATE A SERIES OF DATASETS FOR SIMULATIONS
Prepare a simulation session. Even though we are not planning to perform fitting of the data at this time, the simulation is better done using TotalFit object (session).
session_name='Tutorial_3_simulation';
session=TotalFit(session_name);
Create a simulation series
series_name='U_simulation'; % arbitrary dataset_class_name='NMRLineShapes1D'; % class name model_name='U-model'; model_numeric_solver='analytical'; model_numeric_options='no options'; number_of_datasets=5; number_of_points_to_simulate=100; X_min=-200; X_max=400; X_column=linspace(X_min, X_max, number_of_points_to_simulate)'; % use ' to transpose to a column-vector session.create_simulation_series(series_name, dataset_class_name, model_name, ... model_numeric_solver, model_numeric_options,... number_of_datasets, X_column);
Show datasets
%session.show_datasets % show all datasets in the session from all series session.show_series_datasets(series_name) % show only datasets of the series
ans = =========== Series "U_simulation" =============== ----------------------------- Dataset 1 --------------- Priority = 1 Name: U_simulation-1 Type: 1D NMR Line shapes Active model: Model 2: "U-model" Model description "1D NMR line shape for the U model, no temperature/field dependence, analytical" Model handle: line_shape_equations_1D.U_model_1D Current solver: analytical Model parameters: 1: Rtotal 2: LRratio 3: log10(K_A) 4: k_2_A 5: w0_1 6: w0_2 7: FWHH_1 8: FWHH_2 9: ScaleFactor Dataset 2 --------------- Priority = 1 Name: U_simulation-2 Type: 1D NMR Line shapes Active model: Model 2: "U-model" Model description "1D NMR line shape for the U model, no temperature/field dependence, analytical" Model handle: line_shape_equations_1D.U_model_1D Current solver: analytical Model parameters: 1: Rtotal 2: LRratio 3: log10(K_A) 4: k_2_A 5: w0_1 6: w0_2 7: FWHH_1 8: FWHH_2 9: ScaleFactor Dataset 3 --------------- Priority = 1 Name: U_simulation-3 Type: 1D NMR Line shapes Active model: Model 2: "U-model" Model description "1D NMR line shape for the U model, no temperature/field dependence, analytical" Model handle: line_shape_equations_1D.U_model_1D Current solver: analytical Model parameters: 1: Rtotal 2: LRratio 3: log10(K_A) 4: k_2_A 5: w0_1 6: w0_2 7: FWHH_1 8: FWHH_2 9: ScaleFactor Dataset 4 --------------- Priority = 1 Name: U_simulation-4 Type: 1D NMR Line shapes Active model: Model 2: "U-model" Model description "1D NMR line shape for the U model, no temperature/field dependence, analytical" Model handle: line_shape_equations_1D.U_model_1D Current solver: analytical Model parameters: 1: Rtotal 2: LRratio 3: log10(K_A) 4: k_2_A 5: w0_1 6: w0_2 7: FWHH_1 8: FWHH_2 9: ScaleFactor Dataset 5 --------------- Priority = 1 Name: U_simulation-5 Type: 1D NMR Line shapes Active model: Model 2: "U-model" Model description "1D NMR line shape for the U model, no temperature/field dependence, analytical" Model handle: line_shape_equations_1D.U_model_1D Current solver: analytical Model parameters: 1: Rtotal 2: LRratio 3: log10(K_A) 4: k_2_A 5: w0_1 6: w0_2 7: FWHH_1 8: FWHH_2 9: ScaleFactor
ESTABLISH FITTING ENVIRONMENT
Prepare fitting environment. This is when we make 'session' object fully aware of presence of multiple datasets with (potentially) linkable parameters.
session.initialize_relation_matrix(sprintf('%s.all_datasets.txt', session_name))
Dataset listing is written to "Tutorial_3_simulation.all_datasets.txt".
To inspect current fitting environment use the following command:
session.generate_fitting_environment(sprintf('%s.fitting_environment.txt', session_name))
Fitting environment saved in Tutorial_3_simulation.fitting_environment.txt. ans = New parameter relations (indexed as in all_parameters vector): [1] 1:Rtotal [2] 1:LRratio [3] 1:log10(K_A) [4] 1:k_2_A [5] 1:w0_1 [6] 1:w0_2 [7] 1:FWHH_1 [8] 1:FWHH_2 [9] 1:ScaleFactor [10] 2:Rtotal [11] 2:LRratio [12] 2:log10(K_A) [13] 2:k_2_A [14] 2:w0_1 [15] 2:w0_2 [16] 2:FWHH_1 [17] 2:FWHH_2 [18] 2:ScaleFactor [19] 3:Rtotal [20] 3:LRratio [21] 3:log10(K_A) [22] 3:k_2_A [23] 3:w0_1 [24] 3:w0_2 [25] 3:FWHH_1 [26] 3:FWHH_2 [27] 3:ScaleFactor [28] 4:Rtotal [29] 4:LRratio [30] 4:log10(K_A) [31] 4:k_2_A [32] 4:w0_1 [33] 4:w0_2 [34] 4:FWHH_1 [35] 4:FWHH_2 [36] 4:ScaleFactor [37] 5:Rtotal [38] 5:LRratio [39] 5:log10(K_A) [40] 5:k_2_A [41] 5:w0_1 [42] 5:w0_2 [43] 5:FWHH_1 [44] 5:FWHH_2 [45] 5:ScaleFactor Summary of datasets with lookup vectors (position of each parameter in all_parameter vector) -------- Dataset 1/U_simulation-1, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 1 2 3 4 5 6 7 8 9 Dataset 2/U_simulation-2, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 10 11 12 13 14 15 16 17 18 Dataset 3/U_simulation-3, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 19 20 21 22 23 24 25 26 27 Dataset 4/U_simulation-4, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 28 29 30 31 32 33 34 35 36 Dataset 5/U_simulation-5, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 37 38 39 40 41 42 43 44 45
The all_parameters vector is the vector created of all parameters of all datasets. The parameters of each datasets are shown at their respective places in the all_parameters vector. If the parameters are linked---they will be shown together. Their respective 'individual' places are left unoccupied.
The lookup_vectors contain the same information in a reverse way: for each dataset they give positions of parameters as they are found in all_parameters vector. This is a 'reverse lookup', essentially.
CREATE PARAMETER LINKAGES
We have multiple datasets that are linked by their nature: they have many common parameters and just two parameters that is variable between them (the total receptor concentraion and ligand/receptor ratio). Enter here the parameter indices (as they show up in dataset listings) to link:
parameter_number_array=[ 3 4 5 6 7 8 9 ]; session.batch_link_parameters_in_series(series_name, parameter_number_array);
Propagate information about links across all datasets
session.generate_fitting_environment(sprintf('%s.fitting_environment.txt', session_name))
Fitting environment saved in Tutorial_3_simulation.fitting_environment.txt. ans = New parameter relations (indexed as in all_parameters vector): [1] 1:Rtotal [2] 1:LRratio [3] 1:log10(K_A) | 2:log10(K_A) | 3:log10(K_A) | 4:log10(K_A) | 5:log10(K_A) [4] 1:k_2_A | 2:k_2_A | 3:k_2_A | 4:k_2_A | 5:k_2_A [5] 1:w0_1 | 2:w0_1 | 3:w0_1 | 4:w0_1 | 5:w0_1 [6] 1:w0_2 | 2:w0_2 | 3:w0_2 | 4:w0_2 | 5:w0_2 [7] 1:FWHH_1 | 2:FWHH_1 | 3:FWHH_1 | 4:FWHH_1 | 5:FWHH_1 [8] 1:FWHH_2 | 2:FWHH_2 | 3:FWHH_2 | 4:FWHH_2 | 5:FWHH_2 [9] 1:ScaleFactor | 2:ScaleFactor | 3:ScaleFactor | 4:ScaleFactor | 5:ScaleFactor [10] 2:Rtotal [11] 2:LRratio [12] n/a [13] n/a [14] n/a [15] n/a [16] n/a [17] n/a [18] n/a [19] 3:Rtotal [20] 3:LRratio [21] n/a [22] n/a [23] n/a [24] n/a [25] n/a [26] n/a [27] n/a [28] 4:Rtotal [29] 4:LRratio [30] n/a [31] n/a [32] n/a [33] n/a [34] n/a [35] n/a [36] n/a [37] 5:Rtotal [38] 5:LRratio [39] n/a [40] n/a [41] n/a [42] n/a [43] n/a [44] n/a [45] n/a Summary of datasets with lookup vectors (position of each parameter in all_parameter vector) -------- Dataset 1/U_simulation-1, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 1 2 3 4 5 6 7 8 9 Dataset 2/U_simulation-2, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 10 11 3 4 5 6 7 8 9 Dataset 3/U_simulation-3, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 19 20 3 4 5 6 7 8 9 Dataset 4/U_simulation-4, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 28 29 3 4 5 6 7 8 9 Dataset 5/U_simulation-5, model "U-model" Parameters : Rtotal LRratio log10(K_A) k_2_A w0_1 w0_2 FWHH_1 FWHH_2 ScaleFactor Lookup vector : 37 38 3 4 5 6 7 8 9
As we requested, the first two parameters, Rtotal and LRratio, are individual for each dataset because they depend on how the sample was made. The rest of parameters belongs to the system (constants, frequencies, line widths) and to the hardware (ScaleFactor). They are made linked across entire series .
ASSIGN PARAMETERS
Choose some reasonable parameters (use ones from previous tutorials)
load('../Tutorial_1_2.U_simulation_fitting_one_dataset/tutorial_1.mat','setup');
To assign linked parameters we need to assign them to the first of the linked datasets (these values will be propagated to other datasets automatically through established links
Obtain number of the first datasets in the series
first_dataset_index=session.dataset_index(series_name,1);
prepare vectors for easier handling:
FAKE_VALUE=1E-6; % individual (unlinked) parameters: to be assigned later ideal_parameters=[ FAKE_VALUE FAKE_VALUE setup.Log10_K_A setup.k_2_A ... setup.w0_1 setup.w0_2 setup.FWHH_1 setup.FWHH_2 setup.ScaleFactor ] % no ';'-sign to show parameters
ideal_parameters = Columns 1 through 5 0.0000 0.0000 5.0000 10.0000 0 Columns 6 through 9 200.0000 20.0000 20.0000 1.0000
Formally prepare limits (we will not need them for simulation but must assign arrays of the same size as parameters
fake_limits=zeros(1,length(ideal_parameters));
Perform assignment (I keep names of function arguments for information)
Monte_Carlo_range_min=fake_limits;
Monte_Carlo_range_max=fake_limits;
parameter_limits_min=fake_limits;
parameter_limits_max=fake_limits;
session.assign_parameter_values(first_dataset_index, ideal_parameters, ...
Monte_Carlo_range_min, Monte_Carlo_range_max, parameter_limits_min, parameter_limits_max);
Assign unlinked parameters These parameters are NOT linked therefore we need to go through all datasets to assign them.
Create a vector of values first
Rtotal_vector=ones(1,number_of_datasets)*setup.Rtotal; % this one is constant for all datasets LRratio_vector=[0 0.4 0.8 1.2 1.6]; % this one is variable
Create vector ranges for formal assignment (different length from the above!)
unlinked_fake_ranges=zeros(1,number_of_datasets);
Assign Rtotal
parameter_number=1; values_array=Rtotal_vector; MonteCarlo_range_min_array=unlinked_fake_ranges; MonteCarlo_range_max_array=unlinked_fake_ranges; parameter_limits_min_array=unlinked_fake_ranges; parameter_limits_max_array=unlinked_fake_ranges; session.assign_unlinked_parameter_in_series(... series_name, parameter_number, values_array, ... MonteCarlo_range_min_array, MonteCarlo_range_max_array, ... parameter_limits_min_array, parameter_limits_max_array);
Assign LRratio
parameter_number=2; values_array=LRratio_vector; session.assign_unlinked_parameter_in_series(... series_name, parameter_number, values_array, ... MonteCarlo_range_min_array, MonteCarlo_range_max_array, ... parameter_limits_min_array, parameter_limits_max_array);
CALCULATE MODEL VALUES
Run a simulation
X_standard_dev=0;
Y_standard_dev=1e-8; % something really small
session.simulate_series(series_name, X_standard_dev, Y_standard_dev);
Plot the simulation result
Y_offset_percent=10; % to offset figures vertically for easier viewing figure_handle1=session.plot_1D_series(series_name, 'Simulation 3', Y_offset_percent);
output simulation
figure_handle=figure_handle1; folder_name=session_name; figure_name=series_name; results_output.output_figure(figure_handle, folder_name, figure_name)
To adjust appearance of the output figures: load files from FIG/ folder in MATLAB and directly edit them there.
HOW TO CHECK VALUES OF SPECIFIC PARAMETERS FOR PARTICULAR DATASETS?
To do this we need (1) find out the index of the dataset we are interested in, and (2) display its 'best-fit' parameters (this is just the name of the vector simulated parameters are placed in);
The deal with the index is that we need TOTAL index the dataset has in the TotalFit object session. What is easy to know for us is the LOCAL index inside the series. This is how to convert the LOCAL index to a TOTAL one:
index_inside_the_series=3; dataset_in_question_index=session.dataset_index(series_name,index_inside_the_series);
Show parameters
session.dataset_best_fit_parameters(dataset_in_question_index)
ans = Columns 1 through 5 0.0010 0.8000 5.0000 10.0000 0 Columns 6 through 9 200.0000 20.0000 20.0000 1.0000
Plot figure:
figure_title='inspection';
session.dataset_plot_fit(dataset_in_question_index, figure_title);
or (which uses index relative to the series)
session.plot_one_series_dataset(series_name,index_inside_the_series, figure_title);