diff --git a/.gitignore b/.gitignore index 43a033e..a3774a7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.log *.toc *.sty +/old_functions diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a1ab0..530ec39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [0.1.12] - latest + +### Added +- New *SNR*-option in **NUCLEUSmod** to set the noise of the forward modelled NMR data either by noise level or signal-to-noise ratio (SNR) +- New *Multi modal* fitting option in **NUCLEUSinv** (only in Expert mode) with built-in uncertainty estimation for the final RTD +- New import routines to **NUCLEUSinv** for *BGR* devices (*Mouse* and *Helios*) +- Difussion relaxation time *Tdiff* is now considered in **NUCLEUSmod** (*NMR* panel) and **NUCLEUSinv** (*Petro Parameter* panel) +- Added an `AUTHORS.md` file to the repository. + +### Changed +- Changed the default export path and file name for graphics files in **NUCLEUSinv** to the current import path and data file +- Changed the visualization of the imaginary part of the raw data (if available) +- Minor internal changes + +### Fixed +- Fixed an issue regarding the import of T1 data without noise (noise is now estimated on-the-fly via a fit with five free exponents) + ## [0.1.11] - 2021-03-12 ### Added @@ -75,13 +92,13 @@ ## [0.1.6] - 2019-06-24 ### Added -- Added a new *PhaseView* subGUI to view and change the phase between real and imaginary part of a T2 signal. **NUCLEUSinv** +- Added a new *PhaseView* subGUI to view and change the phase between real and imaginary part of a T2 signal. **NUCLEUSinv** - Added a new import filter for the BAM NMR tomograph. **NUCLEUSinv** -- Added an export feature that allows to save T2 raw data into a csv-file (e.g. LIAG format); during save it is possible to overwrite the imaginary part with zeros. **NUCLEUSinv** +- Added an export feature that allows to save T2 raw data into a csv-file (e.g. LIAG format); during save it is possible to overwrite the imaginary part with zeros. **NUCLEUSinv** ### Changed -- If a T2 signal is imported it is automatically rotated to minimize its imaginary part (the fit incorporates real and imag. part of the signal). **NUCLEUSinv** +- If a T2 signal is imported it is automatically rotated to minimize its imaginary part (the fit incorporates real and imag. part of the signal). **NUCLEUSinv** - The *FitStatistics* window layout is now in line with the *PhaseView* layout for consistency reasons. **NUCLEUSinv** ### Fixed @@ -115,7 +132,7 @@ - Due to the new error weights there is no default gating method anymore for the *free exp. inversion*. **NUCLEUSinv** ### Fixed -- T1 inversion recovery factor (1 or 2 depending on inversion or saturation recovery) was missing in *free exp. inversion* and *free joint inversion* (in Jacobian calculation for angular pores). **NUCLEUSinv** +- T1 inversion recovery factor (1 or 2 depending on inversion or saturation recovery) was missing in *free exp. inversion* and *free joint inversion* (in Jacobian calculation for angular pores). **NUCLEUSinv** ## [0.1.3] - 2019-02-22 @@ -154,6 +171,7 @@ Initial Version +[0.1.12]: https://github.com/ThoHiller/nmr-nucleus/compare/v.0.1.11...v.0.1.12 [0.1.11]: https://github.com/ThoHiller/nmr-nucleus/compare/v.0.1.10...v.0.1.11 [0.1.10]: https://github.com/ThoHiller/nmr-nucleus/compare/v.0.1.9...v.0.1.10 [0.1.9]: https://github.com/ThoHiller/nmr-nucleus/compare/v.0.1.8...v.0.1.9 diff --git a/NUCLEUSinv/NUCLEUSinv.m b/NUCLEUSinv/NUCLEUSinv.m index 0fbefb4..b3f772e 100644 --- a/NUCLEUSinv/NUCLEUSinv.m +++ b/NUCLEUSinv/NUCLEUSinv.m @@ -27,8 +27,8 @@ % none % % See also NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -38,10 +38,10 @@ if ~isempty(h0); close(h0); end %% GUI 'header' info and defaults -myui.version = '0.1.11'; -myui.date = '12.03.2021'; -myui.author = {'Thomas Hiller','Stephan Costabel'}; -myui.email = 'thomas.hiller[at]leibniz-liag.de'; +myui.version = '0.1.12'; +myui.date = '17.02.2022'; +myui.author = {'Stephan Costabel','Thomas Hiller'}; +myui.email = 'thomas.hiller[at]bgr.de'; myui.fontsize = 10; myui.inifile = 'NUCLEUSinv.ini'; diff --git a/NUCLEUSinv/NUCLEUSinv_createGUI.m b/NUCLEUSinv/NUCLEUSinv_createGUI.m index 8f1407f..dfd6bca 100644 --- a/NUCLEUSinv/NUCLEUSinv_createGUI.m +++ b/NUCLEUSinv/NUCLEUSinv_createGUI.m @@ -36,8 +36,8 @@ function NUCLEUSinv_createGUI(h,wbon) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -118,7 +118,7 @@ function NUCLEUSinv_createGUI(h,wbon) 'TitleColor',myui.colors.BoxCPS,'ForegroundColor',myui.colors.BoxTitle); % adjust the heights of all left-column-panels -myui.heights = [250 22 22 22 22; -1 109 137 190 299]; +myui.heights = [250 22 22 22 22; -1 109 165 190 299]; % panel header is always 22 high set(gui.panels.main,'Heights',myui.heights(2,:),... 'MinimumHeights',[250 22 22 22 22]); @@ -199,7 +199,7 @@ function NUCLEUSinv_createGUI(h,wbon) % otherwise "fixAxes" throws an error (in NUCLEUSmod); strangely here it % also works without it, but I put it for consistency reasons setappdata(h,'gui',gui); -% changeColorTheme('INV',myui.colors.theme); +changeColorTheme('INV',myui.colors.theme); set(gui.main,'Visible','on'); %% enable all menus diff --git a/NUCLEUSinv/NUCLEUSinv_createMenus.m b/NUCLEUSinv/NUCLEUSinv_createMenus.m index a58b965..a89cb8a 100644 --- a/NUCLEUSinv/NUCLEUSinv_createMenus.m +++ b/NUCLEUSinv/NUCLEUSinv_createMenus.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -61,12 +61,23 @@ % 1.1.1.2.1 BGR std gui.menu.file_import_lab_bgr_std = uimenu(gui.menu.file_import_lab_bgr,... 'Label','BGR std','Tag','Lab','Callback',@onMenuImport); -% 1.1.1.2.2 BGR org -gui.menu.file_import_lab_bgr_org = uimenu(gui.menu.file_import_lab_bgr,... - 'Label','BGR org','Tag','Lab','Callback',@onMenuImport); -% 1.1.1.2.3 BGR mat +% 1.1.1.2.2 BGR mat gui.menu.file_import_lab_bgr_mat = uimenu(gui.menu.file_import_lab_bgr,... 'Label','BGR mat','Tag','Lab','Callback',@onMenuImport); +% 1.1.1.2.3 Mouse CPMG data, single data subfolders from CPMG +gui.menu.file_import_lab_bgr_mouse_cpmg = uimenu(gui.menu.file_import_lab_bgr,... + 'Label','MouseCPMG','Tag','Lab','Callback',@onMenuImport); +% 1.1.1.2.4 Mouse plus Lift, single data subfolder from t1test,... +% ...cpmgfastautotest, or (old Prospa Versions) cpmgfastauto +gui.menu.file_import_lab_bgr_mouse_liftsingle = uimenu(gui.menu.file_import_lab_bgr,... + 'Label','MouseLiftSingle','Tag','Lab','Callback',@onMenuImport); +% 1.1.1.2.5 Mouse plus Lift, all data subfolders from t1test,... +% cpmgfastautotest, or (old Prospa Versions) cpmgfastauto +gui.menu.file_import_lab_bgr_mouse_liftall = uimenu(gui.menu.file_import_lab_bgr,... + 'Label','MouseLiftAll','Tag','Lab','Callback',@onMenuImport); +% 1.1.1.2.6 Helios +gui.menu.file_import_lab_bgr_helios = uimenu(gui.menu.file_import_lab_bgr,... + 'Label','Helios','Tag','Lab','Callback',@onMenuImport); % 1.1.1.3 LIAG gui.menu.file_import_lab_liag = uimenu(gui.menu.file_import_lab,... diff --git a/NUCLEUSinv/NUCLEUSinv_createPanelData.m b/NUCLEUSinv/NUCLEUSinv_createPanelData.m index 0e751e5..d9af8c7 100644 --- a/NUCLEUSinv/NUCLEUSinv_createPanelData.m +++ b/NUCLEUSinv/NUCLEUSinv_createPanelData.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -78,7 +78,7 @@ uimenu(gui.cm_handles.data_list_single,... 'Label','save','Tag','single','Callback',@onContextSignalList); uimenu(gui.cm_handles.data_list_single,... - 'Label','remove','Tag','single','Separator','on',... + 'Label','\remove','Tag','single','Separator','on',... 'Callback',@onContextSignalList); uimenu(gui.cm_handles.data_list_single,... 'Label','use as calib.','Tag','single','Separator','on',... diff --git a/NUCLEUSinv/NUCLEUSinv_createPanelInfo.m b/NUCLEUSinv/NUCLEUSinv_createPanelInfo.m index a1757ce..e6cbf39 100644 --- a/NUCLEUSinv/NUCLEUSinv_createPanelInfo.m +++ b/NUCLEUSinv/NUCLEUSinv_createPanelInfo.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSinv/NUCLEUSinv_createPanelInversionJoint.m b/NUCLEUSinv/NUCLEUSinv_createPanelInversionJoint.m index 5065213..3587bff 100644 --- a/NUCLEUSinv/NUCLEUSinv_createPanelInversionJoint.m +++ b/NUCLEUSinv/NUCLEUSinv_createPanelInversionJoint.m @@ -26,8 +26,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSinv/NUCLEUSinv_createPanelInversionStd.m b/NUCLEUSinv/NUCLEUSinv_createPanelInversionStd.m index 408db21..e2dd4ef 100644 --- a/NUCLEUSinv/NUCLEUSinv_createPanelInversionStd.m +++ b/NUCLEUSinv/NUCLEUSinv_createPanelInversionStd.m @@ -26,8 +26,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -62,10 +62,10 @@ switch data.info.ExpertMode case 'on' tstr = ' '; - istring = {'Mono exp.','Several free exp. (2-5)','Multi exp. (LSQ)','Multi exp. (LU decomp.)'}; + istring = {'Mono exp.','N free exp. (2-5)','Multi exp. (LSQ)','Multi exp. (LU decomp.)','Multi modal'}; case 'off' tstr = ' '; - istring = {'Mono exp.','Several free exp. (2-5)','Multi exp. (LSQ)'}; + istring = {'Mono exp.','N free exp. (2-5)','Multi exp. (LSQ)'}; end gui.popup_handles.invstd_InvType = uicontrol('Parent',gui.panels.invstd.HBox1,... 'Style','popup','String',istring,'FontSize',myui.fontsize,'Enable','off','Value',3,... diff --git a/NUCLEUSinv/NUCLEUSinv_createPanelPetro.m b/NUCLEUSinv/NUCLEUSinv_createPanelPetro.m index b8da803..c52f186 100644 --- a/NUCLEUSinv/NUCLEUSinv_createPanelPetro.m +++ b/NUCLEUSinv/NUCLEUSinv_createPanelPetro.m @@ -26,8 +26,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -36,38 +36,65 @@ gui.panels.petro.VBox = uix.VBox('Parent',gui.panels.petro.main,... 'Spacing',3,'Padding',3); -% Tbulk, surface relaxivity rho and geometry factor a +% Tbulk and Tdiff gui.panels.petro.HBox1 = uix.HBox('Parent',gui.panels.petro.VBox,... 'Spacing',3); -% CBW and BVI +% surface relaxivity rho and geometry factor a gui.panels.petro.HBox2 = uix.HBox('Parent',gui.panels.petro.VBox,... 'Spacing',3); -% calibration switch calib volume +% CBW and BVI gui.panels.petro.HBox3 = uix.HBox('Parent',gui.panels.petro.VBox,... 'Spacing',3); -% sample volume, sample porosity +% calibration switch calib volume gui.panels.petro.HBox4 = uix.HBox('Parent',gui.panels.petro.VBox,... 'Spacing',3); +% sample volume, sample porosity +gui.panels.petro.HBox5 = uix.HBox('Parent',gui.panels.petro.VBox,... + 'Spacing',3); -%% Tbulk, surface relaxivity rho and geometry factor a +%% Tbulk and Tdiff gui.text_handles.petro_Tbulk = uicontrol('Parent',gui.panels.petro.HBox1,... 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String',['Tbulk [s] | ',char(hex2dec('03C1')),' [µm/s] | geom']); -tstr = 'Set the T bulk [s] value.
'; + 'String','Tbulk [s] | Tdiff [s]'); +tstr = ['Bulk relaxation time in [s].

',... + '1/T = 1/Ts + 1/Tb + 1/Td

',... + 'Default value:
',... + '1e6 (so that 1/Tb is ignored)
']; gui.edit_handles.invstd_Tbulk = uicontrol('Parent',gui.panels.petro.HBox1,... 'Style','edit','String',num2str(data.invstd.Tbulk),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.invstd.Tbulk 1 1]),... 'Tag','invstd_Tbulk','Enable','off','Callback',@onEditValue); -tstr = ['Surface relaxivity rho in [m/s].

',... - '1/T = rho*S/V = rho*a/R.

',... +tstr = ['Diffusion relaxation time in [s].

',... + '1/T = 1/Ts + 1/Tb + 1/Td

',... + 'Td can be caluclated by

',... + 'Td = 12 / (D*(',char(hex2dec('03B3')),'*G*TE)2 )

',... + 'with

',... + 'D = diffusion coefficent of water
',... + char(hex2dec('03B3')),' = gyromagnetic ratio of hydrogen
',... + 'G = magnetic gradient
',... + 'TE = echo time

',... + 'Default value:
',... + '1e6 (so that 1/Td is ignored)
']; +gui.edit_handles.invstd_Tdiff = uicontrol('Parent',gui.panels.petro.HBox1,... + 'Style','edit','String',num2str(data.invstd.Tdiff),'FontSize',myui.fontsize,... + 'UserData',struct('Tooltipstr',tstr,'defaults',[data.invstd.Tdiff 1 1]),... + 'Tag','invstd_Tdiff','Enable','off','Callback',@onEditValue); +set(gui.panels.petro.HBox1,'Widths',[200 -1 -1]); + +%% surface relaxivity rho and geometry factor a +gui.text_handles.petro_rho = uicontrol('Parent',gui.panels.petro.HBox2,... + 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... + 'String',[char(hex2dec('03C1')),' [µm/s] | geom ']); +tstr = ['Surface relaxivity in [µm/s].

',... + '1/Ts = rho*S/V = rho*a/R.

',... 'Default value:
',... - '2.5e-5
']; -gui.edit_handles.param_rho = uicontrol('Parent',gui.panels.petro.HBox1,... + '10
']; +gui.edit_handles.param_rho = uicontrol('Parent',gui.panels.petro.HBox2,... 'Style','edit','String',num2str(data.param.rho),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.rho 1 1]),... 'Tag','param_rho','Enable','off','Callback',@onEditValue); -tstr = ['Give the geometry factor "a" to convert relaxation times to pore radii

',... - '1/T = rho*S/V = rho*a/R.

',... +tstr = ['Geometry factor "a" to convert relaxation times to pore radii.

',... + '1/Ts = rho*S/V = rho*a/R.

',... 'Possible options:
',... '2 capillaries with circular cross section
',... '3 spheres

',... @@ -77,17 +104,17 @@ 'e.g. 2.72 is 90°-45°-45° | 2.87 is 90°-60°-30° | 5.64 is 90°-85°-5°

',... 'Default value:
',... '2
']; -gui.edit_handles.param_geom = uicontrol('Parent',gui.panels.petro.HBox1,... +gui.edit_handles.param_geom = uicontrol('Parent',gui.panels.petro.HBox2,... 'Style','edit','String',num2str(data.param.a),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.a 1 1]),... 'Tag','param_a','Enable','off','Callback',@onEditValue); -set(gui.panels.petro.HBox1,'Widths',[200 -1 -1 -1]); +set(gui.panels.petro.HBox2,'Widths',[200 -1 -1]); %% CBW and BVI -gui.text_handles.petro_CBW = uicontrol('Parent',gui.panels.petro.HBox2,... +gui.text_handles.petro_CBW = uicontrol('Parent',gui.panels.petro.HBox3,... 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String','CBW [ms] | BVI [ms]'); -tstr = ['Give cut-off time between CBW and BVI in [ms].',... + 'String','CBW [ms] | BVI [ms] '); +tstr = ['Cut-off time between CBW and BVI in [ms].',... ' This value depends on lithology.

',... 'Abbreviations:
',... 'CBW clay bound water
',... @@ -96,11 +123,11 @@ 'The value is usually 3 [ms]

',... 'Default value:
',... '3
']; -gui.edit_handles.param_CBW = uicontrol('Parent',gui.panels.petro.HBox2,... +gui.edit_handles.param_CBW = uicontrol('Parent',gui.panels.petro.HBox3,... 'Style','edit','String',num2str(data.param.CBWcutoff),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.CBWcutoff 1 1]),... 'Tag','param_CBWcutoff','Enable','off','Callback',@onEditValue); -tstr = ['Give cut off time between BVI and BVM in [ms].',... +tstr = ['Cut-off time between BVI and BVM in [ms].',... ' This value depends on lithology.

',... 'Abbreviations:
',... 'CBW clay bound water
',... @@ -110,49 +137,51 @@ 'For Carbonates the value is usually 92 [ms]

',... 'Default value:
',... '33
']; -gui.edit_handles.param_BVI = uicontrol('Parent',gui.panels.petro.HBox2,... +gui.edit_handles.param_BVI = uicontrol('Parent',gui.panels.petro.HBox3,... 'Style','edit','String',num2str(data.param.BVIcutoff),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.BVIcutoff 1 1]),... 'Tag','param_BVIcutoff','Enable','off','Callback',@onEditValue); -set(gui.panels.petro.HBox2,'Widths',[200 -1 -1]); +set(gui.panels.petro.HBox3,'Widths',[200 -1 -1]); %% calibration switch, calibration volume -gui.text_handles.petro_calibVol = uicontrol('Parent',gui.panels.petro.HBox3,... +gui.text_handles.petro_calibVol = uicontrol('Parent',gui.panels.petro.HBox4,... 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String','calib. Vol. | calib. Amp.'); + 'String',' calib. Vol. | calib. Amp.'); tstr = ''; -gui.edit_handles.param_calibVol = uicontrol('Parent',gui.panels.petro.HBox3,... +gui.edit_handles.param_calibVol = uicontrol('Parent',gui.panels.petro.HBox4,... 'Style','edit','String',num2str(data.param.calibVol),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.calibVol 1 1]),... 'Tag','param_calibVol','Enable','off','Callback',@onEditValue); tstr = ''; -gui.edit_handles.param_calibAmp = uicontrol('Parent',gui.panels.petro.HBox3,... +gui.edit_handles.param_calibAmp = uicontrol('Parent',gui.panels.petro.HBox4,... 'Style','edit','String',num2str(data.param.calibAmp),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.calibAmp 1 1]),... 'Tag','param_calibAmp','Enable','off','Callback',@onEditValue); -set(gui.panels.petro.HBox3,'Widths',[200 -1 -1]); +set(gui.panels.petro.HBox4,'Widths',[200 -1 -1]); %% sample volume, porosity -gui.text_handles.petro_sampVol = uicontrol('Parent',gui.panels.petro.HBox4,... +gui.text_handles.petro_sampVol = uicontrol('Parent',gui.panels.petro.HBox5,... 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String','sample Vol. | porosity'); + 'String','sample Vol. | porosity '); tstr = ' '; -gui.edit_handles.param_sampVol = uicontrol('Parent',gui.panels.petro.HBox4,... +gui.edit_handles.param_sampVol = uicontrol('Parent',gui.panels.petro.HBox5,... 'Style','edit','String',num2str(data.param.sampVol),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.sampVol 1 1]),... 'Tag','param_sampVol','Enable','off','Callback',@onEditValue); -tstr = ['Set porosity (between 0 and 1)

',... +tstr = ['Porosity (between 0 and 1)

',... 'Default value:
',... '1

']; -gui.edit_handles.invstd_porosity = uicontrol('Parent',gui.panels.petro.HBox4,... +gui.edit_handles.invstd_porosity = uicontrol('Parent',gui.panels.petro.HBox5,... 'Style','edit','String',num2str(data.invstd.porosity),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.invstd.porosity 1 1]),... 'Tag','invstd_porosity','Enable','off','Callback',@onEditValue); -set(gui.panels.petro.HBox4,'Widths',[200 -1 -1]); +set(gui.panels.petro.HBox5,'Widths',[200 -1 -1]); %% Java Hack to adjust vertical alignment of text fields jh = findjobj(gui.text_handles.petro_Tbulk); jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +jh = findjobj(gui.text_handles.petro_rho); +jh.setVerticalAlignment(javax.swing.JLabel.CENTER); jh = findjobj(gui.text_handles.petro_CBW); jh.setVerticalAlignment(javax.swing.JLabel.CENTER); jh = findjobj(gui.text_handles.petro_calibVol); diff --git a/NUCLEUSinv/NUCLEUSinv_createPanelPlots.m b/NUCLEUSinv/NUCLEUSinv_createPanelPlots.m index fe4cf01..f91d292 100644 --- a/NUCLEUSinv/NUCLEUSinv_createPanelPlots.m +++ b/NUCLEUSinv/NUCLEUSinv_createPanelPlots.m @@ -26,8 +26,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSinv/NUCLEUSinv_createPanelProcess.m b/NUCLEUSinv/NUCLEUSinv_createPanelProcess.m index 3d19158..439d8b3 100644 --- a/NUCLEUSinv/NUCLEUSinv_createPanelProcess.m +++ b/NUCLEUSinv/NUCLEUSinv_createPanelProcess.m @@ -26,8 +26,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSinv/NUCLEUSinv_createStatusbar.m b/NUCLEUSinv/NUCLEUSinv_createStatusbar.m index b2d0a0a..a4055e4 100644 --- a/NUCLEUSinv/NUCLEUSinv_createStatusbar.m +++ b/NUCLEUSinv/NUCLEUSinv_createStatusbar.m @@ -24,8 +24,8 @@ % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md %------------- BEGIN CODE -------------- diff --git a/NUCLEUSinv/NUCLEUSinv_loadDefaults.m b/NUCLEUSinv/NUCLEUSinv_loadDefaults.m index 7aa925d..5e3985b 100644 --- a/NUCLEUSinv/NUCLEUSinv_loadDefaults.m +++ b/NUCLEUSinv/NUCLEUSinv_loadDefaults.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -127,9 +127,18 @@ out.invstd.noise = 0; % water bulk relaxation time [s] out.invstd.Tbulk = 1e6; +% diffusion relaxation time [s] +out.invstd.Tdiff = 1e6; % porosity value between 0 and 1 [-] out.invstd.porosity = 1; +out.invstd.useUncert = 1; +out.invstd.uncertMethod = 'thresh'; +out.invstd.uncertThresh = 0.05; +out.invstd.uncertChi2 = 0.005; +out.invstd.uncertN = 100; +out.invstd.uncertMax = 1e4; + %% joint inversion panel defaults % joint inversion methods to choose 'free' | 'fixed' | 'shape' out.invjoint.invtype = 'free'; diff --git a/NUCLEUSinv/NUCLEUSinv_processINI.m b/NUCLEUSinv/NUCLEUSinv_processINI.m index a5c939e..937542a 100644 --- a/NUCLEUSinv/NUCLEUSinv_processINI.m +++ b/NUCLEUSinv/NUCLEUSinv_processINI.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSinv/NUCLEUSinv_updateInterface.m b/NUCLEUSinv/NUCLEUSinv_updateInterface.m index 80d65f9..9141613 100644 --- a/NUCLEUSinv/NUCLEUSinv_updateInterface.m +++ b/NUCLEUSinv/NUCLEUSinv_updateInterface.m @@ -32,8 +32,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -69,7 +69,7 @@ %% update standard inversion panel % inversion method popup istring = {'Mono exp.','Several free exp. (2-5)',... - 'Multi exp. (LSQ)','Multi exp. (LU decomp.)'}; + 'Multi exp. (LSQ)','Multi exp. (LU decomp.)','Multi modal'}; set(gui.popup_handles.invstd_InvType,'String',istring); switch data.invstd.invtype case 'mono' @@ -87,9 +87,11 @@ gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); gui = updateInvstdTime(gui,data.invstd.invtype,0,0); - % Tbulk + % Tbulk & Tdiff set(gui.edit_handles.invstd_Tbulk,'Enable','off',... 'String',num2str(data.invstd.Tbulk)); + set(gui.edit_handles.invstd_Tdiff,'Enable','off',... + 'String',num2str(data.invstd.Tdiff)); case 'free' % inversion method popup @@ -107,9 +109,11 @@ gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); gui = updateInvstdTime(gui,data.invstd.invtype,0,0); - % Tbulk + % Tbulk & Tdiff set(gui.edit_handles.invstd_Tbulk,'Enable','off',... 'String',num2str(data.invstd.Tbulk)); + set(gui.edit_handles.invstd_Tdiff,'Enable','off',... + 'String',num2str(data.invstd.Tdiff)); case 'NNLS' % inversion method popup @@ -145,9 +149,11 @@ gui = updateInvstdTime(gui,data.invstd.invtype,data.invstd.time,... data.invstd.Ntime); - % Tbulk + % Tbulk & Tdiff set(gui.edit_handles.invstd_Tbulk,'Enable','on',... 'String',num2str(data.invstd.Tbulk)); + set(gui.edit_handles.invstd_Tdiff,'Enable','on',... + 'String',num2str(data.invstd.Tdiff)); case 'LU' % inversion method popup @@ -175,9 +181,39 @@ gui = updateInvstdTime(gui,data.invstd.invtype,data.invstd.time,... data.invstd.Ntime); - % Tbulk + % Tbulk & Tdiff set(gui.edit_handles.invstd_Tbulk,'Enable','on',... 'String',num2str(data.invstd.Tbulk)); + set(gui.edit_handles.invstd_Tdiff,'Enable','on',... + 'String',num2str(data.invstd.Tdiff)); + + case 'MUMO' + % inversion method popup + set(gui.popup_handles.invstd_InvType,'Value',5,'Enable','on'); + + % additional inversion settings + set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... + 'Value',data.invstd.freeDT,... + 'String',{'1','2','3','4','5'}); + set(gui.text_handles.invstd_InvTypeOpt,... + 'String','No. of modes'); + +% % lambda, smoothness constraint and RTD limits +% gui = updateLambda(gui,data.invstd.regtype,data.invstd.lambda,... +% data.invstd.lambdaR,data.invstd.NlambdaR); +% gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); + gui = updateInvstdTime(gui,data.invstd.invtype,data.invstd.time,... + data.invstd.Ntime); + + % lambda, smoothness constraint and RTD limits + gui = updateLambda(gui,data.invstd.regtype,0,0,0); + gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); + + % Tbulk & Tdiff + set(gui.edit_handles.invstd_Tbulk,'Enable','on',... + 'String',num2str(data.invstd.Tbulk)); + set(gui.edit_handles.invstd_Tdiff,'Enable','on',... + 'String',num2str(data.invstd.Tdiff)); end % updates CBW, BVI, rho and a @@ -535,9 +571,11 @@ gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); gui = updateInvstdTime(gui,data.invstd.invtype,0,0); - % Tbulk + % Tbulk & Tdiff set(gui.edit_handles.invstd_Tbulk,'Enable','off',... 'String',num2str(data.invstd.Tbulk)); + set(gui.edit_handles.invstd_Tdiff,'Enable','off',... + 'String',num2str(data.invstd.Tdiff)); case 'free' % inversion method popup @@ -555,9 +593,11 @@ gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); gui = updateInvstdTime(gui,data.invstd.invtype,0,0); - % Tbulk + % Tbulk & Tdiff set(gui.edit_handles.invstd_Tbulk,'Enable','off',... 'String',num2str(data.invstd.Tbulk)); + set(gui.edit_handles.invstd_Tdiff,'Enable','off',... + 'String',num2str(data.invstd.Tdiff)); case 'NNLS' % inversion method popup @@ -592,9 +632,11 @@ set(gui.edit_handles.invstd_Ntime,'Enable','off',... 'String',num2str(data.invstd.Ntime)); - % Tbulk + % Tbulk & Tdiff set(gui.edit_handles.invstd_Tbulk,'Enable','on',... 'String',num2str(data.invstd.Tbulk)); + set(gui.edit_handles.invstd_Tdiff,'Enable','on',... + 'String',num2str(data.invstd.Tdiff)); end %% update petro parameter panel @@ -681,16 +723,16 @@ set(gui.radio_handles.process_timescale_ms,'Enable','on','Value',0); set(gui.text_handles.invstd_RTDtimes,'String','RTD - min [s] | max [s] | # / dec',... 'FontSize',10); - set(gui.text_handles.petro_Tbulk,'String',... - ['Tbulk [s] | ',char(hex2dec('03C1')),' [µm/s] | geom']); + set(gui.text_handles.petro_Tbulk,'String','Tbulk [s] | Tdiff [s]'); + set(gui.text_handles.petro_rho,'String',[char(hex2dec('03C1')),' [µm/s] | geom ']); case 'ms' set(gui.radio_handles.process_timescale_s,'Enable','on','Value',0); set(gui.radio_handles.process_timescale_ms,'Enable','on','Value',1); set(gui.text_handles.invstd_RTDtimes,'String','RTD - min [ms] | max [ms] | # / dec',... 'FontSize',9); - set(gui.text_handles.petro_Tbulk,'String',... - ['Tbulk [ms] | ',char(hex2dec('03C1')),' [µm/s] | geom']); + set(gui.text_handles.petro_Tbulk,'String','Tbulk [ms] | Tdiff [ms]'); + set(gui.text_handles.petro_rho,'String',[char(hex2dec('03C1')),' [µm/s] | geom ']); end end @@ -704,7 +746,7 @@ set(gui.edit_handles.invstd_time_max,'Enable','off'); set(gui.edit_handles.invstd_Ntime,'Enable','off'); - case {'LU','NNLS'} + case {'LU','NNLS','MUMO'} set(gui.edit_handles.invstd_time_min,'Enable','on','String',num2str(time(1))); set(gui.edit_handles.invstd_time_max,'Enable','on','String',num2str(time(2))); set(gui.edit_handles.invstd_Ntime,'Enable','on','String',num2str(Ntime)); @@ -809,7 +851,7 @@ function gui = updateLorder(gui,invtype,Lorder) switch invtype - case {'mono','free'} + case {'mono','free','MUMO'} set(gui.radio_handles.invstd_Lorder0,'Enable','off'); set(gui.radio_handles.invstd_Lorder1,'Enable','off'); set(gui.radio_handles.invstd_Lorder2,'Enable','off'); @@ -881,7 +923,7 @@ set(gui.edit_handles.param_rho,'Enable','on','String',num2str(p.rho)); set(gui.edit_handles.param_geom,'Enable','on','String',num2str(p.a)); - case {'LU','NNLS'} + case {'LU','NNLS','MUMO'} set(gui.edit_handles.param_CBW,'Enable','on','String',num2str(p.CBWcutoff)); set(gui.edit_handles.param_BVI,'Enable','on','String',num2str(p.BVIcutoff)); set(gui.edit_handles.param_rho,'Enable','on','String',num2str(p.rho)); diff --git a/NUCLEUSmod/NUCLEUSmod.m b/NUCLEUSmod/NUCLEUSmod.m index 271b5cf..14bea02 100644 --- a/NUCLEUSmod/NUCLEUSmod.m +++ b/NUCLEUSmod/NUCLEUSmod.m @@ -30,8 +30,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -41,10 +41,10 @@ if ~isempty(h0); close(h0); end %% GUI 'header' info and defaults -myui.version = '0.1.11'; -myui.date = '12.03.2021'; -myui.author = {'Thomas Hiller','Stephan Costabel'}; -myui.email = 'thomas.hiller[at]leibniz-liag.de'; +myui.version = '0.1.12'; +myui.date = '17.02.2022'; +myui.author = {'Stephan Costabel','Thomas Hiller'}; +myui.email = 'thomas.hiller[at]bgr.de'; myui.fontsize = 10; %% Default data settings diff --git a/NUCLEUSmod/NUCLEUSmod_createGUI.m b/NUCLEUSmod/NUCLEUSmod_createGUI.m index 9579889..163c193 100644 --- a/NUCLEUSmod/NUCLEUSmod_createGUI.m +++ b/NUCLEUSmod/NUCLEUSmod_createGUI.m @@ -29,8 +29,8 @@ function NUCLEUSmod_createGUI(h,wbon) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSmod/NUCLEUSmod_createMenus.m b/NUCLEUSmod/NUCLEUSmod_createMenus.m index 7b38e1d..462eff1 100644 --- a/NUCLEUSmod/NUCLEUSmod_createMenus.m +++ b/NUCLEUSmod/NUCLEUSmod_createMenus.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSmod/NUCLEUSmod_createPanelCPS.m b/NUCLEUSmod/NUCLEUSmod_createPanelCPS.m index ac63e0d..0d1c5b0 100644 --- a/NUCLEUSmod/NUCLEUSmod_createPanelCPS.m +++ b/NUCLEUSmod/NUCLEUSmod_createPanelCPS.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSmod/NUCLEUSmod_createPanelGeometry.m b/NUCLEUSmod/NUCLEUSmod_createPanelGeometry.m index 5d5feb1..5485372 100644 --- a/NUCLEUSmod/NUCLEUSmod_createPanelGeometry.m +++ b/NUCLEUSmod/NUCLEUSmod_createPanelGeometry.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSmod/NUCLEUSmod_createPanelNMR.m b/NUCLEUSmod/NUCLEUSmod_createPanelNMR.m index 5755e45..4c707ad 100644 --- a/NUCLEUSmod/NUCLEUSmod_createPanelNMR.m +++ b/NUCLEUSmod/NUCLEUSmod_createPanelNMR.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -34,10 +34,10 @@ gui.panels.nmr.VBox = uix.VBox('Parent',gui.panels.nmr.main,... 'Spacing',3,'Padding',3); -% Tbulk & surface relaxivity rho +% Tbulk & Tdiff gui.panels.nmr.HBox1 = uix.HBox('Parent',gui.panels.nmr.VBox,... 'Spacing',3); -% echo time TE & number of echos +% surface relaxivity rho & echo time TE & number of echos gui.panels.nmr.HBox2 = uix.HBox('Parent',gui.panels.nmr.VBox,... 'Spacing',3); % RUN button @@ -47,51 +47,62 @@ gui.panels.nmr.HBox4 = uix.HBox('Parent',gui.panels.nmr.VBox,... 'Spacing',3); -%% Tbulk & surface relaxivity rho +%% Tbulk & Tdiff gui.text_handles.Tbulk = uicontrol('Parent',gui.panels.nmr.HBox1,... 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String','Tbulk [s]'); -tstr = ['Set relaxation time of bulk water.

',... + 'String','Tbulk [s] | Tdiff [s]'); +tstr = ['Bulk relaxation time in [s].

',... + '1/T = 1/Ts + 1/Tb + 1/Td

',... 'Default value:
',... - '2 s
']; + '2
']; gui.edit_handles.Tbulk = uicontrol('Parent',gui.panels.nmr.HBox1,... 'Style','edit','String',num2str(data.nmr.Tbulk),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.Tbulk 1 1]),... 'Tag','nmr_Tbulk','Enable','on','Callback',@onEditValue); -gui.text_handles.rho = uicontrol('Parent',gui.panels.nmr.HBox1,... +tstr = ['Diffusion relaxation time in [s].

',... + '1/T = 1/Ts + 1/Tb + 1/Td

',... + 'Td can be caluclated by

',... + 'Td = 12 / (D*(',char(hex2dec('03B3')),'*G*TE)2 )

',... + 'with

',... + 'D = diffusion coefficent of water
',... + char(hex2dec('03B3')),' = gyromagnetic ratio of hydrogen
',... + 'G = magnetic gradient
',... + 'TE = echo time

',... + 'Default value:
',... + '1e6 (so that 1/Td is ignored)
']; +gui.edit_handles.Tdiff = uicontrol('Parent',gui.panels.nmr.HBox1,... + 'Style','edit','String',num2str(data.nmr.Tdiff),'FontSize',myui.fontsize,... + 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.Tdiff 1 1]),... + 'Tag','nmr_Tdiff','Enable','on','Callback',@onEditValue); +set(gui.panels.nmr.HBox1,'Widths',[200 -1 -1]); + +%% surface relaxivity rho & echo time TE & number of echoes +gui.text_handles.rho = uicontrol('Parent',gui.panels.nmr.HBox2,... 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String',[char(hex2dec('03C1')),' [µm/s]']); -tstr = ['Set surface relaxivity &rho .

',... + 'String',[char(hex2dec('03C1')),' [µm/s] | TE [µs] | # echoes']); +tstr = ['Surface relaxivity in [µm/s].

',... + '1/Ts = rho*S/V = rho*a/R.

',... 'Default value:
',... - '10 µm/s
']; -gui.edit_handles.rho = uicontrol('Parent',gui.panels.nmr.HBox1,... + '10
']; +gui.edit_handles.rho = uicontrol('Parent',gui.panels.nmr.HBox2,... 'Style','edit','String',num2str(data.nmr.rho),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.rho 1 1]),... 'Tag','nmr_rho','Enable','on','Callback',@onEditValue); -set(gui.panels.nmr.HBox1,'Widths',[100 -1 100 -1]); - -%% echo time TE & number of echoes -gui.text_handles.TE = uicontrol('Parent',gui.panels.nmr.HBox2,... - 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String','echo time [µs]'); -tstr = ['Set echo time.

',... +tstr = ['Echo time TE in [µs].

',... 'Default value:
',... - '1000 µs
']; + '1000
']; gui.edit_handles.TE = uicontrol('Parent',gui.panels.nmr.HBox2,... 'Style','edit','String',num2str(data.nmr.TE),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.TE 1 1]),... 'Tag','nmr_TE','Enable','on','Callback',@onEditValue); -gui.text_handles.echosN = uicontrol('Parent',gui.panels.nmr.HBox2,... - 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String','# echoes'); -tstr = ['Set number of echoes.

',... +tstr = ['Number of echoes.

',... 'Default value:
',... '1001
']; gui.edit_handles.echosN = uicontrol('Parent',gui.panels.nmr.HBox2,... 'Style','edit','String',num2str(data.nmr.echosN),'FontSize',myui.fontsize,... 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.echosN 1 1]),... 'Tag','nmr_echosN','Enable','on','Callback',@onEditValue); -set(gui.panels.nmr.HBox2,'Widths',[100 -1 100 -1]); +set(gui.panels.nmr.HBox2,'Widths',[200 -1 -1 -1]); %% RUN button gui.text_handles.nmr_RUN = uicontrol('Parent',gui.panels.nmr.HBox3,... @@ -103,10 +114,19 @@ set(gui.panels.nmr.HBox3,'Widths',[200 -1]); %% noise & porosity -gui.text_handles.noise = uicontrol('Parent',gui.panels.nmr.HBox4,... - 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... - 'String','add noise'); -tstr = ['Set NMR data noise.

',... + +tstr = ['NMR data noise method.

',... + 'A noise level will be used globally for all NMR signals.
',... + 'A signal-to-ratio will be used individually on every single NMR signal.

',... + 'Available options:
',... + 'noise level or SNR

',... + 'Default value:
',... + 'noise level
']; +gui.popup_handles.noisetype = uicontrol('Parent',gui.panels.nmr.HBox4,... + 'Style','popup','String',{'noise level','SNR'},... + 'Value',1,'FontSize',myui.fontsize,'UserData',struct('Tooltipstr',tstr),... + 'Callback',@onPopupNMRNoiseType); +tstr = ['NMR data noise.

',... 'Hint:
',... 'You do not need to press RUN to add noise to the NMR signals.
',... 'The raw NMR signals are stored internally and the noise is
',... @@ -120,7 +140,7 @@ gui.text_handles.porosity = uicontrol('Parent',gui.panels.nmr.HBox4,... 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... 'String','porosity'); -tstr = ['Set porosity value in the range [0, 1].

',... +tstr = ['Porosity value in the range [0, 1].

',... 'Note:
',... 'This value is applied only as a scaling factor to the NMR amplitudes.
',... 'Hence, saturation becomes water content.']; @@ -135,14 +155,8 @@ jh.setVerticalAlignment(javax.swing.JLabel.CENTER); jh = findjobj(gui.text_handles.rho); jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -jh = findjobj(gui.text_handles.TE ); -jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -jh = findjobj(gui.text_handles.echosN ); -jh.setVerticalAlignment(javax.swing.JLabel.CENTER); jh = findjobj(gui.text_handles.nmr_RUN); jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -jh = findjobj(gui.text_handles.noise); -jh.setVerticalAlignment(javax.swing.JLabel.CENTER); jh = findjobj(gui.text_handles.porosity); jh.setVerticalAlignment(javax.swing.JLabel.CENTER); diff --git a/NUCLEUSmod/NUCLEUSmod_createPanelPlots.m b/NUCLEUSmod/NUCLEUSmod_createPanelPlots.m index 9a18aa6..46bf877 100644 --- a/NUCLEUSmod/NUCLEUSmod_createPanelPlots.m +++ b/NUCLEUSmod/NUCLEUSmod_createPanelPlots.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/NUCLEUSmod/NUCLEUSmod_createStatusbar.m b/NUCLEUSmod/NUCLEUSmod_createStatusbar.m index 66c9b2a..8f2af5d 100644 --- a/NUCLEUSmod/NUCLEUSmod_createStatusbar.m +++ b/NUCLEUSmod/NUCLEUSmod_createStatusbar.m @@ -24,8 +24,8 @@ % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md %------------- BEGIN CODE -------------- diff --git a/NUCLEUSmod/NUCLEUSmod_loadDefaults.m b/NUCLEUSmod/NUCLEUSmod_loadDefaults.m index c382e05..e187ae7 100644 --- a/NUCLEUSmod/NUCLEUSmod_loadDefaults.m +++ b/NUCLEUSmod/NUCLEUSmod_loadDefaults.m @@ -21,8 +21,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -73,10 +73,14 @@ out.nmr.TE = 1000; % number of echoes out.nmr.echosN = 1001; -% noise level [%] +% noise creation type 'level' or 'SNR' +out.nmr.noisetype = 'level'; +% noise level [0:1] or SNR [-] out.nmr.noise = 0; % water bulk relaxation time [s] out.nmr.Tbulk = 2; +% diffusion relaxation time [s] +out.nmr.Tdiff = 1e6; % surface relaxivity [µm/s] out.nmr.rho = 10; % porosity value between 0 and 1 [-] diff --git a/NUCLEUSmod/NUCLEUSmod_updateInterface.m b/NUCLEUSmod/NUCLEUSmod_updateInterface.m index ea8b086..4f0cef9 100644 --- a/NUCLEUSmod/NUCLEUSmod_updateInterface.m +++ b/NUCLEUSmod/NUCLEUSmod_updateInterface.m @@ -22,8 +22,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -125,6 +125,14 @@ end %% update NMR panel +% noise type +switch data.nmr.noisetype + case 'level' % noise level + set(gui.popup_handles.noisetype,'Value',1); + case 'SNR' % signal-to-noise ratio (SNR) + set(gui.popup_handles.noisetype,'Value',2); +end + % all edit fields set(gui.edit_handles.Tbulk,'String',num2str(data.nmr.Tbulk)); set(gui.edit_handles.rho,'String',num2str(data.nmr.rho)); diff --git a/README.md b/README.md index 36192bc..ce8f44b 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ modeling and i**N**version of n**UCL**ear magnetic r**E**sonance data with ang** ### About -**NUCLEUS** is a set of MATLABTM tools, that allow forward and inverse modeling of nuclear magnetic resonance (NMR) relaxometry data. The main front-ends to these tools are two graphical user interfaces, **NUCLEUSmod** and **NUCLEUSinv** for forward and inverse modeling, respectively. For simple NMR relaxometry data inversion, the **NUCLEUSinv** GUI may be a little *feature-rich*. But one of the ideas, when starting to develop this code, was to help students understand the basic concepts of NMR relaxometry data inversion. +**NUCLEUS** is a set of MATLABTM tools, that allow forward and inverse modeling of nuclear magnetic resonance (NMR) relaxometry data (T1 and T2 relaxation). The main front-ends to these tools are two graphical user interfaces, **NUCLEUSmod** and **NUCLEUSinv** for forward and inverse modeling, respectively. For simple NMR relaxometry data inversion, the **NUCLEUSinv** GUI may be a little *feature-rich*. But one of the ideas, when starting to develop this code, was to help students understand the basic concepts of NMR relaxometry data inversion. ###### NUCLEUSmod basic features: @@ -62,7 +62,7 @@ If you do not have the Optimization or Statistics toolboxes then not all feature #### Operating System -I tested it successfully under Windows 7 (64bit) and 10 (64bit) with Matlab R2014b and newer. Always with the latest version of the GUI Layout Toolbox (current version is v2.3.4) +I tested it successfully under Windows 7 (64bit) and 10 (64bit) with Matlab R2014b and newer. Always with the latest version of the GUI Layout Toolbox (current version is v2.3.5) **NOTE:** So far I did not test anything on Linux or a Mac. If you get it to work on either of the two systems (which it basically should I guess) please let me know. @@ -108,13 +108,15 @@ In no particular order and without guarantee that it will ever happen :-) : ### Cite as If you use NUCLEUS for your research, please cite it as: -Thomas Hiller. (2021, March 12). ThoHiller/nmr-nucleus: v0.1.11 (Version v0.1.11). Zenodo. [https://doi.org/10.5281/zenodo.4022195] +Thomas Hiller. (2021, March 12). ThoHiller/nmr-nucleus: v0.1.12 (Version v0.1.12). Zenodo. [https://doi.org/10.5281/zenodo.4022195] Note: Even though the version number might change due to updates, this DOI is permanent (represents all versions) and always links to the latest version. + ### References -1. Hiller, T. and Klitzsch, N., "Joint inversion of nuclear magnetic resonance data from partially saturated rocks using a triangular pore model", *GEOPHYSICS* **83**(4), JM15-JM28, 2018, [DOI](https://doi.org/10.1190/geo2017-0697.1) -2. Costabel, S. and Hiller, T., "Soil hydraulic interpretation of nuclear magnetic resonance measurements based on circular and triangular capillary models", *Vadose Zone Journal*, 2021, e20104, [DOI](https://doi.org/10.1002/vzj2.20104) +1. Hiller, T., Costabel, S., Radic, T., Dlugosch, R. and Müller-Petke, M. "Feasibility study on prepolarized surface nuclear magnetic resonance for soil moisture measurements", *Vadose Zone Journal*, **20**(5), 2021, e20138, [DOI](https://doi.org/10.1002/vzj2.20138) +2. Costabel, S. and Hiller, T., "Soil hydraulic interpretation of nuclear magnetic resonance measurements based on circular and triangular capillary models", *Vadose Zone Journal*, **20**(2), 2021, e20104, [DOI](https://doi.org/10.1002/vzj2.20104) +3. Hiller, T. and Klitzsch, N., "Joint inversion of nuclear magnetic resonance data from partially saturated rocks using a triangular pore model", *GEOPHYSICS*, **83**(4), JM15-JM28, 2018, [DOI](https://doi.org/10.1190/geo2017-0697.1) - - -

MATLAB is a registered trademark of The Mathworks, Inc.

\ No newline at end of file diff --git a/callbacks/contextmenus/onContextAxisLogLin.m b/callbacks/contextmenus/onContextAxisLogLin.m index 47da942..5911082 100644 --- a/callbacks/contextmenus/onContextAxisLogLin.m +++ b/callbacks/contextmenus/onContextAxisLogLin.m @@ -26,8 +26,8 @@ function onContextAxisLogLin(src,~) % none % % See also: NUCLEUSmod, NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/contextmenus/onContextAxisT1T2.m b/callbacks/contextmenus/onContextAxisT1T2.m index cfb049a..e97c777 100644 --- a/callbacks/contextmenus/onContextAxisT1T2.m +++ b/callbacks/contextmenus/onContextAxisT1T2.m @@ -24,8 +24,8 @@ function onContextAxisT1T2(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/contextmenus/onContextPlotsPSD.m b/callbacks/contextmenus/onContextPlotsPSD.m index 1ffb49c..7c28f30 100644 --- a/callbacks/contextmenus/onContextPlotsPSD.m +++ b/callbacks/contextmenus/onContextPlotsPSD.m @@ -27,8 +27,8 @@ function onContextPlotsPSD(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/contextmenus/onContextPlotsPSDJ.m b/callbacks/contextmenus/onContextPlotsPSDJ.m index 38cdbea..3313671 100644 --- a/callbacks/contextmenus/onContextPlotsPSDJ.m +++ b/callbacks/contextmenus/onContextPlotsPSDJ.m @@ -24,8 +24,8 @@ function onContextPlotsPSDJ(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/contextmenus/onContextPlotsRTD.m b/callbacks/contextmenus/onContextPlotsRTD.m index bf64784..91ec38d 100644 --- a/callbacks/contextmenus/onContextPlotsRTD.m +++ b/callbacks/contextmenus/onContextPlotsRTD.m @@ -25,8 +25,8 @@ function onContextPlotsRTD(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/contextmenus/onContextSignalList.m b/callbacks/contextmenus/onContextSignalList.m index 8bbffa6..74f784f 100644 --- a/callbacks/contextmenus/onContextSignalList.m +++ b/callbacks/contextmenus/onContextSignalList.m @@ -31,8 +31,8 @@ function onContextSignalList(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/contextmenus/onContextTableSelect.m b/callbacks/contextmenus/onContextTableSelect.m index 3dd4d82..ca17b45 100644 --- a/callbacks/contextmenus/onContextTableSelect.m +++ b/callbacks/contextmenus/onContextTableSelect.m @@ -25,8 +25,8 @@ function onContextTableSelect(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/edits/onEditCPSTable.m b/callbacks/edits/onEditCPSTable.m index c80bfa4..5570d20 100644 --- a/callbacks/edits/onEditCPSTable.m +++ b/callbacks/edits/onEditCPSTable.m @@ -23,8 +23,8 @@ function onEditCPSTable(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/edits/onEditValue.m b/callbacks/edits/onEditValue.m index 6ef57cf..db2d7a3 100644 --- a/callbacks/edits/onEditValue.m +++ b/callbacks/edits/onEditValue.m @@ -26,7 +26,6 @@ function onEditValue(src,~) % updateInfo % updateNMRsignals % updatePlotsDistribution -% updatePlotsNMR % updatePlotsSignal % % Subfunctions: @@ -36,8 +35,8 @@ function onEditValue(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -146,6 +145,12 @@ function onEditValue(src,~) setappdata(fig,'data',data); set(src,'String',num2str(data.invstd.Tbulk)); end + case 'Tdiff' + if data.invstd.Tdiff <=0 + data.invstd.Tdiff = 1e6; + setappdata(fig,'data',data); + set(src,'String',num2str(data.invstd.Tdiff)); + end case 'porosity' if data.invstd.porosity < 0 || data.invstd.porosity > 1 data.invstd.porosity = 1; @@ -225,9 +230,17 @@ function onEditValue(src,~) case 'nmr' switch out.field case 'noise' + switch data.nmr.noisetype + case 'level' + case 'SNR' + if data.nmr.noise == 0 + data.nmr.noise = Inf; + set(src,'String',num2str(data.nmr.noise)); + end + end + setappdata(fig,'data',data); if isfield(data.results,'NMR') updateNMRsignals; - updatePlotsNMR; end case 'porosity' if data.nmr.porosity <= 0 || data.nmr.porosity > 1 @@ -237,7 +250,6 @@ function onEditValue(src,~) end if isfield(data.results,'NMR') updateNMRsignals; - updatePlotsNMR; end otherwise data = removeCalculationFields(data,'nmr'); diff --git a/callbacks/listboxes/onListboxData.m b/callbacks/listboxes/onListboxData.m index c3d5558..07706f7 100644 --- a/callbacks/listboxes/onListboxData.m +++ b/callbacks/listboxes/onListboxData.m @@ -32,8 +32,8 @@ function onListboxData(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -98,7 +98,7 @@ function onListboxData(src,~) data.process.start = 1; case 'T2' switch data.import.fileformat - case {'dart','field','mouse','NMRMOD','excel'} + case {'dart','excel','field','helios','mouse','NMRMOD'} data.process.gatetype = 'raw'; data.process.start = 1; otherwise @@ -147,7 +147,8 @@ function onListboxData(src,~) end if isfield(data.import,'NMRMOD') data.param.rho = data.import.NMR.para{id}.rho*1e6; - data.invstd.Tbulk = data.import.NMR.para{id}.Tbulk; + data.invstd.Tbulk = data.import.NMR.para{id}.Tbulk; + data.invstd.Tdiff = data.import.NMR.para{id}.Tdiff; data.invstd.porosity = data.import.NMR.para{id}.porosity; end % --- diff --git a/callbacks/menus/onMenuExpert.m b/callbacks/menus/onMenuExpert.m index 02076ab..f566e50 100644 --- a/callbacks/menus/onMenuExpert.m +++ b/callbacks/menus/onMenuExpert.m @@ -31,8 +31,8 @@ function onMenuExpert(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -48,7 +48,7 @@ function onMenuExpert(src,~) % deactivate or activate expert mode switch onoff - case 'on' % it it's on, switch it off + case 'on' % if it's on, switch it off data.info.ExpertMode = 'off'; % menu entry set(gui.menu.extra_expert,'Checked','off'); diff --git a/callbacks/menus/onMenuExportData.m b/callbacks/menus/onMenuExportData.m index bbd2a59..9765c05 100644 --- a/callbacks/menus/onMenuExportData.m +++ b/callbacks/menus/onMenuExportData.m @@ -24,8 +24,8 @@ function onMenuExportData(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuExportGraphics.m b/callbacks/menus/onMenuExportGraphics.m index db838cc..faca7ae 100644 --- a/callbacks/menus/onMenuExportGraphics.m +++ b/callbacks/menus/onMenuExportGraphics.m @@ -26,8 +26,8 @@ function onMenuExportGraphics(src,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuExtraColor.m b/callbacks/menus/onMenuExtraColor.m index ffc4bf6..2c0860a 100644 --- a/callbacks/menus/onMenuExtraColor.m +++ b/callbacks/menus/onMenuExtraColor.m @@ -23,8 +23,8 @@ function onMenuExtraColor(src,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuExtraRhoBounds.m b/callbacks/menus/onMenuExtraRhoBounds.m index 42193d5..ffda8e3 100644 --- a/callbacks/menus/onMenuExtraRhoBounds.m +++ b/callbacks/menus/onMenuExtraRhoBounds.m @@ -23,8 +23,8 @@ function onMenuExtraRhoBounds(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuHelp.m b/callbacks/menus/onMenuHelp.m index 3c5b94e..8f97786 100644 --- a/callbacks/menus/onMenuHelp.m +++ b/callbacks/menus/onMenuHelp.m @@ -23,8 +23,8 @@ function onMenuHelp(src,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuImport.m b/callbacks/menus/onMenuImport.m index 23e07e3..4114d12 100644 --- a/callbacks/menus/onMenuImport.m +++ b/callbacks/menus/onMenuImport.m @@ -29,8 +29,8 @@ function onMenuImport(src,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -68,13 +68,15 @@ function onMenuImport(src,~) % activate the PhaseView GUI in case real data is imported switch menu_tag - case {'NUCLEUSinv','NUCLEUSmod'} + case 'NUCLEUSmod' set(gui.menu.extra_phaseview,'Enable','off'); otherwise set(gui.menu.extra_phaseview,'Enable','on'); end - % update the "last import" value within the ini-file + % get updated gui data + gui = getappdata(fig,'gui'); + % update the "last import" value within the ini-file gui.myui.inidata.lastimport = [menu_tag,'_',label]; setappdata(fig,'gui',gui); gui = makeINIfile(gui,'update'); diff --git a/callbacks/menus/onMenuJointInversion.m b/callbacks/menus/onMenuJointInversion.m index 2f989d4..4b74e72 100644 --- a/callbacks/menus/onMenuJointInversion.m +++ b/callbacks/menus/onMenuJointInversion.m @@ -30,8 +30,8 @@ function onMenuJointInversion(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuRestartQuit.m b/callbacks/menus/onMenuRestartQuit.m index 6466507..ff947f8 100644 --- a/callbacks/menus/onMenuRestartQuit.m +++ b/callbacks/menus/onMenuRestartQuit.m @@ -24,8 +24,8 @@ function onMenuRestartQuit(src,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuSolver.m b/callbacks/menus/onMenuSolver.m index fe32035..c668573 100644 --- a/callbacks/menus/onMenuSolver.m +++ b/callbacks/menus/onMenuSolver.m @@ -25,8 +25,8 @@ function onMenuSolver(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuView.m b/callbacks/menus/onMenuView.m index 77dc216..66c699f 100644 --- a/callbacks/menus/onMenuView.m +++ b/callbacks/menus/onMenuView.m @@ -24,8 +24,8 @@ function onMenuView(src,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/menus/onMenuViewFigures.m b/callbacks/menus/onMenuViewFigures.m index b964396..7a87499 100644 --- a/callbacks/menus/onMenuViewFigures.m +++ b/callbacks/menus/onMenuViewFigures.m @@ -24,8 +24,8 @@ function onMenuViewFigures(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupGeometryModesN.m b/callbacks/popup/onPopupGeometryModesN.m index e2f8ad6..8a12182 100644 --- a/callbacks/popup/onPopupGeometryModesN.m +++ b/callbacks/popup/onPopupGeometryModesN.m @@ -25,8 +25,8 @@ function onPopupGeometryModesN(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupGeometryPolyN.m b/callbacks/popup/onPopupGeometryPolyN.m index 12512ec..89bf707 100644 --- a/callbacks/popup/onPopupGeometryPolyN.m +++ b/callbacks/popup/onPopupGeometryPolyN.m @@ -25,8 +25,8 @@ function onPopupGeometryPolyN(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupGeometrySinglePSD.m b/callbacks/popup/onPopupGeometrySinglePSD.m index de70f90..69457f7 100644 --- a/callbacks/popup/onPopupGeometrySinglePSD.m +++ b/callbacks/popup/onPopupGeometrySinglePSD.m @@ -25,8 +25,8 @@ function onPopupGeometrySinglePSD(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupGeometryType.m b/callbacks/popup/onPopupGeometryType.m index 85a791a..5d30471 100644 --- a/callbacks/popup/onPopupGeometryType.m +++ b/callbacks/popup/onPopupGeometryType.m @@ -25,8 +25,8 @@ function onPopupGeometryType(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupInvjointGeometryType.m b/callbacks/popup/onPopupInvjointGeometryType.m index 904c966..d284620 100644 --- a/callbacks/popup/onPopupInvjointGeometryType.m +++ b/callbacks/popup/onPopupInvjointGeometryType.m @@ -24,8 +24,8 @@ function onPopupInvjointGeometryType(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupInvjointPolyN.m b/callbacks/popup/onPopupInvjointPolyN.m index eda133a..ad02068 100644 --- a/callbacks/popup/onPopupInvjointPolyN.m +++ b/callbacks/popup/onPopupInvjointPolyN.m @@ -24,8 +24,8 @@ function onPopupInvjointPolyN(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupInvjointType.m b/callbacks/popup/onPopupInvjointType.m index e6100e0..ddfaa3c 100644 --- a/callbacks/popup/onPopupInvjointType.m +++ b/callbacks/popup/onPopupInvjointType.m @@ -24,8 +24,8 @@ function onPopupInvjointType(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupInvjointTypeOptional.m b/callbacks/popup/onPopupInvjointTypeOptional.m index 5faede1..444305d 100644 --- a/callbacks/popup/onPopupInvjointTypeOptional.m +++ b/callbacks/popup/onPopupInvjointTypeOptional.m @@ -25,8 +25,8 @@ function onPopupInvjointTypeOptional(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupInvstdType.m b/callbacks/popup/onPopupInvstdType.m index 62edaa9..fe4c6ee 100644 --- a/callbacks/popup/onPopupInvstdType.m +++ b/callbacks/popup/onPopupInvstdType.m @@ -25,8 +25,8 @@ function onPopupInvstdType(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -62,6 +62,11 @@ function onPopupInvstdType(src,~) data.invstd.invtype = 'LU'; data.invstd.regtype = 'auto'; data.invstd.lambda = -1; + + case 5 + data.invstd.invtype = 'MUMO'; + data.invstd.regtype = 'none'; + data.invstd.lambda = 1; end case 'off' @@ -89,12 +94,17 @@ function onPopupInvstdType(src,~) else data.invstd.regtype = 'manual'; data.invstd.lambda = 1e-2; - end + end % update GUI data setappdata(fig,'data',data); % because the gate type could have changed update data onRadioGates(gui.radio_handles.process_gates_log); data = getappdata(fig,'data'); + + case 4 + data.invstd.invtype = 'MUMO'; + data.invstd.regtype = 'none'; + data.invstd.lambda = 1; end end % update GUI data diff --git a/callbacks/popup/onPopupInvstdTypeOptional.m b/callbacks/popup/onPopupInvstdTypeOptional.m index ca3a91d..e9b6278 100644 --- a/callbacks/popup/onPopupInvstdTypeOptional.m +++ b/callbacks/popup/onPopupInvstdTypeOptional.m @@ -27,8 +27,8 @@ function onPopupInvstdTypeOptional(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -135,6 +135,10 @@ function onPopupInvstdTypeOptional(src,~) data.invstd.regtype = 'auto'; data.invstd.lambda = -1; end + + case 'MUMO' + % # free distributions = value (1 to 4) + data.invstd.freeDT = value; end % update GUI data diff --git a/callbacks/popup/onPopupNMRNoiseType.m b/callbacks/popup/onPopupNMRNoiseType.m new file mode 100644 index 0000000..1d381d0 --- /dev/null +++ b/callbacks/popup/onPopupNMRNoiseType.m @@ -0,0 +1,92 @@ +function onPopupNMRNoiseType(src,~) +%onPopupNMRNoiseType selects the noise type to be aplied to the forward +%modelled NMR data +% +% Syntax: +% onPopupNMRNoiseType +% +% Inputs: +% src - handle of the calling object +% +% Outputs: +% none +% +% Example: +% onPopupNMRNoiseType(src,~) +% +% Other m-files required: +% clearSingleAxis.m +% updateCPSTable.m +% +% Subfunctions: +% none +% +% MAT-files required: +% none +% +% See also: NUCLEUSmod +% Author: see AUTHORS.md +% email: see AUTHORS.md +% License: MIT License (at end) + +%------------- BEGIN CODE -------------- + +%% get GUI handle and data +fig = findobj('Tag','MOD'); +data = getappdata(fig,'data'); +gui = getappdata(fig,'gui'); + +% get the value of the popup menu +value = get(src,'Value'); + +% change settings accordingly +switch value + case 1 % noise level + data.nmr.noisetype = 'level'; + if data.nmr.noise > 0 + data.nmr.noise = 1/data.nmr.noise; + end + case 2 % signal-to-noise ratio (SNR) + data.nmr.noisetype = 'SNR'; + if data.nmr.noise == 0 + data.nmr.noise = inf; + else + data.nmr.noise = 1/data.nmr.noise; + end +end +% update the corresponding edit field +set(gui.edit_handles.noise,'String',num2str(data.nmr.noise)); + +% update GUI data +setappdata(fig,'data',data); +% update NMR data (if available) +if isfield(data.results,'NMR') + updateNMRsignals; +end + +end + +%------------- END OF CODE -------------- + +%% License: +% MIT License +% +% Copyright (c) 2021 Thomas Hiller +% +% Permission is hereby granted, free of charge, to any person obtaining a copy +% of this software and associated documentation files (the "Software"), to deal +% in the Software without restriction, including without limitation the rights +% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the Software is +% furnished to do so, subject to the following conditions: +% +% The above copyright notice and this permission notice shall be included in all +% copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +% SOFTWARE. \ No newline at end of file diff --git a/callbacks/popup/onPopupPressureLoglin.m b/callbacks/popup/onPopupPressureLoglin.m index 6255b01..d752af6 100644 --- a/callbacks/popup/onPopupPressureLoglin.m +++ b/callbacks/popup/onPopupPressureLoglin.m @@ -25,8 +25,8 @@ function onPopupPressureLoglin(src,~) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/popup/onPopupPressureUnits.m b/callbacks/popup/onPopupPressureUnits.m index 47cfcd3..48b3eb1 100644 --- a/callbacks/popup/onPopupPressureUnits.m +++ b/callbacks/popup/onPopupPressureUnits.m @@ -24,8 +24,8 @@ function onPopupPressureUnits(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/push/onPushCPSTable.m b/callbacks/push/onPushCPSTable.m index 053dacf..b0160e9 100644 --- a/callbacks/push/onPushCPSTable.m +++ b/callbacks/push/onPushCPSTable.m @@ -24,8 +24,8 @@ function onPushCPSTable(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/push/onPushRun.m b/callbacks/push/onPushRun.m index ebc1f02..8ad7eb4 100644 --- a/callbacks/push/onPushRun.m +++ b/callbacks/push/onPushRun.m @@ -27,8 +27,8 @@ function onPushRun(src,~) % calculateNMR % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/push/onPushShowHide.m b/callbacks/push/onPushShowHide.m index 898878e..78eb9cf 100644 --- a/callbacks/push/onPushShowHide.m +++ b/callbacks/push/onPushShowHide.m @@ -23,8 +23,8 @@ function onPushShowHide(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/push/onPushStop.m b/callbacks/push/onPushStop.m index 25fa4ba..123b302 100644 --- a/callbacks/push/onPushStop.m +++ b/callbacks/push/onPushStop.m @@ -26,8 +26,8 @@ function onPushStop(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/radio/onRadioGates.m b/callbacks/radio/onRadioGates.m index 876be07..51404ec 100644 --- a/callbacks/radio/onRadioGates.m +++ b/callbacks/radio/onRadioGates.m @@ -26,8 +26,8 @@ function onRadioGates(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/radio/onRadioLorder.m b/callbacks/radio/onRadioLorder.m index b69dbd8..45a9f56 100644 --- a/callbacks/radio/onRadioLorder.m +++ b/callbacks/radio/onRadioLorder.m @@ -24,8 +24,8 @@ function onRadioLorder(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/radio/onRadioNormalize.m b/callbacks/radio/onRadioNormalize.m index 12ed20b..bcaa50a 100644 --- a/callbacks/radio/onRadioNormalize.m +++ b/callbacks/radio/onRadioNormalize.m @@ -26,8 +26,8 @@ function onRadioNormalize(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/callbacks/radio/onRadioTimescale.m b/callbacks/radio/onRadioTimescale.m index d70df46..e0afa54 100644 --- a/callbacks/radio/onRadioTimescale.m +++ b/callbacks/radio/onRadioTimescale.m @@ -26,8 +26,8 @@ function onRadioTimescale(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -55,6 +55,7 @@ function onRadioTimescale(src,~) data.process.timefac = 1; data.invstd.time = data.invstd.time ./ 1000; data.invstd.Tbulk = data.invstd.Tbulk ./ 1000; + data.invstd.Tdiff = data.invstd.Tdiff ./ 1000; end case 'ms' @@ -63,6 +64,7 @@ function onRadioTimescale(src,~) data.process.timefac = 1000; data.invstd.time = data.invstd.time .* 1000; data.invstd.Tbulk = data.invstd.Tbulk .* 1000; + data.invstd.Tdiff = data.invstd.Tdiff .* 1000; end end diff --git a/doc/menu.html b/doc/menu.html index c55120a..1cd7e85 100644 --- a/doc/menu.html +++ b/doc/menu.html @@ -16,7 +16,7 @@

Matlab Index

Matlab Directories

- +
Generated by m2html © 2005
diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv.html index 67d39e0..c121aed 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv.html @@ -54,8 +54,8 @@

DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also NUCLEUSmod -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- @@ -111,10 +111,10 @@

SOURCE CODE ^if ~isempty(h0); close(h0); end 0039 0040 %% GUI 'header' info and defaults -0041 myui.version = '0.1.11'; -0042 myui.date = '12.03.2021'; -0043 myui.author = {'Thomas Hiller','Stephan Costabel'}; -0044 myui.email = 'thomas.hiller[at]leibniz-liag.de'; +0041 myui.version = '0.1.12'; +0042 myui.date = '17.02.2022'; +0043 myui.author = {'Stephan Costabel','Thomas Hiller'}; +0044 myui.email = 'thomas.hiller[at]bgr.de'; 0045 myui.fontsize = 10; 0046 myui.inifile = 'NUCLEUSinv.ini'; 0047 diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createGUI.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createGUI.html index 7fbeec2..a7f0549 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createGUI.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createGUI.html @@ -63,15 +63,15 @@

DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end)

CROSS-REFERENCE INFORMATION ^

This function calls: +
  • NUCLEUSinv_createMenus creates all GUI menus
  • NUCLEUSinv_createPanelData creates data panel
  • NUCLEUSinv_createPanelInfo creates status bar
  • NUCLEUSinv_createPanelInversionJoint creates joint inversion panel
  • NUCLEUSinv_createPanelInversionStd creates standard inversion panel
  • NUCLEUSinv_createPanelPetro creates Petrophysics panel
  • NUCLEUSinv_createPanelPlots creates graphics panel
  • NUCLEUSinv_createPanelProcess creates process panel
  • NUCLEUSinv_createStatusbar creates status bar
  • NUCLEUSinv_processINI processes the ini-file
  • changeColorTheme changes the color theme of the calling figure
  • displayStatusText shows status information either in the GUI or on the
  • getColorTheme returns the colors of the selected color theme
  • minimizePanel handles the minimization/maximization of all box-panels for
  • switchToolTips switches GUI tool tips either "on" or "off"
  • updateStatusInformation updates all fields inside the bottom status bar
  • updateToolTips updates tool tip entries dependent on the chosen settings
  • This function is called by: @@ -118,8 +118,8 @@

    SOURCE CODE ^% none 0037 % 0038 % See also: NUCLEUSinv -0039 % Author: Thomas Hiller -0040 % email: thomas.hiller[at]leibniz-liag.de +0039 % Author: see AUTHORS.md +0040 % email: see AUTHORS.md 0041 % License: MIT License (at end) 0042 0043 %------------- BEGIN CODE -------------- @@ -200,7 +200,7 @@

    SOURCE CODE ^'TitleColor',myui.colors.BoxCPS,'ForegroundColor',myui.colors.BoxTitle); 0119 0120 % adjust the heights of all left-column-panels -0121 myui.heights = [250 22 22 22 22; -1 109 137 190 299]; +0121 myui.heights = [250 22 22 22 22; -1 109 165 190 299]; 0122 % panel header is always 22 high 0123 set(gui.panels.main,'Heights',myui.heights(2,:),... 0124 'MinimumHeights',[250 22 22 22 22]); @@ -281,7 +281,7 @@

    SOURCE CODE ^% otherwise "fixAxes" throws an error (in NUCLEUSmod); strangely here it 0200 % also works without it, but I put it for consistency reasons 0201 setappdata(h,'gui',gui); -0202 % changeColorTheme('INV',myui.colors.theme); +0202 changeColorTheme('INV',myui.colors.theme); 0203 set(gui.main,'Visible','on'); 0204 0205 %% enable all menus diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createMenus.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createMenus.html index 28b991b..acae6e6 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createMenus.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createMenus.html @@ -51,8 +51,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- @@ -131,350 +131,361 @@

    SOURCE CODE ^% 1.1.1.2.1 BGR std 0062 gui.menu.file_import_lab_bgr_std = uimenu(gui.menu.file_import_lab_bgr,... 0063 'Label','BGR std','Tag','Lab','Callback',@onMenuImport); -0064 % 1.1.1.2.2 BGR org -0065 gui.menu.file_import_lab_bgr_org = uimenu(gui.menu.file_import_lab_bgr,... -0066 'Label','BGR org','Tag','Lab','Callback',@onMenuImport); -0067 % 1.1.1.2.3 BGR mat -0068 gui.menu.file_import_lab_bgr_mat = uimenu(gui.menu.file_import_lab_bgr,... -0069 'Label','BGR mat','Tag','Lab','Callback',@onMenuImport); -0070 -0071 % 1.1.1.3 LIAG -0072 gui.menu.file_import_lab_liag = uimenu(gui.menu.file_import_lab,... -0073 'Label','LIAG'); -0074 % 1.1.1.3.1 LIAG -0075 gui.menu.file_import_lab_liag_single = uimenu(gui.menu.file_import_lab_liag,... -0076 'Label','LIAG single','Tag','Lab','Callback',@onMenuImport); -0077 % 1.1.1.3.2 LIAG -0078 gui.menu.file_import_lab_liag_project = uimenu(gui.menu.file_import_lab_liag,... -0079 'Label','LIAG from project','Tag','Lab','Callback',@onMenuImport); -0080 -0081 % 1.1.1.4 RWTH -0082 gui.menu.file_import_lab_rwth = uimenu(gui.menu.file_import_lab,... -0083 'Label','RWTH'); -0084 % 1.1.1.4.1 IBAC -0085 gui.menu.file_import_lab_ibac = uimenu(gui.menu.file_import_lab_rwth,... -0086 'Label','IBAC'); -0087 % 1.1.1.4.1.1 IBAC -0088 gui.menu.file_import_lab_ibac_pm5 = uimenu(gui.menu.file_import_lab_ibac,... -0089 'Label','PM5','Tag','Lab','Callback',@onMenuImport); -0090 % 1.1.1.4.1.2 IBAC -0091 gui.menu.file_import_lab_ibac_pm25 = uimenu(gui.menu.file_import_lab_ibac,... -0092 'Label','PM25','Tag','Lab','Callback',@onMenuImport); -0093 -0094 % 1.1.1.4.2 GGE -0095 gui.menu.file_import_lab_gge = uimenu(gui.menu.file_import_lab_rwth,... -0096 'Label','GGE'); -0097 % 1.1.1.4.2.1 GGE ascii -0098 gui.menu.file_import_lab_gge_ascii = uimenu(gui.menu.file_import_lab_gge,... -0099 'Label','GGE ascii','Tag','Lab','Callback',@onMenuImport); -0100 % 1.1.1.4.2.2 GGE field -0101 gui.menu.file_import_lab_gge_field = uimenu(gui.menu.file_import_lab_gge,... -0102 'Label','GGE field','Tag','Lab','Callback',@onMenuImport); -0103 % 1.1.1.4.2.3 GGE Dart -0104 gui.menu.file_import_lab_gge_dart = uimenu(gui.menu.file_import_lab_gge,... -0105 'Label','GGE Dart','Tag','Lab','Callback',@onMenuImport); -0106 -0107 % 1.1.1.5 OTHER -0108 gui.menu.file_import_lab_other = uimenu(gui.menu.file_import_lab,... -0109 'Label','OTHER'); -0110 % 1.1.1.5.1 CoreLab ascii -0111 gui.menu.file_import_lab_corelab = uimenu(gui.menu.file_import_lab_other,... -0112 'Label','CoreLab ascii','Tag','Lab','Callback',@onMenuImport); -0113 % 1.1.1.5.2 MOUSE -0114 gui.menu.file_import_lab_mouse = uimenu(gui.menu.file_import_lab_other,... -0115 'Label','MOUSE','Tag','Lab','Callback',@onMenuImport); -0116 -0117 % 1.1.2 Ascii -0118 gui.menu.file_import_ascii = uimenu(gui.menu.file_import,... -0119 'Label','Ascii'); -0120 % 1.1.2.1 T1 -0121 gui.menu.file_import_lab_ascii_T1 = uimenu(gui.menu.file_import_ascii,... -0122 'Label','T1','Tag','Ascii','Callback',@onMenuImport); -0123 % 1.1.2.2 T2 -0124 gui.menu.file_import_lab_ascii_T2 = uimenu(gui.menu.file_import_ascii,... -0125 'Label','T2','Tag','Ascii','Callback',@onMenuImport); -0126 -0127 % 1.1.3 Excel -0128 gui.menu.file_import_excel = uimenu(gui.menu.file_import,... -0129 'Label','Excel'); -0130 % 1.1.3.1 T1 -0131 gui.menu.file_import_lab_excel_T1 = uimenu(gui.menu.file_import_excel,... -0132 'Label','T1','Tag','Excel','Callback',@onMenuImport); -0133 % 1.1.3.2 T2 -0134 gui.menu.file_import_lab_excel_T2 = uimenu(gui.menu.file_import_excel,... -0135 'Label','T2','Tag','Excel','Callback',@onMenuImport); -0136 -0137 % 1.1.4 NUCLEUSinv -0138 gui.menu.file_import_nmrinv = uimenu(gui.menu.file_import,... -0139 'Label','NUCLEUSinv','Separator','on'); -0140 % 1.1.4.1 NUCLEUSinv session file -0141 gui.menu.file_import_nmrinv_file = uimenu(gui.menu.file_import_nmrinv,... -0142 'Label','Session','Tag','NUCLEUSinv','Callback',@onMenuImport); -0143 -0144 % 1.1.5 NUCLEUSmod -0145 gui.menu.file_import_nmrmod = uimenu(gui.menu.file_import,... -0146 'Label','NUCLEUSmod'); -0147 % 1.1.5.1 NUCLEUSmod from file -0148 gui.menu.file_import_nmrmod_file = uimenu(gui.menu.file_import_nmrmod,... -0149 'Label','File','Tag','NUCLEUSmod','Callback',@onMenuImport); -0150 % 1.1.5.2 NUCLEUSmod from GUI -0151 gui.menu.file_import_nmrmod_gui = uimenu(gui.menu.file_import_nmrmod,.... -0152 'Label','GUI','Tag','NUCLEUSmod','Callback',@onMenuImport); -0153 -0154 % 1.2 Export -0155 gui.menu.file_export = uimenu(gui.menu.file,... -0156 'Label','Export'); -0157 % 1.2.0 Last export -0158 lastexport = gui.myui.inidata.lastexport; -0159 gui.menu.file_export_lastexport = uimenu(gui.menu.file_export,... -0160 'Label',lastexport,'Callback',@onMenuExportData); -0161 % 1.2.1 Data -0162 gui.menu.file_export_data = uimenu(gui.menu.file_export,... -0163 'Label','Data'); -0164 % 1.2.1.1 GUI raw data mat-file -0165 gui.menu.file_export_data_GUImat = uimenu(gui.menu.file_export_data,... -0166 'Label','NUCLEUSinv (raw)','Callback',@onMenuExportData); -0167 % 1.2.1.2 GUI session mat-file -0168 gui.menu.file_export_data_GUImat = uimenu(gui.menu.file_export_data,... -0169 'Label','NUCLEUSinv (session)','Callback',@onMenuExportData); -0170 % 1.2.1.3 Inversion results single xls -0171 gui.menu.file_export_data_invstd_excel = uimenu(gui.menu.file_export_data,... -0172 'Label','EXCEL single (std)','Separator','on','Callback',@onMenuExportData); -0173 % 1.2.1.4 Inversion results single mat-file -0174 gui.menu.file_export_data_invstd_mat_single = uimenu(gui.menu.file_export_data,... -0175 'Label','MAT single (std)','Callback',@onMenuExportData); -0176 % 1.2.1.5 Inversion results all mat-file -0177 gui.menu.file_export_data_invstd_mat_all = uimenu(gui.menu.file_export_data,... -0178 'Label','MAT all (std)','Callback',@onMenuExportData); -0179 % 1.2.1.6 Joint Inversion results xls -0180 gui.menu.file_export_data_invjoint_excel = uimenu(gui.menu.file_export_data,... -0181 'Label','EXCEL all (joint)','Separator','on','Enable','off',... -0182 'Callback',@onMenuExportData); -0183 % 1.2.1.7 Joint Inversion results mat-file -0184 gui.menu.file_export_data_invjoint_mat = uimenu(gui.menu.file_export_data,... -0185 'Label','MAT all (joint)','Enable','off','Callback',@onMenuExportData); -0186 % 1.2.1.8 LIAG archive -0187 gui.menu.file_export_data_liag_archive = uimenu(gui.menu.file_export_data,... -0188 'Label','LIAG archive','Separator','on','Callback',@onMenuExportData); -0189 % 1.2.1.9 LIAG CSV T2 -0190 gui.menu.file_export_data_liag_csvT2 = uimenu(gui.menu.file_export_data,... -0191 'Label','LIAG CSV T2','Callback',@onMenuExportData); -0192 -0193 % 1.2.2 Graphics -0194 gui.menu.file_export_graphics = uimenu(gui.menu.file_export,... -0195 'Label','Graphics'); -0196 % 1.2.2.1 Layout -0197 gui.menu.file_export_graphics_layout = uimenu(gui.menu.file_export_graphics,... -0198 'Label','Layout'); -0199 % 1.2.2.1.1 Layout vertical -0200 gui.menu.file_export_graphics_layout_vert = uimenu(gui.menu.file_export_graphics_layout,... -0201 'Label','vert','Checked','on','Callback',@onMenuExportGraphics); -0202 % 1.2.2.1.2 Layout horizontal -0203 gui.menu.file_export_graphics_layout_horz = uimenu(gui.menu.file_export_graphics_layout,... -0204 'Label','horz','Callback',@onMenuExportGraphics); -0205 % 1.2.2.2 fig -0206 gui.menu.file_export_graphics_fig = uimenu(gui.menu.file_export_graphics,... -0207 'Label','FIG','Callback',@onMenuExportGraphics); -0208 % 1.2.2.3 png -0209 gui.menu.file_export_graphicspng = uimenu(gui.menu.file_export_graphics,... -0210 'Label','PNG','Callback',@onMenuExportGraphics); -0211 % 1.2.2.4 tiff -0212 gui.menu.file_export_graphicstiff = uimenu(gui.menu.file_export_graphics,... -0213 'Label','TIFF','Callback',@onMenuExportGraphics); -0214 % 1.2.2.5 eps -0215 gui.menu.file_export_graphicseps = uimenu(gui.menu.file_export_graphics,... -0216 'Label','EPS','Callback',@onMenuExportGraphics); -0217 -0218 % 1.3 Restart -0219 gui.menu.file_restart = uimenu(gui.menu.file,... -0220 'Label','Restart','Separator','on','Callback',@onMenuRestartQuit); -0221 -0222 % 1.4 Quit -0223 gui.menu.file_quit = uimenu(gui.menu.file,... -0224 'Label','Quit','Callback',@onMenuRestartQuit); -0225 -0226 %% 2. View -0227 gui.menu.view = uimenu(gui.figh,... -0228 'Label','View','Enable','off'); -0229 -0230 % 2.1 tooltips (on/off) -0231 gui.menu.view_tooltips = uimenu(gui.menu.view,... -0232 'Label','Tooltips','Checked','off','Callback',@onMenuView); -0233 switch gui.myui.inidata.tooltips -0234 case 'on' -0235 set(gui.menu.view_tooltips,'Checked','on'); -0236 case 'off' -0237 set(gui.menu.view_tooltips,'Checked','off'); -0238 end -0239 % 2.2 Figure Toolbar -0240 gui.menu.view_toolbar = uimenu(gui.menu.view,... -0241 'Label','Figure Toolbar','Callback',@onMenuView); -0242 -0243 % 2.3 INFO fields in plot panels (on/off) -0244 gui.menu.view_infofields = uimenu(gui.menu.view,... -0245 'Label','INFO fields','Separator','on','Callback',@onMenuView); -0246 -0247 % 2.4 inversion info on command line (on/off) -0248 gui.menu.view_invinfo = uimenu(gui.menu.view,... -0249 'Label','CLI Inv. Info','Callback',@onMenuView); -0250 switch gui.myui.inidata.invinfo -0251 case 'on' -0252 set(gui.menu.view_invinfo,'Checked','on'); -0253 case 'off' -0254 set(gui.menu.view_invinfo,'Checked','off'); -0255 end -0256 -0257 % 2.5 figures -0258 gui.menu.extra_graphics = uimenu(gui.menu.view,... -0259 'Label','Figures','Separator','on'); -0260 % 2.5.1 parameter file info -0261 gui.menu.extra_graphics_parinfo = uimenu(gui.menu.extra_graphics,... -0262 'Label','Parameter Info','Callback',@onMenuViewFigures); -0263 % 2.5.2 fit statistics -0264 gui.menu.extra_graphics_stats = uimenu(gui.menu.extra_graphics,... -0265 'Label','Fit statistics','Callback',@onMenuViewFigures); -0266 switch gui.myui.inidata.expertmode -0267 case 'on' -0268 % 2.5.3 amplitude over time -0269 gui.menu.extra_graphics_amp = uimenu(gui.menu.extra_graphics,... -0270 'Label','AMP-TLGM-SNR','Callback',@onMenuViewFigures); -0271 % 2.5.4 amplitude vs tlgm -0272 gui.menu.extra_graphics_amp2 = uimenu(gui.menu.extra_graphics,... -0273 'Label','AMP vs TLGM','Callback',@onMenuViewFigures); -0274 % 2.5.5 relaxation time distribution over time -0275 gui.menu.extra_graphics_rtd = uimenu(gui.menu.extra_graphics,... -0276 'Label','RTD','Callback',@onMenuViewFigures); -0277 case 'off' -0278 % 2.5.3 amplitude over time -0279 gui.menu.extra_graphics_amp = uimenu(gui.menu.extra_graphics,... -0280 'Label','AMP-TLGM-SNR','Enable','off','Callback',@onMenuViewFigures); -0281 % 2.5.4 amplitude vs tlgm -0282 gui.menu.extra_graphics_amp2 = uimenu(gui.menu.extra_graphics,... -0283 'Label','AMP vs TLGM','Enable','off','Callback',@onMenuViewFigures); -0284 % 2.5.5 relaxation time distribution over time -0285 gui.menu.extra_graphics_rtd = uimenu(gui.menu.extra_graphics,... -0286 'Label','RTD','Enable','off','Callback',@onMenuViewFigures); -0287 end -0288 -0289 % 2.6 PhaseView -0290 gui.menu.extra_phaseview = uimenu(gui.menu.view,... -0291 'Label','PhaseView GUI','Enable','off','Callback',@PhaseView); -0292 % 2.7 ConductVIEW -> hydraulic conductivity -0293 gui.menu.extra_conduct = uimenu(gui.menu.view,... -0294 'Label','ConductView GUI','Enable','off','Callback',@onMenuViewFigures); -0295 -0296 %% 3. Extras -0297 gui.menu.extra = uimenu(gui.figh,... -0298 'Label','Extra','Enable','off'); +0064 % 1.1.1.2.2 BGR mat +0065 gui.menu.file_import_lab_bgr_mat = uimenu(gui.menu.file_import_lab_bgr,... +0066 'Label','BGR mat','Tag','Lab','Callback',@onMenuImport); +0067 % 1.1.1.2.3 Mouse CPMG data, single data subfolders from CPMG +0068 gui.menu.file_import_lab_bgr_mouse_cpmg = uimenu(gui.menu.file_import_lab_bgr,... +0069 'Label','MouseCPMG','Tag','Lab','Callback',@onMenuImport); +0070 % 1.1.1.2.4 Mouse plus Lift, single data subfolder from t1test,... +0071 % ...cpmgfastautotest, or (old Prospa Versions) cpmgfastauto +0072 gui.menu.file_import_lab_bgr_mouse_liftsingle = uimenu(gui.menu.file_import_lab_bgr,... +0073 'Label','MouseLiftSingle','Tag','Lab','Callback',@onMenuImport); +0074 % 1.1.1.2.5 Mouse plus Lift, all data subfolders from t1test,... +0075 % cpmgfastautotest, or (old Prospa Versions) cpmgfastauto +0076 gui.menu.file_import_lab_bgr_mouse_liftall = uimenu(gui.menu.file_import_lab_bgr,... +0077 'Label','MouseLiftAll','Tag','Lab','Callback',@onMenuImport); +0078 % 1.1.1.2.6 Helios +0079 gui.menu.file_import_lab_bgr_helios = uimenu(gui.menu.file_import_lab_bgr,... +0080 'Label','Helios','Tag','Lab','Callback',@onMenuImport); +0081 +0082 % 1.1.1.3 LIAG +0083 gui.menu.file_import_lab_liag = uimenu(gui.menu.file_import_lab,... +0084 'Label','LIAG'); +0085 % 1.1.1.3.1 LIAG +0086 gui.menu.file_import_lab_liag_single = uimenu(gui.menu.file_import_lab_liag,... +0087 'Label','LIAG single','Tag','Lab','Callback',@onMenuImport); +0088 % 1.1.1.3.2 LIAG +0089 gui.menu.file_import_lab_liag_project = uimenu(gui.menu.file_import_lab_liag,... +0090 'Label','LIAG from project','Tag','Lab','Callback',@onMenuImport); +0091 +0092 % 1.1.1.4 RWTH +0093 gui.menu.file_import_lab_rwth = uimenu(gui.menu.file_import_lab,... +0094 'Label','RWTH'); +0095 % 1.1.1.4.1 IBAC +0096 gui.menu.file_import_lab_ibac = uimenu(gui.menu.file_import_lab_rwth,... +0097 'Label','IBAC'); +0098 % 1.1.1.4.1.1 IBAC +0099 gui.menu.file_import_lab_ibac_pm5 = uimenu(gui.menu.file_import_lab_ibac,... +0100 'Label','PM5','Tag','Lab','Callback',@onMenuImport); +0101 % 1.1.1.4.1.2 IBAC +0102 gui.menu.file_import_lab_ibac_pm25 = uimenu(gui.menu.file_import_lab_ibac,... +0103 'Label','PM25','Tag','Lab','Callback',@onMenuImport); +0104 +0105 % 1.1.1.4.2 GGE +0106 gui.menu.file_import_lab_gge = uimenu(gui.menu.file_import_lab_rwth,... +0107 'Label','GGE'); +0108 % 1.1.1.4.2.1 GGE ascii +0109 gui.menu.file_import_lab_gge_ascii = uimenu(gui.menu.file_import_lab_gge,... +0110 'Label','GGE ascii','Tag','Lab','Callback',@onMenuImport); +0111 % 1.1.1.4.2.2 GGE field +0112 gui.menu.file_import_lab_gge_field = uimenu(gui.menu.file_import_lab_gge,... +0113 'Label','GGE field','Tag','Lab','Callback',@onMenuImport); +0114 % 1.1.1.4.2.3 GGE Dart +0115 gui.menu.file_import_lab_gge_dart = uimenu(gui.menu.file_import_lab_gge,... +0116 'Label','GGE Dart','Tag','Lab','Callback',@onMenuImport); +0117 +0118 % 1.1.1.5 OTHER +0119 gui.menu.file_import_lab_other = uimenu(gui.menu.file_import_lab,... +0120 'Label','OTHER'); +0121 % 1.1.1.5.1 CoreLab ascii +0122 gui.menu.file_import_lab_corelab = uimenu(gui.menu.file_import_lab_other,... +0123 'Label','CoreLab ascii','Tag','Lab','Callback',@onMenuImport); +0124 % 1.1.1.5.2 MOUSE +0125 gui.menu.file_import_lab_mouse = uimenu(gui.menu.file_import_lab_other,... +0126 'Label','MOUSE','Tag','Lab','Callback',@onMenuImport); +0127 +0128 % 1.1.2 Ascii +0129 gui.menu.file_import_ascii = uimenu(gui.menu.file_import,... +0130 'Label','Ascii'); +0131 % 1.1.2.1 T1 +0132 gui.menu.file_import_lab_ascii_T1 = uimenu(gui.menu.file_import_ascii,... +0133 'Label','T1','Tag','Ascii','Callback',@onMenuImport); +0134 % 1.1.2.2 T2 +0135 gui.menu.file_import_lab_ascii_T2 = uimenu(gui.menu.file_import_ascii,... +0136 'Label','T2','Tag','Ascii','Callback',@onMenuImport); +0137 +0138 % 1.1.3 Excel +0139 gui.menu.file_import_excel = uimenu(gui.menu.file_import,... +0140 'Label','Excel'); +0141 % 1.1.3.1 T1 +0142 gui.menu.file_import_lab_excel_T1 = uimenu(gui.menu.file_import_excel,... +0143 'Label','T1','Tag','Excel','Callback',@onMenuImport); +0144 % 1.1.3.2 T2 +0145 gui.menu.file_import_lab_excel_T2 = uimenu(gui.menu.file_import_excel,... +0146 'Label','T2','Tag','Excel','Callback',@onMenuImport); +0147 +0148 % 1.1.4 NUCLEUSinv +0149 gui.menu.file_import_nmrinv = uimenu(gui.menu.file_import,... +0150 'Label','NUCLEUSinv','Separator','on'); +0151 % 1.1.4.1 NUCLEUSinv session file +0152 gui.menu.file_import_nmrinv_file = uimenu(gui.menu.file_import_nmrinv,... +0153 'Label','Session','Tag','NUCLEUSinv','Callback',@onMenuImport); +0154 +0155 % 1.1.5 NUCLEUSmod +0156 gui.menu.file_import_nmrmod = uimenu(gui.menu.file_import,... +0157 'Label','NUCLEUSmod'); +0158 % 1.1.5.1 NUCLEUSmod from file +0159 gui.menu.file_import_nmrmod_file = uimenu(gui.menu.file_import_nmrmod,... +0160 'Label','File','Tag','NUCLEUSmod','Callback',@onMenuImport); +0161 % 1.1.5.2 NUCLEUSmod from GUI +0162 gui.menu.file_import_nmrmod_gui = uimenu(gui.menu.file_import_nmrmod,.... +0163 'Label','GUI','Tag','NUCLEUSmod','Callback',@onMenuImport); +0164 +0165 % 1.2 Export +0166 gui.menu.file_export = uimenu(gui.menu.file,... +0167 'Label','Export'); +0168 % 1.2.0 Last export +0169 lastexport = gui.myui.inidata.lastexport; +0170 gui.menu.file_export_lastexport = uimenu(gui.menu.file_export,... +0171 'Label',lastexport,'Callback',@onMenuExportData); +0172 % 1.2.1 Data +0173 gui.menu.file_export_data = uimenu(gui.menu.file_export,... +0174 'Label','Data'); +0175 % 1.2.1.1 GUI raw data mat-file +0176 gui.menu.file_export_data_GUImat = uimenu(gui.menu.file_export_data,... +0177 'Label','NUCLEUSinv (raw)','Callback',@onMenuExportData); +0178 % 1.2.1.2 GUI session mat-file +0179 gui.menu.file_export_data_GUImat = uimenu(gui.menu.file_export_data,... +0180 'Label','NUCLEUSinv (session)','Callback',@onMenuExportData); +0181 % 1.2.1.3 Inversion results single xls +0182 gui.menu.file_export_data_invstd_excel = uimenu(gui.menu.file_export_data,... +0183 'Label','EXCEL single (std)','Separator','on','Callback',@onMenuExportData); +0184 % 1.2.1.4 Inversion results single mat-file +0185 gui.menu.file_export_data_invstd_mat_single = uimenu(gui.menu.file_export_data,... +0186 'Label','MAT single (std)','Callback',@onMenuExportData); +0187 % 1.2.1.5 Inversion results all mat-file +0188 gui.menu.file_export_data_invstd_mat_all = uimenu(gui.menu.file_export_data,... +0189 'Label','MAT all (std)','Callback',@onMenuExportData); +0190 % 1.2.1.6 Joint Inversion results xls +0191 gui.menu.file_export_data_invjoint_excel = uimenu(gui.menu.file_export_data,... +0192 'Label','EXCEL all (joint)','Separator','on','Enable','off',... +0193 'Callback',@onMenuExportData); +0194 % 1.2.1.7 Joint Inversion results mat-file +0195 gui.menu.file_export_data_invjoint_mat = uimenu(gui.menu.file_export_data,... +0196 'Label','MAT all (joint)','Enable','off','Callback',@onMenuExportData); +0197 % 1.2.1.8 LIAG archive +0198 gui.menu.file_export_data_liag_archive = uimenu(gui.menu.file_export_data,... +0199 'Label','LIAG archive','Separator','on','Callback',@onMenuExportData); +0200 % 1.2.1.9 LIAG CSV T2 +0201 gui.menu.file_export_data_liag_csvT2 = uimenu(gui.menu.file_export_data,... +0202 'Label','LIAG CSV T2','Callback',@onMenuExportData); +0203 +0204 % 1.2.2 Graphics +0205 gui.menu.file_export_graphics = uimenu(gui.menu.file_export,... +0206 'Label','Graphics'); +0207 % 1.2.2.1 Layout +0208 gui.menu.file_export_graphics_layout = uimenu(gui.menu.file_export_graphics,... +0209 'Label','Layout'); +0210 % 1.2.2.1.1 Layout vertical +0211 gui.menu.file_export_graphics_layout_vert = uimenu(gui.menu.file_export_graphics_layout,... +0212 'Label','vert','Checked','on','Callback',@onMenuExportGraphics); +0213 % 1.2.2.1.2 Layout horizontal +0214 gui.menu.file_export_graphics_layout_horz = uimenu(gui.menu.file_export_graphics_layout,... +0215 'Label','horz','Callback',@onMenuExportGraphics); +0216 % 1.2.2.2 fig +0217 gui.menu.file_export_graphics_fig = uimenu(gui.menu.file_export_graphics,... +0218 'Label','FIG','Callback',@onMenuExportGraphics); +0219 % 1.2.2.3 png +0220 gui.menu.file_export_graphicspng = uimenu(gui.menu.file_export_graphics,... +0221 'Label','PNG','Callback',@onMenuExportGraphics); +0222 % 1.2.2.4 tiff +0223 gui.menu.file_export_graphicstiff = uimenu(gui.menu.file_export_graphics,... +0224 'Label','TIFF','Callback',@onMenuExportGraphics); +0225 % 1.2.2.5 eps +0226 gui.menu.file_export_graphicseps = uimenu(gui.menu.file_export_graphics,... +0227 'Label','EPS','Callback',@onMenuExportGraphics); +0228 +0229 % 1.3 Restart +0230 gui.menu.file_restart = uimenu(gui.menu.file,... +0231 'Label','Restart','Separator','on','Callback',@onMenuRestartQuit); +0232 +0233 % 1.4 Quit +0234 gui.menu.file_quit = uimenu(gui.menu.file,... +0235 'Label','Quit','Callback',@onMenuRestartQuit); +0236 +0237 %% 2. View +0238 gui.menu.view = uimenu(gui.figh,... +0239 'Label','View','Enable','off'); +0240 +0241 % 2.1 tooltips (on/off) +0242 gui.menu.view_tooltips = uimenu(gui.menu.view,... +0243 'Label','Tooltips','Checked','off','Callback',@onMenuView); +0244 switch gui.myui.inidata.tooltips +0245 case 'on' +0246 set(gui.menu.view_tooltips,'Checked','on'); +0247 case 'off' +0248 set(gui.menu.view_tooltips,'Checked','off'); +0249 end +0250 % 2.2 Figure Toolbar +0251 gui.menu.view_toolbar = uimenu(gui.menu.view,... +0252 'Label','Figure Toolbar','Callback',@onMenuView); +0253 +0254 % 2.3 INFO fields in plot panels (on/off) +0255 gui.menu.view_infofields = uimenu(gui.menu.view,... +0256 'Label','INFO fields','Separator','on','Callback',@onMenuView); +0257 +0258 % 2.4 inversion info on command line (on/off) +0259 gui.menu.view_invinfo = uimenu(gui.menu.view,... +0260 'Label','CLI Inv. Info','Callback',@onMenuView); +0261 switch gui.myui.inidata.invinfo +0262 case 'on' +0263 set(gui.menu.view_invinfo,'Checked','on'); +0264 case 'off' +0265 set(gui.menu.view_invinfo,'Checked','off'); +0266 end +0267 +0268 % 2.5 figures +0269 gui.menu.extra_graphics = uimenu(gui.menu.view,... +0270 'Label','Figures','Separator','on'); +0271 % 2.5.1 parameter file info +0272 gui.menu.extra_graphics_parinfo = uimenu(gui.menu.extra_graphics,... +0273 'Label','Parameter Info','Callback',@onMenuViewFigures); +0274 % 2.5.2 fit statistics +0275 gui.menu.extra_graphics_stats = uimenu(gui.menu.extra_graphics,... +0276 'Label','Fit statistics','Callback',@onMenuViewFigures); +0277 switch gui.myui.inidata.expertmode +0278 case 'on' +0279 % 2.5.3 amplitude over time +0280 gui.menu.extra_graphics_amp = uimenu(gui.menu.extra_graphics,... +0281 'Label','AMP-TLGM-SNR','Callback',@onMenuViewFigures); +0282 % 2.5.4 amplitude vs tlgm +0283 gui.menu.extra_graphics_amp2 = uimenu(gui.menu.extra_graphics,... +0284 'Label','AMP vs TLGM','Callback',@onMenuViewFigures); +0285 % 2.5.5 relaxation time distribution over time +0286 gui.menu.extra_graphics_rtd = uimenu(gui.menu.extra_graphics,... +0287 'Label','RTD','Callback',@onMenuViewFigures); +0288 case 'off' +0289 % 2.5.3 amplitude over time +0290 gui.menu.extra_graphics_amp = uimenu(gui.menu.extra_graphics,... +0291 'Label','AMP-TLGM-SNR','Enable','off','Callback',@onMenuViewFigures); +0292 % 2.5.4 amplitude vs tlgm +0293 gui.menu.extra_graphics_amp2 = uimenu(gui.menu.extra_graphics,... +0294 'Label','AMP vs TLGM','Enable','off','Callback',@onMenuViewFigures); +0295 % 2.5.5 relaxation time distribution over time +0296 gui.menu.extra_graphics_rtd = uimenu(gui.menu.extra_graphics,... +0297 'Label','RTD','Enable','off','Callback',@onMenuViewFigures); +0298 end 0299 -0300 % 3.1 expert mode (on/off) -0301 gui.menu.extra_expert = uimenu(gui.menu.extra,... -0302 'Label','Expert Mode','Callback',@onMenuExpert); -0303 switch gui.myui.inidata.expertmode -0304 case 'on' -0305 set(gui.menu.extra_expert,'Checked','on'); -0306 case 'off' -0307 set(gui.menu.extra_expert,'Checked','of'); -0308 end -0309 -0310 % 3.2 optimization toolbox (on/off) -0311 switch gui.myui.inidata.expertmode -0312 case 'on' -0313 switch data.info.has_optim -0314 case 'on' -0315 gui.menu.extra_solver = uimenu(gui.menu.extra,... -0316 'Label','LSQ Solver','Enable','on'); -0317 case 'off' -0318 gui.menu.extra_solver = uimenu(gui.menu.extra,... -0319 'Label','LSQ Solver','Enable','off'); -0320 end -0321 case 'off' -0322 gui.menu.extra_solver = uimenu(gui.menu.extra,... -0323 'Label','LSQ Solver','Enable','off'); -0324 end -0325 gui.menu.extra_solver_lsqlin = uimenu(gui.menu.extra_solver,... -0326 'Label','LSQLIN (Optim. TB)','Callback',@onMenuSolver); -0327 gui.menu.extra_solver_lsqnonneg = uimenu(gui.menu.extra_solver,... -0328 'Label','LSQNONNEG (default)','Checked','on','Callback',@onMenuSolver); -0329 -0330 % 3.3 joint inversion (on/off) -0331 gui.menu.extra_joint = uimenu(gui.menu.extra,... -0332 'Label','Joint Inversion','Checked','off','Separator','on',... -0333 'Callback',@onMenuJointInversion); -0334 switch gui.myui.inidata.expertmode -0335 case 'on' -0336 set(gui.menu.extra_joint,'Enable','on'); -0337 case 'off' -0338 set(gui.menu.extra_joint,'Enable','off'); -0339 end +0300 % 2.6 PhaseView +0301 gui.menu.extra_phaseview = uimenu(gui.menu.view,... +0302 'Label','PhaseView GUI','Enable','off','Callback',@PhaseView); +0303 % 2.7 ConductVIEW -> hydraulic conductivity +0304 gui.menu.extra_conduct = uimenu(gui.menu.view,... +0305 'Label','ConductView GUI','Enable','off','Callback',@onMenuViewFigures); +0306 +0307 %% 3. Extras +0308 gui.menu.extra = uimenu(gui.figh,... +0309 'Label','Extra','Enable','off'); +0310 +0311 % 3.1 expert mode (on/off) +0312 gui.menu.extra_expert = uimenu(gui.menu.extra,... +0313 'Label','Expert Mode','Callback',@onMenuExpert); +0314 switch gui.myui.inidata.expertmode +0315 case 'on' +0316 set(gui.menu.extra_expert,'Checked','on'); +0317 case 'off' +0318 set(gui.menu.extra_expert,'Checked','of'); +0319 end +0320 +0321 % 3.2 optimization toolbox (on/off) +0322 switch gui.myui.inidata.expertmode +0323 case 'on' +0324 switch data.info.has_optim +0325 case 'on' +0326 gui.menu.extra_solver = uimenu(gui.menu.extra,... +0327 'Label','LSQ Solver','Enable','on'); +0328 case 'off' +0329 gui.menu.extra_solver = uimenu(gui.menu.extra,... +0330 'Label','LSQ Solver','Enable','off'); +0331 end +0332 case 'off' +0333 gui.menu.extra_solver = uimenu(gui.menu.extra,... +0334 'Label','LSQ Solver','Enable','off'); +0335 end +0336 gui.menu.extra_solver_lsqlin = uimenu(gui.menu.extra_solver,... +0337 'Label','LSQLIN (Optim. TB)','Callback',@onMenuSolver); +0338 gui.menu.extra_solver_lsqnonneg = uimenu(gui.menu.extra_solver,... +0339 'Label','LSQNONNEG (default)','Checked','on','Callback',@onMenuSolver); 0340 -0341 % 3.4 set inversion bounds for surface relaxivity rho -0342 gui.menu.extra_joint_rhobounds = uimenu(gui.menu.extra,... -0343 'Label','Surface relaxivity bounds','Enable','off',... -0344 'Callback',@onMenuExtraRhoBounds); -0345 -0346 -0347 %% 4. Color theme -0348 gui.menu.color_theme = uimenu(gui.figh,... -0349 'Label','Color Theme','Enable','off'); -0350 -0351 % 4.1 default color theme -0352 gui.menu.color_theme_standard = uimenu(gui.menu.color_theme,... -0353 'Label','standard','Callback',@onMenuExtraColor); -0354 % 4.2 basic color theme -0355 gui.menu.color_theme_basic = uimenu(gui.menu.color_theme,... -0356 'Label','basic','Callback',@onMenuExtraColor); -0357 % 4.3 dark color theme -0358 gui.menu.color_theme_dark = uimenu(gui.menu.color_theme,... -0359 'Label','dark','Callback',@onMenuExtraColor); -0360 % 4.4 black color theme -0361 gui.menu.color_theme_black = uimenu(gui.menu.color_theme,... -0362 'Label','black','Callback',@onMenuExtraColor); -0363 switch gui.myui.inidata.colortheme -0364 case 'standard' -0365 set(gui.menu.color_theme_standard,'Checked','on'); -0366 case 'basic' -0367 set(gui.menu.color_theme_basic,'Checked','on'); -0368 case 'dark' -0369 set(gui.menu.color_theme_dark,'Checked','on'); -0370 case 'black' -0371 set(gui.menu.color_theme_black,'Checked','on'); -0372 end -0373 -0374 %% 5. Help -0375 gui.menu.help = uimenu(gui.figh,... -0376 'Label','Help','Enable','off'); -0377 -0378 % 5.1 About -0379 gui.menu.help_about = uimenu(gui.menu.help,... -0380 'Label','About','Callback',@onMenuHelp); -0381 -0382 return -0383 -0384 %------------- END OF CODE -------------- -0385 -0386 %% License: -0387 % MIT License -0388 % -0389 % Copyright (c) 2018 Thomas Hiller -0390 % -0391 % Permission is hereby granted, free of charge, to any person obtaining a copy -0392 % of this software and associated documentation files (the "Software"), to deal -0393 % in the Software without restriction, including without limitation the rights -0394 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0395 % copies of the Software, and to permit persons to whom the Software is -0396 % furnished to do so, subject to the following conditions: -0397 % -0398 % The above copyright notice and this permission notice shall be included in all -0399 % copies or substantial portions of the Software. -0400 % -0401 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0402 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0403 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0404 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0405 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0406 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0407 % SOFTWARE. +0341 % 3.3 joint inversion (on/off) +0342 gui.menu.extra_joint = uimenu(gui.menu.extra,... +0343 'Label','Joint Inversion','Checked','off','Separator','on',... +0344 'Callback',@onMenuJointInversion); +0345 switch gui.myui.inidata.expertmode +0346 case 'on' +0347 set(gui.menu.extra_joint,'Enable','on'); +0348 case 'off' +0349 set(gui.menu.extra_joint,'Enable','off'); +0350 end +0351 +0352 % 3.4 set inversion bounds for surface relaxivity rho +0353 gui.menu.extra_joint_rhobounds = uimenu(gui.menu.extra,... +0354 'Label','Surface relaxivity bounds','Enable','off',... +0355 'Callback',@onMenuExtraRhoBounds); +0356 +0357 +0358 %% 4. Color theme +0359 gui.menu.color_theme = uimenu(gui.figh,... +0360 'Label','Color Theme','Enable','off'); +0361 +0362 % 4.1 default color theme +0363 gui.menu.color_theme_standard = uimenu(gui.menu.color_theme,... +0364 'Label','standard','Callback',@onMenuExtraColor); +0365 % 4.2 basic color theme +0366 gui.menu.color_theme_basic = uimenu(gui.menu.color_theme,... +0367 'Label','basic','Callback',@onMenuExtraColor); +0368 % 4.3 dark color theme +0369 gui.menu.color_theme_dark = uimenu(gui.menu.color_theme,... +0370 'Label','dark','Callback',@onMenuExtraColor); +0371 % 4.4 black color theme +0372 gui.menu.color_theme_black = uimenu(gui.menu.color_theme,... +0373 'Label','black','Callback',@onMenuExtraColor); +0374 switch gui.myui.inidata.colortheme +0375 case 'standard' +0376 set(gui.menu.color_theme_standard,'Checked','on'); +0377 case 'basic' +0378 set(gui.menu.color_theme_basic,'Checked','on'); +0379 case 'dark' +0380 set(gui.menu.color_theme_dark,'Checked','on'); +0381 case 'black' +0382 set(gui.menu.color_theme_black,'Checked','on'); +0383 end +0384 +0385 %% 5. Help +0386 gui.menu.help = uimenu(gui.figh,... +0387 'Label','Help','Enable','off'); +0388 +0389 % 5.1 About +0390 gui.menu.help_about = uimenu(gui.menu.help,... +0391 'Label','About','Callback',@onMenuHelp); +0392 +0393 return +0394 +0395 %------------- END OF CODE -------------- +0396 +0397 %% License: +0398 % MIT License +0399 % +0400 % Copyright (c) 2018 Thomas Hiller +0401 % +0402 % Permission is hereby granted, free of charge, to any person obtaining a copy +0403 % of this software and associated documentation files (the "Software"), to deal +0404 % in the Software without restriction, including without limitation the rights +0405 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0406 % copies of the Software, and to permit persons to whom the Software is +0407 % furnished to do so, subject to the following conditions: +0408 % +0409 % The above copyright notice and this permission notice shall be included in all +0410 % copies or substantial portions of the Software. +0411 % +0412 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0413 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0414 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0415 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0416 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0417 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0418 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelData.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelData.html index e762c10..26df343 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelData.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelData.html @@ -52,8 +52,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -96,8 +96,8 @@

    SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- @@ -149,7 +149,7 @@

    SOURCE CODE ^... 0079 'Label','save','Tag','single','Callback',@onContextSignalList); 0080 uimenu(gui.cm_handles.data_list_single,... -0081 'Label','remove','Tag','single','Separator','on',... +0081 'Label','\remove','Tag','single','Separator','on',... 0082 'Callback',@onContextSignalList); 0083 uimenu(gui.cm_handles.data_list_single,... 0084 'Label','use as calib.','Tag','single','Separator','on',... diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInfo.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInfo.html index f2b8b12..f456451 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInfo.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInfo.html @@ -50,8 +50,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -92,8 +92,8 @@

    SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInversionJoint.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInversionJoint.html index 4209fc2..76fb6d7 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInversionJoint.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInversionJoint.html @@ -53,8 +53,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -98,8 +98,8 @@

    SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInversionStd.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInversionStd.html index 195dd4b..4789d6b 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInversionStd.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelInversionStd.html @@ -53,8 +53,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -98,8 +98,8 @@

    SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- @@ -134,10 +134,10 @@

    SOURCE CODE ^switch data.info.ExpertMode 0063 case 'on' 0064 tstr = ' '; -0065 istring = {'Mono exp.','Several free exp. (2-5)','Multi exp. (LSQ)','Multi exp. (LU decomp.)'}; +0065 istring = {'Mono exp.','N free exp. (2-5)','Multi exp. (LSQ)','Multi exp. (LU decomp.)','Multi modal'}; 0066 case 'off' 0067 tstr = ' '; -0068 istring = {'Mono exp.','Several free exp. (2-5)','Multi exp. (LSQ)'}; +0068 istring = {'Mono exp.','N free exp. (2-5)','Multi exp. (LSQ)'}; 0069 end 0070 gui.popup_handles.invstd_InvType = uicontrol('Parent',gui.panels.invstd.HBox1,... 0071 'Style','popup','String',istring,'FontSize',myui.fontsize,'Enable','off','Value',3,... diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelPetro.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelPetro.html index 486b24d..4e6181f 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelPetro.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelPetro.html @@ -53,8 +53,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -98,8 +98,8 @@

    SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- @@ -108,156 +108,185 @@

    SOURCE CODE ^'Parent',gui.panels.petro.main,... 0037 'Spacing',3,'Padding',3); 0038 -0039 % Tbulk, surface relaxivity rho and geometry factor a +0039 % Tbulk and Tdiff 0040 gui.panels.petro.HBox1 = uix.HBox('Parent',gui.panels.petro.VBox,... 0041 'Spacing',3); -0042 % CBW and BVI +0042 % surface relaxivity rho and geometry factor a 0043 gui.panels.petro.HBox2 = uix.HBox('Parent',gui.panels.petro.VBox,... 0044 'Spacing',3); -0045 % calibration switch calib volume +0045 % CBW and BVI 0046 gui.panels.petro.HBox3 = uix.HBox('Parent',gui.panels.petro.VBox,... 0047 'Spacing',3); -0048 % sample volume, sample porosity +0048 % calibration switch calib volume 0049 gui.panels.petro.HBox4 = uix.HBox('Parent',gui.panels.petro.VBox,... 0050 'Spacing',3); -0051 -0052 %% Tbulk, surface relaxivity rho and geometry factor a -0053 gui.text_handles.petro_Tbulk = uicontrol('Parent',gui.panels.petro.HBox1,... -0054 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0055 'String',['Tbulk [s] | ',char(hex2dec('03C1')),' [µm/s] | geom']); -0056 tstr = '<HTML>Set the T bulk [s] value.<br>'; -0057 gui.edit_handles.invstd_Tbulk = uicontrol('Parent',gui.panels.petro.HBox1,... -0058 'Style','edit','String',num2str(data.invstd.Tbulk),'FontSize',myui.fontsize,... -0059 'UserData',struct('Tooltipstr',tstr,'defaults',[data.invstd.Tbulk 1 1]),... -0060 'Tag','invstd_Tbulk','Enable','off','Callback',@onEditValue); -0061 tstr = ['<HTML>Surface relaxivity rho in [m/s].<br><br>',... -0062 '1/T = rho*S/V = rho*a/R.<br><br>',... -0063 '<u>Default value:</u><br>',... -0064 '<b>2.5e-5</b><br>']; -0065 gui.edit_handles.param_rho = uicontrol('Parent',gui.panels.petro.HBox1,... -0066 'Style','edit','String',num2str(data.param.rho),'FontSize',myui.fontsize,... -0067 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.rho 1 1]),... -0068 'Tag','param_rho','Enable','off','Callback',@onEditValue); -0069 tstr = ['<HTML>Give the geometry factor "a" to convert relaxation times to pore radii<br><br>',... -0070 '1/T = rho*S/V = rho*a/R.<br><br>',... -0071 '<u>Possible options:</u><br>',... -0072 '<b>2</b> capillaries with circular cross section<br>',... -0073 '<b>3</b> spheres<br><br>',... -0074 'For <b>right angular</b> and <b>polygonal</b> cross-sections "a" converts to the area-equivalent cylinder radius e.g.:<br>',... -0075 '<b>2.57</b> capillaries with 60°-60°-60° equilateral cross section<br>',... -0076 '<b>2.72-12.18</b> capillaries with 90°-a°-(90-a)° right angular cross section<br>',... -0077 'e.g. <b>2.72</b> is 90°-45°-45° | <b>2.87</b> is 90°-60°-30° | <b>5.64</b> is 90°-85°-5°<br><br>',... -0078 '<u>Default value:</u><br>',... -0079 '<b>2</b><br>']; -0080 gui.edit_handles.param_geom = uicontrol('Parent',gui.panels.petro.HBox1,... -0081 'Style','edit','String',num2str(data.param.a),'FontSize',myui.fontsize,... -0082 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.a 1 1]),... -0083 'Tag','param_a','Enable','off','Callback',@onEditValue); -0084 set(gui.panels.petro.HBox1,'Widths',[200 -1 -1 -1]); -0085 -0086 %% CBW and BVI -0087 gui.text_handles.petro_CBW = uicontrol('Parent',gui.panels.petro.HBox2,... -0088 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0089 'String','CBW [ms] | BVI [ms]'); -0090 tstr = ['<HTML>Give cut-off time between CBW and BVI in [ms].',... -0091 ' This value depends on lithology.<br><br>',... -0092 '<u>Abbreviations:</u><br>',... -0093 '<b>CBW</b> clay bound water<br>',... -0094 '<b>BVI</b> bulk volume irreducible (irreducible water)<br>',... -0095 '<b>BVM</b> bulk volume movable (free water)<br><br>',... -0096 'The value is usually <b>3 [ms]</b><br><br>',... -0097 '<u>Default value:</u><br>',... -0098 '<b>3</b><br>']; -0099 gui.edit_handles.param_CBW = uicontrol('Parent',gui.panels.petro.HBox2,... -0100 'Style','edit','String',num2str(data.param.CBWcutoff),'FontSize',myui.fontsize,... -0101 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.CBWcutoff 1 1]),... -0102 'Tag','param_CBWcutoff','Enable','off','Callback',@onEditValue); -0103 tstr = ['<HTML>Give cut off time between BVI and BVM in [ms].',... -0104 ' This value depends on lithology.<br><br>',... -0105 '<u>Abbreviations:</u><br>',... -0106 '<b>CBW</b> clay bound water<br>',... -0107 '<b>BVI</b> bulk volume irreducible (irreducible water)<br>',... -0108 '<b>BVM</b> bulk volume movable (free water)<br><br>',... -0109 'For Sandstones the value is usually <b>33 [ms]</b><br>',... -0110 'For Carbonates the value is usually <b>92 [ms]</b><br><br>',... -0111 '<u>Default value:</u><br>',... -0112 '<b>33</b><br>']; -0113 gui.edit_handles.param_BVI = uicontrol('Parent',gui.panels.petro.HBox2,... -0114 'Style','edit','String',num2str(data.param.BVIcutoff),'FontSize',myui.fontsize,... -0115 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.BVIcutoff 1 1]),... -0116 'Tag','param_BVIcutoff','Enable','off','Callback',@onEditValue); -0117 set(gui.panels.petro.HBox2,'Widths',[200 -1 -1]); -0118 -0119 %% calibration switch, calibration volume -0120 gui.text_handles.petro_calibVol = uicontrol('Parent',gui.panels.petro.HBox3,... -0121 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0122 'String','calib. Vol. | calib. Amp.'); -0123 tstr = ''; -0124 gui.edit_handles.param_calibVol = uicontrol('Parent',gui.panels.petro.HBox3,... -0125 'Style','edit','String',num2str(data.param.calibVol),'FontSize',myui.fontsize,... -0126 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.calibVol 1 1]),... -0127 'Tag','param_calibVol','Enable','off','Callback',@onEditValue); -0128 tstr = ''; -0129 gui.edit_handles.param_calibAmp = uicontrol('Parent',gui.panels.petro.HBox3,... -0130 'Style','edit','String',num2str(data.param.calibAmp),'FontSize',myui.fontsize,... -0131 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.calibAmp 1 1]),... -0132 'Tag','param_calibAmp','Enable','off','Callback',@onEditValue); -0133 set(gui.panels.petro.HBox3,'Widths',[200 -1 -1]); -0134 -0135 %% sample volume, porosity -0136 gui.text_handles.petro_sampVol = uicontrol('Parent',gui.panels.petro.HBox4,... -0137 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0138 'String','sample Vol. | porosity'); -0139 tstr = ' '; -0140 gui.edit_handles.param_sampVol = uicontrol('Parent',gui.panels.petro.HBox4,... -0141 'Style','edit','String',num2str(data.param.sampVol),'FontSize',myui.fontsize,... -0142 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.sampVol 1 1]),... -0143 'Tag','param_sampVol','Enable','off','Callback',@onEditValue); -0144 tstr = ['<HTML>Set porosity (between 0 and 1)<br><br>',... -0145 '<u>Default value:</u><br>',... -0146 '<b>1</b><br><br>']; -0147 gui.edit_handles.invstd_porosity = uicontrol('Parent',gui.panels.petro.HBox4,... -0148 'Style','edit','String',num2str(data.invstd.porosity),'FontSize',myui.fontsize,... -0149 'UserData',struct('Tooltipstr',tstr,'defaults',[data.invstd.porosity 1 1]),... -0150 'Tag','invstd_porosity','Enable','off','Callback',@onEditValue); -0151 set(gui.panels.petro.HBox4,'Widths',[200 -1 -1]); -0152 -0153 %% Java Hack to adjust vertical alignment of text fields -0154 jh = findjobj(gui.text_handles.petro_Tbulk); -0155 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0156 jh = findjobj(gui.text_handles.petro_CBW); -0157 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0158 jh = findjobj(gui.text_handles.petro_calibVol); -0159 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0160 jh = findjobj(gui.text_handles.petro_sampVol); -0161 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0162 -0163 return -0164 -0165 %------------- END OF CODE -------------- -0166 -0167 %% License: -0168 % MIT License -0169 % -0170 % Copyright (c) 2018 Thomas Hiller -0171 % -0172 % Permission is hereby granted, free of charge, to any person obtaining a copy -0173 % of this software and associated documentation files (the "Software"), to deal -0174 % in the Software without restriction, including without limitation the rights -0175 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0176 % copies of the Software, and to permit persons to whom the Software is -0177 % furnished to do so, subject to the following conditions: -0178 % -0179 % The above copyright notice and this permission notice shall be included in all -0180 % copies or substantial portions of the Software. -0181 % -0182 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0183 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0184 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0185 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0186 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0187 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0188 % SOFTWARE. +0051 % sample volume, sample porosity +0052 gui.panels.petro.HBox5 = uix.HBox('Parent',gui.panels.petro.VBox,... +0053 'Spacing',3); +0054 +0055 %% Tbulk and Tdiff +0056 gui.text_handles.petro_Tbulk = uicontrol('Parent',gui.panels.petro.HBox1,... +0057 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... +0058 'String','Tbulk [s] | Tdiff [s]'); +0059 tstr = ['<HTML>Bulk relaxation time in [s].<br><br>',... +0060 '1/T = 1/Ts + 1/<b>Tb</b> + 1/Td<br><br>',... +0061 '<u>Default value:</u><br>',... +0062 '<b>1e6</b> (so that 1/<b>Tb</b> is ignored)<br>']; +0063 gui.edit_handles.invstd_Tbulk = uicontrol('Parent',gui.panels.petro.HBox1,... +0064 'Style','edit','String',num2str(data.invstd.Tbulk),'FontSize',myui.fontsize,... +0065 'UserData',struct('Tooltipstr',tstr,'defaults',[data.invstd.Tbulk 1 1]),... +0066 'Tag','invstd_Tbulk','Enable','off','Callback',@onEditValue); +0067 tstr = ['<HTML>Diffusion relaxation time in [s].<br><br>',... +0068 '1/T = 1/Ts + 1/Tb + 1/<b>Td</b><br><br>',... +0069 '<b>Td</b> can be caluclated by<br><br>',... +0070 '<b>Td</b> = 12 / (D*(',char(hex2dec('03B3')),'*G*TE)<sup>2</sup> )<br><br>',... +0071 'with<br><br>',... +0072 'D = diffusion coefficent of water<br>',... +0073 char(hex2dec('03B3')),' = gyromagnetic ratio of hydrogen<br>',... +0074 'G = magnetic gradient<br>',... +0075 'TE = echo time<br><br>',... +0076 '<u>Default value:</u><br>',... +0077 '<b>1e6</b> (so that 1/<b>Td</b> is ignored)<br>']; +0078 gui.edit_handles.invstd_Tdiff = uicontrol('Parent',gui.panels.petro.HBox1,... +0079 'Style','edit','String',num2str(data.invstd.Tdiff),'FontSize',myui.fontsize,... +0080 'UserData',struct('Tooltipstr',tstr,'defaults',[data.invstd.Tdiff 1 1]),... +0081 'Tag','invstd_Tdiff','Enable','off','Callback',@onEditValue); +0082 set(gui.panels.petro.HBox1,'Widths',[200 -1 -1]); +0083 +0084 %% surface relaxivity rho and geometry factor a +0085 gui.text_handles.petro_rho = uicontrol('Parent',gui.panels.petro.HBox2,... +0086 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... +0087 'String',[char(hex2dec('03C1')),' [µm/s] | geom ']); +0088 tstr = ['<HTML>Surface relaxivity in [µm/s].<br><br>',... +0089 '1/Ts = <b>rho</b>*S/V = <b>rho</b>*a/R.<br><br>',... +0090 '<u>Default value:</u><br>',... +0091 '<b>10</b><br>']; +0092 gui.edit_handles.param_rho = uicontrol('Parent',gui.panels.petro.HBox2,... +0093 'Style','edit','String',num2str(data.param.rho),'FontSize',myui.fontsize,... +0094 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.rho 1 1]),... +0095 'Tag','param_rho','Enable','off','Callback',@onEditValue); +0096 tstr = ['<HTML>Geometry factor "a" to convert relaxation times to pore radii.<br><br>',... +0097 '1/Ts = rho*S/V = rho*<b>a</b>/R.<br><br>',... +0098 '<u>Possible options:</u><br>',... +0099 '<b>2</b> capillaries with circular cross section<br>',... +0100 '<b>3</b> spheres<br><br>',... +0101 'For <b>right angular</b> and <b>polygonal</b> cross-sections "a" converts to the area-equivalent cylinder radius e.g.:<br>',... +0102 '<b>2.57</b> capillaries with 60°-60°-60° equilateral cross section<br>',... +0103 '<b>2.72-12.18</b> capillaries with 90°-a°-(90-a)° right angular cross section<br>',... +0104 'e.g. <b>2.72</b> is 90°-45°-45° | <b>2.87</b> is 90°-60°-30° | <b>5.64</b> is 90°-85°-5°<br><br>',... +0105 '<u>Default value:</u><br>',... +0106 '<b>2</b><br>']; +0107 gui.edit_handles.param_geom = uicontrol('Parent',gui.panels.petro.HBox2,... +0108 'Style','edit','String',num2str(data.param.a),'FontSize',myui.fontsize,... +0109 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.a 1 1]),... +0110 'Tag','param_a','Enable','off','Callback',@onEditValue); +0111 set(gui.panels.petro.HBox2,'Widths',[200 -1 -1]); +0112 +0113 %% CBW and BVI +0114 gui.text_handles.petro_CBW = uicontrol('Parent',gui.panels.petro.HBox3,... +0115 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... +0116 'String','CBW [ms] | BVI [ms] '); +0117 tstr = ['<HTML>Cut-off time between CBW and BVI in [ms].',... +0118 ' This value depends on lithology.<br><br>',... +0119 '<u>Abbreviations:</u><br>',... +0120 '<b>CBW</b> clay bound water<br>',... +0121 '<b>BVI</b> bulk volume irreducible (irreducible water)<br>',... +0122 '<b>BVM</b> bulk volume movable (free water)<br><br>',... +0123 'The value is usually <b>3 [ms]</b><br><br>',... +0124 '<u>Default value:</u><br>',... +0125 '<b>3</b><br>']; +0126 gui.edit_handles.param_CBW = uicontrol('Parent',gui.panels.petro.HBox3,... +0127 'Style','edit','String',num2str(data.param.CBWcutoff),'FontSize',myui.fontsize,... +0128 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.CBWcutoff 1 1]),... +0129 'Tag','param_CBWcutoff','Enable','off','Callback',@onEditValue); +0130 tstr = ['<HTML>Cut-off time between BVI and BVM in [ms].',... +0131 ' This value depends on lithology.<br><br>',... +0132 '<u>Abbreviations:</u><br>',... +0133 '<b>CBW</b> clay bound water<br>',... +0134 '<b>BVI</b> bulk volume irreducible (irreducible water)<br>',... +0135 '<b>BVM</b> bulk volume movable (free water)<br><br>',... +0136 'For Sandstones the value is usually <b>33 [ms]</b><br>',... +0137 'For Carbonates the value is usually <b>92 [ms]</b><br><br>',... +0138 '<u>Default value:</u><br>',... +0139 '<b>33</b><br>']; +0140 gui.edit_handles.param_BVI = uicontrol('Parent',gui.panels.petro.HBox3,... +0141 'Style','edit','String',num2str(data.param.BVIcutoff),'FontSize',myui.fontsize,... +0142 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.BVIcutoff 1 1]),... +0143 'Tag','param_BVIcutoff','Enable','off','Callback',@onEditValue); +0144 set(gui.panels.petro.HBox3,'Widths',[200 -1 -1]); +0145 +0146 %% calibration switch, calibration volume +0147 gui.text_handles.petro_calibVol = uicontrol('Parent',gui.panels.petro.HBox4,... +0148 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... +0149 'String',' calib. Vol. | calib. Amp.'); +0150 tstr = ''; +0151 gui.edit_handles.param_calibVol = uicontrol('Parent',gui.panels.petro.HBox4,... +0152 'Style','edit','String',num2str(data.param.calibVol),'FontSize',myui.fontsize,... +0153 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.calibVol 1 1]),... +0154 'Tag','param_calibVol','Enable','off','Callback',@onEditValue); +0155 tstr = ''; +0156 gui.edit_handles.param_calibAmp = uicontrol('Parent',gui.panels.petro.HBox4,... +0157 'Style','edit','String',num2str(data.param.calibAmp),'FontSize',myui.fontsize,... +0158 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.calibAmp 1 1]),... +0159 'Tag','param_calibAmp','Enable','off','Callback',@onEditValue); +0160 set(gui.panels.petro.HBox4,'Widths',[200 -1 -1]); +0161 +0162 %% sample volume, porosity +0163 gui.text_handles.petro_sampVol = uicontrol('Parent',gui.panels.petro.HBox5,... +0164 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... +0165 'String','sample Vol. | porosity '); +0166 tstr = ' '; +0167 gui.edit_handles.param_sampVol = uicontrol('Parent',gui.panels.petro.HBox5,... +0168 'Style','edit','String',num2str(data.param.sampVol),'FontSize',myui.fontsize,... +0169 'UserData',struct('Tooltipstr',tstr,'defaults',[data.param.sampVol 1 1]),... +0170 'Tag','param_sampVol','Enable','off','Callback',@onEditValue); +0171 tstr = ['<HTML>Porosity (between 0 and 1)<br><br>',... +0172 '<u>Default value:</u><br>',... +0173 '<b>1</b><br><br>']; +0174 gui.edit_handles.invstd_porosity = uicontrol('Parent',gui.panels.petro.HBox5,... +0175 'Style','edit','String',num2str(data.invstd.porosity),'FontSize',myui.fontsize,... +0176 'UserData',struct('Tooltipstr',tstr,'defaults',[data.invstd.porosity 1 1]),... +0177 'Tag','invstd_porosity','Enable','off','Callback',@onEditValue); +0178 set(gui.panels.petro.HBox5,'Widths',[200 -1 -1]); +0179 +0180 %% Java Hack to adjust vertical alignment of text fields +0181 jh = findjobj(gui.text_handles.petro_Tbulk); +0182 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0183 jh = findjobj(gui.text_handles.petro_rho); +0184 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0185 jh = findjobj(gui.text_handles.petro_CBW); +0186 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0187 jh = findjobj(gui.text_handles.petro_calibVol); +0188 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0189 jh = findjobj(gui.text_handles.petro_sampVol); +0190 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0191 +0192 return +0193 +0194 %------------- END OF CODE -------------- +0195 +0196 %% License: +0197 % MIT License +0198 % +0199 % Copyright (c) 2018 Thomas Hiller +0200 % +0201 % Permission is hereby granted, free of charge, to any person obtaining a copy +0202 % of this software and associated documentation files (the "Software"), to deal +0203 % in the Software without restriction, including without limitation the rights +0204 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0205 % copies of the Software, and to permit persons to whom the Software is +0206 % furnished to do so, subject to the following conditions: +0207 % +0208 % The above copyright notice and this permission notice shall be included in all +0209 % copies or substantial portions of the Software. +0210 % +0211 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0212 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0213 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0214 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0215 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0216 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0217 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelPlots.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelPlots.html index 8135e9c..0c76271 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelPlots.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelPlots.html @@ -53,8 +53,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -98,8 +98,8 @@

    SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelProcess.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelProcess.html index 7504b23..5e09ee5 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelProcess.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createPanelProcess.html @@ -53,8 +53,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -98,8 +98,8 @@

    SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createStatusbar.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createStatusbar.html index 8a968b5..87557f3 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createStatusbar.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_createStatusbar.html @@ -90,8 +90,8 @@

    SOURCE CODE ^% 0025 % See also: NUCLEUSinv 0026 -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 0030 %------------- BEGIN CODE -------------- 0031 diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_loadDefaults.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_loadDefaults.html index c199bbe..87c71c0 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_loadDefaults.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_loadDefaults.html @@ -50,8 +50,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -92,8 +92,8 @@

    SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- @@ -196,78 +196,87 @@

    SOURCE CODE ^% water bulk relaxation time [s] 0129 out.invstd.Tbulk = 1e6; -0130 % porosity value between 0 and 1 [-] -0131 out.invstd.porosity = 1; -0132 -0133 %% joint inversion panel defaults -0134 % joint inversion methods to choose 'free' | 'fixed' | 'shape' -0135 out.invjoint.invtype = 'free'; -0136 % pore size distribution in [m] -0137 out.invjoint.radii = [1e-8 1e-2]; -0138 % No. of steps per decade in pore size distribution -0139 out.invjoint.Nradii = 25; -0140 % regularization options for joint inversion 'free' -0141 out.invjoint.regtype = 'manual'; -0142 % smoothness constraint (order) for joint inversion 'free' -0143 out.invjoint.Lorder = 1; -0144 % regularization parameter for joint inversion 'free' -0145 out.invjoint.lambda = 1; -0146 % L-curve range (lambda) for joint inversion 'free' -0147 out.invjoint.lambdaR = [1e-3 1e2]; -0148 % initial L-curve range (lambda) for joint inversion 'free' -0149 out.invjoint.lambdaRinit = [1e-3 1e2]; -0150 out.invjoint.NlambdaR = 20; -0151 % available pore geometries 'cyl' | 'ang' | 'poly' -0152 out.invjoint.geometry_type = 'cyl'; -0153 % number of polygon sides for geometry 'poly' (3 to 12) -0154 out.invjoint.polyN = 3; -0155 % angle alpha [deg] - fixed to 90° -0156 out.invjoint.alpha = 90; -0157 % angle beta [deg] - changed by user -0158 out.invjoint.beta = 60; -0159 % gamma [deg] - alpha-beta -0160 out.invjoint.gamma = 30; -0161 % start value rho [µm/s] -0162 out.invjoint.rhostart = 20; -0163 % lower and upper boundary for rho [µm/s] -0164 out.invjoint.rhobounds = [0.01 1000]; -0165 % sart value beta [deg] -0166 out.invjoint.anglestart = 25; -0167 -0168 % pressure settings -0169 % CPS table initial values (use,p,S,drain/imb) -0170 out.pressure.table = {true,0,1,'D'}; -0171 % pressure units 'Pa' | 'kPa' | 'MPa' | 'bar' -0172 out.pressure.unit = 'Pa'; -0173 % corresponding scale factors - 1 | 1e-3 | 1e-6 | 1e-5 -0174 out.pressure.unitfac = 1; -0175 -0176 return -0177 -0178 %------------- END OF CODE -------------- -0179 -0180 %% License: -0181 % MIT License -0182 % -0183 % Copyright (c) 2018 Thomas Hiller -0184 % -0185 % Permission is hereby granted, free of charge, to any person obtaining a copy -0186 % of this software and associated documentation files (the "Software"), to deal -0187 % in the Software without restriction, including without limitation the rights -0188 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0189 % copies of the Software, and to permit persons to whom the Software is -0190 % furnished to do so, subject to the following conditions: +0130 % diffusion relaxation time [s] +0131 out.invstd.Tdiff = 1e6; +0132 % porosity value between 0 and 1 [-] +0133 out.invstd.porosity = 1; +0134 +0135 out.invstd.useUncert = 1; +0136 out.invstd.uncertMethod = 'thresh'; +0137 out.invstd.uncertThresh = 0.05; +0138 out.invstd.uncertChi2 = 0.005; +0139 out.invstd.uncertN = 100; +0140 out.invstd.uncertMax = 1e4; +0141 +0142 %% joint inversion panel defaults +0143 % joint inversion methods to choose 'free' | 'fixed' | 'shape' +0144 out.invjoint.invtype = 'free'; +0145 % pore size distribution in [m] +0146 out.invjoint.radii = [1e-8 1e-2]; +0147 % No. of steps per decade in pore size distribution +0148 out.invjoint.Nradii = 25; +0149 % regularization options for joint inversion 'free' +0150 out.invjoint.regtype = 'manual'; +0151 % smoothness constraint (order) for joint inversion 'free' +0152 out.invjoint.Lorder = 1; +0153 % regularization parameter for joint inversion 'free' +0154 out.invjoint.lambda = 1; +0155 % L-curve range (lambda) for joint inversion 'free' +0156 out.invjoint.lambdaR = [1e-3 1e2]; +0157 % initial L-curve range (lambda) for joint inversion 'free' +0158 out.invjoint.lambdaRinit = [1e-3 1e2]; +0159 out.invjoint.NlambdaR = 20; +0160 % available pore geometries 'cyl' | 'ang' | 'poly' +0161 out.invjoint.geometry_type = 'cyl'; +0162 % number of polygon sides for geometry 'poly' (3 to 12) +0163 out.invjoint.polyN = 3; +0164 % angle alpha [deg] - fixed to 90° +0165 out.invjoint.alpha = 90; +0166 % angle beta [deg] - changed by user +0167 out.invjoint.beta = 60; +0168 % gamma [deg] - alpha-beta +0169 out.invjoint.gamma = 30; +0170 % start value rho [µm/s] +0171 out.invjoint.rhostart = 20; +0172 % lower and upper boundary for rho [µm/s] +0173 out.invjoint.rhobounds = [0.01 1000]; +0174 % sart value beta [deg] +0175 out.invjoint.anglestart = 25; +0176 +0177 % pressure settings +0178 % CPS table initial values (use,p,S,drain/imb) +0179 out.pressure.table = {true,0,1,'D'}; +0180 % pressure units 'Pa' | 'kPa' | 'MPa' | 'bar' +0181 out.pressure.unit = 'Pa'; +0182 % corresponding scale factors - 1 | 1e-3 | 1e-6 | 1e-5 +0183 out.pressure.unitfac = 1; +0184 +0185 return +0186 +0187 %------------- END OF CODE -------------- +0188 +0189 %% License: +0190 % MIT License 0191 % -0192 % The above copyright notice and this permission notice shall be included in all -0193 % copies or substantial portions of the Software. -0194 % -0195 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0196 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0197 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0198 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0199 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0200 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0201 % SOFTWARE. +0192 % Copyright (c) 2018 Thomas Hiller +0193 % +0194 % Permission is hereby granted, free of charge, to any person obtaining a copy +0195 % of this software and associated documentation files (the "Software"), to deal +0196 % in the Software without restriction, including without limitation the rights +0197 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0198 % copies of the Software, and to permit persons to whom the Software is +0199 % furnished to do so, subject to the following conditions: +0200 % +0201 % The above copyright notice and this permission notice shall be included in all +0202 % copies or substantial portions of the Software. +0203 % +0204 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0205 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0206 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0207 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0208 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0209 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0210 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_processINI.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_processINI.html index 1918cf2..54cf131 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_processINI.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_processINI.html @@ -50,8 +50,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -92,8 +92,8 @@

    SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_updateInterface.html b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_updateInterface.html index 98157ca..e4c1daf 100644 --- a/doc/nucleus/NUCLEUSinv/NUCLEUSinv_updateInterface.html +++ b/doc/nucleus/NUCLEUSinv/NUCLEUSinv_updateInterface.html @@ -59,8 +59,8 @@

    DESCRIPTION ^NUCLEUSinv - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -112,8 +112,8 @@

    SOURCE CODE ^% none 0033 % 0034 % See also: NUCLEUSinv -0035 % Author: Thomas Hiller -0036 % email: thomas.hiller[at]leibniz-liag.de +0035 % Author: see AUTHORS.md +0036 % email: see AUTHORS.md 0037 % License: MIT License (at end) 0038 0039 %------------- BEGIN CODE -------------- @@ -149,7 +149,7 @@

    SOURCE CODE ^%% update standard inversion panel 0070 % inversion method popup 0071 istring = {'Mono exp.','Several free exp. (2-5)',... -0072 'Multi exp. (LSQ)','Multi exp. (LU decomp.)'}; +0072 'Multi exp. (LSQ)','Multi exp. (LU decomp.)','Multi modal'}; 0073 set(gui.popup_handles.invstd_InvType,'String',istring); 0074 switch data.invstd.invtype 0075 case 'mono' @@ -167,837 +167,879 @@

    SOURCE CODE ^updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); 0088 gui = updateInvstdTime(gui,data.invstd.invtype,0,0); 0089 -0090 % Tbulk +0090 % Tbulk & Tdiff 0091 set(gui.edit_handles.invstd_Tbulk,'Enable','off',... 0092 'String',num2str(data.invstd.Tbulk)); -0093 -0094 case 'free' -0095 % inversion method popup -0096 set(gui.popup_handles.invstd_InvType,'Value',2,'Enable','on'); -0097 -0098 % additional inversion settings -0099 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... -0100 'Value',data.invstd.freeDT,... -0101 'String',{'1','2','3','4','5'}); -0102 set(gui.text_handles.invstd_InvTypeOpt,... -0103 'String','No. of free decay times T'); -0104 -0105 % lambda, smoothness constraint and RTD limits -0106 gui = updateLambda(gui,data.invstd.regtype,0,0,0); -0107 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); -0108 gui = updateInvstdTime(gui,data.invstd.invtype,0,0); -0109 -0110 % Tbulk -0111 set(gui.edit_handles.invstd_Tbulk,'Enable','off',... -0112 'String',num2str(data.invstd.Tbulk)); -0113 -0114 case 'NNLS' -0115 % inversion method popup -0116 set(gui.popup_handles.invstd_InvType,'Value',3,'Enable','on'); +0093 set(gui.edit_handles.invstd_Tdiff,'Enable','off',... +0094 'String',num2str(data.invstd.Tdiff)); +0095 +0096 case 'free' +0097 % inversion method popup +0098 set(gui.popup_handles.invstd_InvType,'Value',2,'Enable','on'); +0099 +0100 % additional inversion settings +0101 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... +0102 'Value',data.invstd.freeDT,... +0103 'String',{'1','2','3','4','5'}); +0104 set(gui.text_handles.invstd_InvTypeOpt,... +0105 'String','No. of free decay times T'); +0106 +0107 % lambda, smoothness constraint and RTD limits +0108 gui = updateLambda(gui,data.invstd.regtype,0,0,0); +0109 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); +0110 gui = updateInvstdTime(gui,data.invstd.invtype,0,0); +0111 +0112 % Tbulk & Tdiff +0113 set(gui.edit_handles.invstd_Tbulk,'Enable','off',... +0114 'String',num2str(data.invstd.Tbulk)); +0115 set(gui.edit_handles.invstd_Tdiff,'Enable','off',... +0116 'String',num2str(data.invstd.Tdiff)); 0117 -0118 % additional inversion settings -0119 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... -0120 'String',{'Manual','Tikhonov (SVD)','TSVD (SVD)',... -0121 'DSVD (SVD)','Discrep. (SVD)','L-curve'}); -0122 set(gui.text_handles.invstd_InvTypeOpt,... -0123 'String','regularization options'); -0124 -0125 % regularization options -0126 switch data.invstd.regtype -0127 case 'manual' -0128 set(gui.popup_handles.invstd_InvTypeOpt,'Value',1); -0129 case 'gcv_tikh' -0130 set(gui.popup_handles.invstd_InvTypeOpt,'Value',2); -0131 case 'gcv_trunc' -0132 set(gui.popup_handles.invstd_InvTypeOpt,'Value',3); -0133 case 'gcv_damp' -0134 set(gui.popup_handles.invstd_InvTypeOpt,'Value',4); -0135 case 'discrep' -0136 set(gui.popup_handles.invstd_InvTypeOpt,'Value',5); -0137 case 'lcurve' -0138 set(gui.popup_handles.invstd_InvTypeOpt,'Value',6); -0139 end -0140 -0141 % lambda, smoothness constraint and RTD limits -0142 gui = updateLambda(gui,data.invstd.regtype,data.invstd.lambda,... -0143 data.invstd.lambdaR,data.invstd.NlambdaR); -0144 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); -0145 gui = updateInvstdTime(gui,data.invstd.invtype,data.invstd.time,... -0146 data.invstd.Ntime); -0147 -0148 % Tbulk -0149 set(gui.edit_handles.invstd_Tbulk,'Enable','on',... -0150 'String',num2str(data.invstd.Tbulk)); +0118 case 'NNLS' +0119 % inversion method popup +0120 set(gui.popup_handles.invstd_InvType,'Value',3,'Enable','on'); +0121 +0122 % additional inversion settings +0123 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... +0124 'String',{'Manual','Tikhonov (SVD)','TSVD (SVD)',... +0125 'DSVD (SVD)','Discrep. (SVD)','L-curve'}); +0126 set(gui.text_handles.invstd_InvTypeOpt,... +0127 'String','regularization options'); +0128 +0129 % regularization options +0130 switch data.invstd.regtype +0131 case 'manual' +0132 set(gui.popup_handles.invstd_InvTypeOpt,'Value',1); +0133 case 'gcv_tikh' +0134 set(gui.popup_handles.invstd_InvTypeOpt,'Value',2); +0135 case 'gcv_trunc' +0136 set(gui.popup_handles.invstd_InvTypeOpt,'Value',3); +0137 case 'gcv_damp' +0138 set(gui.popup_handles.invstd_InvTypeOpt,'Value',4); +0139 case 'discrep' +0140 set(gui.popup_handles.invstd_InvTypeOpt,'Value',5); +0141 case 'lcurve' +0142 set(gui.popup_handles.invstd_InvTypeOpt,'Value',6); +0143 end +0144 +0145 % lambda, smoothness constraint and RTD limits +0146 gui = updateLambda(gui,data.invstd.regtype,data.invstd.lambda,... +0147 data.invstd.lambdaR,data.invstd.NlambdaR); +0148 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); +0149 gui = updateInvstdTime(gui,data.invstd.invtype,data.invstd.time,... +0150 data.invstd.Ntime); 0151 -0152 case 'LU' -0153 % inversion method popup -0154 set(gui.popup_handles.invstd_InvType,'Value',4,'Enable','on'); -0155 -0156 % additional inversion settings -0157 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... -0158 'String',{'Manual','Automatic'}); -0159 set(gui.text_handles.invstd_InvTypeOpt,... -0160 'String','regularization options'); +0152 % Tbulk & Tdiff +0153 set(gui.edit_handles.invstd_Tbulk,'Enable','on',... +0154 'String',num2str(data.invstd.Tbulk)); +0155 set(gui.edit_handles.invstd_Tdiff,'Enable','on',... +0156 'String',num2str(data.invstd.Tdiff)); +0157 +0158 case 'LU' +0159 % inversion method popup +0160 set(gui.popup_handles.invstd_InvType,'Value',4,'Enable','on'); 0161 -0162 % regularization options -0163 switch data.invstd.regtype -0164 case 'manual' -0165 set(gui.popup_handles.invstd_InvTypeOpt,'Value',1); -0166 case 'auto' -0167 set(gui.popup_handles.invstd_InvTypeOpt,'Value',2); -0168 data.invstd.lambda = -1; -0169 end -0170 -0171 % lambda, smoothness constraint and RTD limits -0172 gui = updateLambda(gui,data.invstd.regtype,data.invstd.lambda,... -0173 data.invstd.lambdaR,data.invstd.NlambdaR); -0174 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); -0175 gui = updateInvstdTime(gui,data.invstd.invtype,data.invstd.time,... -0176 data.invstd.Ntime); -0177 -0178 % Tbulk -0179 set(gui.edit_handles.invstd_Tbulk,'Enable','on',... -0180 'String',num2str(data.invstd.Tbulk)); -0181 end -0182 -0183 % updates CBW, BVI, rho and a -0184 gui = updateParams(gui,data.invstd.invtype,data.param); -0185 -0186 %% update joint inversion panel -0187 % depending if it is activated or not -0188 switch data.info.JointInv -0189 case 'on' -0190 % inversion method dependent -0191 switch data.invjoint.invtype -0192 case 'free' -0193 % inversion method popup -0194 set(gui.popup_handles.invjoint_InvType,'Value',1,'Enable','on'); -0195 -0196 % PSD limits -0197 gui = updateInvjointRadii(gui,data.invjoint.invtype,... -0198 data.invjoint.radii,data.invjoint.Nradii); -0199 -0200 % additional inversion settings -0201 set(gui.popup_handles.invjoint_InvTypeOpt,'Enable','on'); -0202 -0203 % regularization options -0204 switch data.invjoint.regtype -0205 case 'manual' -0206 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',1); -0207 case 'lcurve' -0208 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',2); -0209 end -0210 -0211 % smoothness constraint and lambda -0212 gui = updateLorderJoint(gui,data.invjoint.invtype,... -0213 data.invjoint.Lorder); -0214 gui = updateLambdaJoint(gui,data.invjoint.regtype,... -0215 data.invjoint.lambda,data.invjoint.lambdaR,... -0216 data.invjoint.NlambdaR,data.invstd.regtype); -0217 -0218 % start values -0219 set(gui.edit_handles.invjoint_rhostart,'Enable','on'); -0220 set(gui.edit_handles.invjoint_anglestart,'Enable','off'); -0221 -0222 % geometry type dependent -0223 switch data.invjoint.geometry_type -0224 case 'cyl' -0225 % geometry popup -0226 set(gui.popup_handles.invjoint_geometry_type,... -0227 'Value',1,'Enable','on'); -0228 -0229 % polygon sides and corresponding angle beta -0230 set(gui.popup_handles.invjoint_polyN,'Enable','off',... -0231 'Value',data.invjoint.polyN-2); -0232 set(gui.edit_handles.invjoint_beta,'Enable','off'); -0233 -0234 % angles -0235 set(gui.edit_handles.invjoint_alpha,'String',''); -0236 set(gui.edit_handles.invjoint_beta,'String',''); -0237 set(gui.edit_handles.invjoint_gamma,'String',''); -0238 -0239 case 'ang' -0240 % geometry popup -0241 set(gui.popup_handles.invjoint_geometry_type,... -0242 'Value',2,'Enable','on'); -0243 -0244 % polygon sides and corresponding angle beta -0245 set(gui.popup_handles.invjoint_polyN,'Enable','off',... -0246 'Value',data.invjoint.polyN-2); -0247 set(gui.edit_handles.invjoint_beta,'Enable','on'); -0248 -0249 % angles -0250 set(gui.edit_handles.invjoint_alpha,... -0251 'String',num2str(data.invjoint.alpha)); -0252 set(gui.edit_handles.invjoint_beta,... -0253 'String',num2str(data.invjoint.beta)); -0254 set(gui.edit_handles.invjoint_gamma,... -0255 'String',num2str(data.invjoint.gamma)); -0256 -0257 case 'poly' -0258 % geometry popup -0259 set(gui.popup_handles.invjoint_geometry_type,... -0260 'Value',3,'Enable','on'); -0261 -0262 % polygon sides and corresponding angle beta -0263 set(gui.popup_handles.invjoint_polyN,'Enable','on',... -0264 'Value',data.invjoint.polyN-2); -0265 set(gui.edit_handles.invjoint_beta,'Enable','off'); -0266 -0267 % angles -0268 polyangle = ((data.invjoint.polyN-2)/data.invjoint.polyN)*180; -0269 set(gui.edit_handles.invjoint_alpha,... -0270 'String',''); -0271 set(gui.edit_handles.invjoint_beta,... -0272 'String',num2str(polyangle)); -0273 set(gui.edit_handles.invjoint_gamma,... -0274 'String',''); -0275 end -0276 -0277 case 'fixed' -0278 % inversion method popup -0279 set(gui.popup_handles.invjoint_InvType,'Value',2,'Enable','on'); -0280 -0281 % PSD limits -0282 gui = updateInvjointRadii(gui,data.invjoint.invtype,... -0283 data.invjoint.radii,data.invjoint.Nradii); -0284 -0285 % additional inversion settings -0286 set(gui.popup_handles.invjoint_InvTypeOpt,'Enable','off'); -0287 -0288 % regularization options -0289 switch data.invjoint.regtype -0290 case 'manual' -0291 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',1); -0292 case 'lcurve' -0293 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',2); -0294 end -0295 -0296 % smoothness constraint and lambda -0297 gui = updateLorderJoint(gui,data.invjoint.invtype,... -0298 data.invjoint.Lorder); -0299 gui = updateLambdaJoint(gui,'none',data.invjoint.lambda,... -0300 data.invjoint.lambdaR,data.invjoint.NlambdaR,... -0301 data.invstd.regtype); -0302 -0303 % start values -0304 set(gui.edit_handles.invjoint_rhostart,'Enable','on'); -0305 set(gui.edit_handles.invjoint_anglestart,'Enable','off'); -0306 -0307 % geometry type dependent -0308 switch data.invjoint.geometry_type -0309 case 'cyl' -0310 % geometry popup -0311 set(gui.popup_handles.invjoint_geometry_type,... -0312 'Value',1,'Enable','on'); -0313 -0314 % polygon sides and corresponding angle beta -0315 set(gui.popup_handles.invjoint_polyN,'Enable','off',... -0316 'Value',data.invjoint.polyN-2); -0317 set(gui.edit_handles.invjoint_beta,'Enable','off'); -0318 -0319 % angles -0320 set(gui.edit_handles.invjoint_alpha,'String',''); -0321 set(gui.edit_handles.invjoint_beta,'String',''); -0322 set(gui.edit_handles.invjoint_gamma,'String',''); -0323 -0324 case 'ang' -0325 % geometry popup -0326 set(gui.popup_handles.invjoint_geometry_type,... -0327 'Value',2,'Enable','on'); -0328 -0329 % polygon sides and corresponding angle beta -0330 set(gui.popup_handles.invjoint_polyN,'Enable','off',... -0331 'Value',data.invjoint.polyN-2); -0332 set(gui.edit_handles.invjoint_beta,'Enable','on'); -0333 -0334 % angles -0335 set(gui.edit_handles.invjoint_alpha,... -0336 'String',num2str(data.invjoint.alpha)); -0337 set(gui.edit_handles.invjoint_beta,... -0338 'String',num2str(data.invjoint.beta)); -0339 set(gui.edit_handles.invjoint_gamma,... -0340 'String',num2str(data.invjoint.gamma)); -0341 -0342 case 'poly' -0343 % geometry popup -0344 set(gui.popup_handles.invjoint_geometry_type,... -0345 'Value',3,'Enable','on'); -0346 -0347 % polygon sides and corresponding angle beta -0348 set(gui.popup_handles.invjoint_polyN,'Enable','on',... -0349 'Value',data.invjoint.polyN-2); -0350 set(gui.edit_handles.invjoint_beta,'Enable','off'); -0351 -0352 % angles -0353 polyangle = ((data.invjoint.polyN-2)/data.invjoint.polyN)*180; -0354 set(gui.edit_handles.invjoint_alpha,... -0355 'String',''); -0356 set(gui.edit_handles.invjoint_beta,... -0357 'String',num2str(polyangle)); -0358 set(gui.edit_handles.invjoint_gamma,... -0359 'String',''); -0360 end -0361 -0362 case 'shape' -0363 % inversion method popup -0364 set(gui.popup_handles.invjoint_InvType,'Value',3,'Enable','on'); -0365 -0366 % PSD limits -0367 gui = updateInvjointRadii(gui,data.invjoint.invtype,... -0368 data.invjoint.radii,data.invjoint.Nradii); -0369 -0370 % additional inversion settings -0371 set(gui.popup_handles.invjoint_InvTypeOpt,'Enable','off'); -0372 -0373 % regularization options -0374 switch data.invjoint.regtype -0375 case 'manual' -0376 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',1); -0377 case 'lcurve' -0378 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',2); -0379 end -0380 -0381 % smoothness constraint and lambda -0382 gui = updateLorderJoint(gui,data.invjoint.invtype,... -0383 data.invjoint.Lorder); -0384 gui = updateLambdaJoint(gui,'none',data.invjoint.lambda,... -0385 data.invjoint.lambdaR,data.invjoint.NlambdaR,data.invstd.regtype); -0386 -0387 % start values -0388 set(gui.edit_handles.invjoint_rhostart,'Enable','on'); -0389 set(gui.edit_handles.invjoint_anglestart,'Enable','on'); -0390 -0391 % geometry type dependent -0392 switch data.invjoint.geometry_type -0393 case 'cyl' -0394 % geometry popup -0395 set(gui.popup_handles.invjoint_geometry_type,... -0396 'Value',1,'Enable','on'); -0397 -0398 % polygon sides and corresponding angle beta -0399 set(gui.popup_handles.invjoint_polyN,'Enable','off',... -0400 'Value',data.invjoint.polyN-2); -0401 set(gui.edit_handles.invjoint_beta,'Enable','off'); -0402 -0403 % angles -0404 set(gui.edit_handles.invjoint_alpha,'String',''); -0405 set(gui.edit_handles.invjoint_beta,'String',''); -0406 set(gui.edit_handles.invjoint_gamma,'String',''); -0407 -0408 case 'ang' -0409 % geometry popup -0410 set(gui.popup_handles.invjoint_geometry_type,... -0411 'Value',2,'Enable','on'); -0412 -0413 % polygon sides and corresponding angle beta -0414 set(gui.popup_handles.invjoint_polyN,'Enable','off',... -0415 'Value',data.invjoint.polyN-2); -0416 set(gui.edit_handles.invjoint_beta,'Enable','off'); -0417 -0418 % angles -0419 set(gui.edit_handles.invjoint_alpha,... -0420 'String',num2str(data.invjoint.alpha)); -0421 set(gui.edit_handles.invjoint_beta,... -0422 'String',num2str(data.invjoint.beta)); -0423 set(gui.edit_handles.invjoint_gamma,... -0424 'String',num2str(data.invjoint.gamma)); -0425 -0426 case 'poly' -0427 % geometry popup -0428 set(gui.popup_handles.invjoint_geometry_type,... -0429 'Value',3,'Enable','on'); -0430 -0431 % polygon sides and corresponding angle beta -0432 set(gui.popup_handles.invjoint_polyN,'Enable','on',... -0433 'Value',data.invjoint.polyN-2); -0434 set(gui.edit_handles.invjoint_beta,'Enable','off'); -0435 -0436 % angles -0437 polyangle = ((data.invjoint.polyN-2)/data.invjoint.polyN)*180; -0438 set(gui.edit_handles.invjoint_alpha,... -0439 'String',''); -0440 set(gui.edit_handles.invjoint_beta,... -0441 'String',num2str(polyangle)); -0442 set(gui.edit_handles.invjoint_gamma,... -0443 'String',''); -0444 end -0445 end -0446 -0447 case 'off' -0448 % inversion method popup -0449 set(gui.popup_handles.invjoint_InvType,'Value',1,'Enable','off'); -0450 -0451 % PSD limits -0452 gui = updateInvjointRadii(gui,'off',0,0); -0453 -0454 % additional inversion settings -0455 set(gui.popup_handles.invjoint_InvTypeOpt,'Enable','off'); -0456 -0457 % smoothness constraint and lambda -0458 gui = updateLorderJoint(gui,'off',0); -0459 gui = updateLambdaJoint(gui,'none',data.invjoint.lambda,... -0460 data.invjoint.lambdaR,data.invjoint.NlambdaR,data.invstd.regtype); -0461 -0462 % polygon sides and angles -0463 set(gui.popup_handles.invjoint_polyN,'Enable','off'); -0464 set(gui.edit_handles.invjoint_alpha,'Enable','off'); -0465 set(gui.edit_handles.invjoint_beta,'Enable','off'); -0466 set(gui.edit_handles.invjoint_gamma,'Enable','off'); -0467 -0468 % start values -0469 set(gui.edit_handles.invjoint_rhostart,'Enable','off'); -0470 set(gui.edit_handles.invjoint_anglestart,'Enable','off'); -0471 end -0472 -0473 % this is always updated -0474 switch data.pressure.unit -0475 case 'Pa' -0476 set(gui.popup_handles.invjoint_pressure_units,'Value',1); -0477 case 'kPa' -0478 set(gui.popup_handles.invjoint_pressure_units,'Value',2); -0479 case 'MPa' -0480 set(gui.popup_handles.invjoint_pressure_units,'Value',3); -0481 case 'bar' -0482 set(gui.popup_handles.invjoint_pressure_units,'Value',4); -0483 end -0484 set(gui.table_handles.invjoint_table,... -0485 'ColumnName',{'use',['p [',data.pressure.unit,']'],'S [-]','D / I'}) -0486 -0487 table = data.pressure.table; -0488 for i = 1:size(table,1) -0489 table{i,2} = table{i,2}.*data.pressure.unitfac; -0490 end -0491 set(gui.table_handles.invjoint_table,'Data',table); -0492 -0493 case 'off' -0494 %% update the processing panel -0495 set(gui.edit_handles.process_start,'Enable','on',... -0496 'String',num2str(data.process.start)); -0497 set(gui.edit_handles.process_end,'Enable','on',... -0498 'String',num2str(data.process.end)); -0499 set(gui.edit_handles.process_Nechoes,'Enable','on',... -0500 'String',num2str(data.process.Nechoes)); -0501 -0502 gui = updateGatetype(gui,data.process.gatetype); -0503 set(gui.radio_handles.process_normalize_on,'Enable','off','Value',0); -0504 set(gui.radio_handles.process_normalize_off,'Enable','off','Value',1); -0505 set(gui.radio_handles.process_timescale_s,'Enable','off','Value',1); -0506 set(gui.radio_handles.process_timescale_ms,'Enable','off','Value',0); -0507 -0508 if data.invstd.porosity <= 1 -0509 set(gui.edit_handles.invstd_porosity,'Enable','on',... -0510 'BackgroundColor','w',... -0511 'String',num2str(data.invstd.porosity)); -0512 else -0513 set(gui.edit_handles.invstd_porosity,'Enable','on',... -0514 'BackgroundColor','r',... -0515 'String',num2str(data.invstd.porosity)); -0516 end -0517 -0518 %% update standard inversion panel -0519 % inversion method popup -0520 istring = {'Mono exp.','Several free exp. (2-5)','Multi exp. (LSQ)'}; -0521 set(gui.popup_handles.invstd_InvType,'String',istring); -0522 switch data.invstd.invtype -0523 case 'mono' -0524 % inversion method popup -0525 set(gui.popup_handles.invstd_InvType,'Value',1,'Enable','on'); -0526 -0527 % additional inversion settings -0528 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','off',... -0529 'Value',1,'String','none'); -0530 set(gui.text_handles.invstd_InvTypeOpt,... -0531 'String','No extra options'); -0532 -0533 % lambda, smoothness constraint and RTD limits -0534 gui = updateLambda(gui,data.invstd.regtype,0,0,0); -0535 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); -0536 gui = updateInvstdTime(gui,data.invstd.invtype,0,0); -0537 -0538 % Tbulk -0539 set(gui.edit_handles.invstd_Tbulk,'Enable','off',... -0540 'String',num2str(data.invstd.Tbulk)); -0541 -0542 case 'free' -0543 % inversion method popup -0544 set(gui.popup_handles.invstd_InvType,'Value',2,'Enable','on'); -0545 -0546 % additional inversion settings -0547 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... -0548 'Value',data.invstd.freeDT,... -0549 'String',{'1','2','3','4','5'}); -0550 set(gui.text_handles.invstd_InvTypeOpt,... -0551 'String','No. of free decay times T'); -0552 -0553 % lambda, smoothness constraint and RTD limits -0554 gui = updateLambda(gui,data.invstd.regtype,0,0,0); -0555 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); -0556 gui = updateInvstdTime(gui,data.invstd.invtype,0,0); -0557 -0558 % Tbulk -0559 set(gui.edit_handles.invstd_Tbulk,'Enable','off',... -0560 'String',num2str(data.invstd.Tbulk)); -0561 -0562 case 'NNLS' -0563 % inversion method popup -0564 set(gui.popup_handles.invstd_InvType,'Value',3,'Enable','on'); -0565 -0566 % additional inversion settings -0567 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... -0568 'String',{'Manual','L-curve'}); -0569 set(gui.text_handles.invstd_InvTypeOpt,... -0570 'String','regularization options'); -0571 -0572 % regularization options -0573 switch data.invstd.regtype -0574 case 'manual' -0575 set(gui.popup_handles.invstd_InvTypeOpt,'Value',1); -0576 case 'lcurve' -0577 set(gui.popup_handles.invstd_InvTypeOpt,'Value',2); -0578 end +0162 % additional inversion settings +0163 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... +0164 'String',{'Manual','Automatic'}); +0165 set(gui.text_handles.invstd_InvTypeOpt,... +0166 'String','regularization options'); +0167 +0168 % regularization options +0169 switch data.invstd.regtype +0170 case 'manual' +0171 set(gui.popup_handles.invstd_InvTypeOpt,'Value',1); +0172 case 'auto' +0173 set(gui.popup_handles.invstd_InvTypeOpt,'Value',2); +0174 data.invstd.lambda = -1; +0175 end +0176 +0177 % lambda, smoothness constraint and RTD limits +0178 gui = updateLambda(gui,data.invstd.regtype,data.invstd.lambda,... +0179 data.invstd.lambdaR,data.invstd.NlambdaR); +0180 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); +0181 gui = updateInvstdTime(gui,data.invstd.invtype,data.invstd.time,... +0182 data.invstd.Ntime); +0183 +0184 % Tbulk & Tdiff +0185 set(gui.edit_handles.invstd_Tbulk,'Enable','on',... +0186 'String',num2str(data.invstd.Tbulk)); +0187 set(gui.edit_handles.invstd_Tdiff,'Enable','on',... +0188 'String',num2str(data.invstd.Tdiff)); +0189 +0190 case 'MUMO' +0191 % inversion method popup +0192 set(gui.popup_handles.invstd_InvType,'Value',5,'Enable','on'); +0193 +0194 % additional inversion settings +0195 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... +0196 'Value',data.invstd.freeDT,... +0197 'String',{'1','2','3','4','5'}); +0198 set(gui.text_handles.invstd_InvTypeOpt,... +0199 'String','No. of modes'); +0200 +0201 % % lambda, smoothness constraint and RTD limits +0202 % gui = updateLambda(gui,data.invstd.regtype,data.invstd.lambda,... +0203 % data.invstd.lambdaR,data.invstd.NlambdaR); +0204 % gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); +0205 gui = updateInvstdTime(gui,data.invstd.invtype,data.invstd.time,... +0206 data.invstd.Ntime); +0207 +0208 % lambda, smoothness constraint and RTD limits +0209 gui = updateLambda(gui,data.invstd.regtype,0,0,0); +0210 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); +0211 +0212 % Tbulk & Tdiff +0213 set(gui.edit_handles.invstd_Tbulk,'Enable','on',... +0214 'String',num2str(data.invstd.Tbulk)); +0215 set(gui.edit_handles.invstd_Tdiff,'Enable','on',... +0216 'String',num2str(data.invstd.Tdiff)); +0217 end +0218 +0219 % updates CBW, BVI, rho and a +0220 gui = updateParams(gui,data.invstd.invtype,data.param); +0221 +0222 %% update joint inversion panel +0223 % depending if it is activated or not +0224 switch data.info.JointInv +0225 case 'on' +0226 % inversion method dependent +0227 switch data.invjoint.invtype +0228 case 'free' +0229 % inversion method popup +0230 set(gui.popup_handles.invjoint_InvType,'Value',1,'Enable','on'); +0231 +0232 % PSD limits +0233 gui = updateInvjointRadii(gui,data.invjoint.invtype,... +0234 data.invjoint.radii,data.invjoint.Nradii); +0235 +0236 % additional inversion settings +0237 set(gui.popup_handles.invjoint_InvTypeOpt,'Enable','on'); +0238 +0239 % regularization options +0240 switch data.invjoint.regtype +0241 case 'manual' +0242 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',1); +0243 case 'lcurve' +0244 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',2); +0245 end +0246 +0247 % smoothness constraint and lambda +0248 gui = updateLorderJoint(gui,data.invjoint.invtype,... +0249 data.invjoint.Lorder); +0250 gui = updateLambdaJoint(gui,data.invjoint.regtype,... +0251 data.invjoint.lambda,data.invjoint.lambdaR,... +0252 data.invjoint.NlambdaR,data.invstd.regtype); +0253 +0254 % start values +0255 set(gui.edit_handles.invjoint_rhostart,'Enable','on'); +0256 set(gui.edit_handles.invjoint_anglestart,'Enable','off'); +0257 +0258 % geometry type dependent +0259 switch data.invjoint.geometry_type +0260 case 'cyl' +0261 % geometry popup +0262 set(gui.popup_handles.invjoint_geometry_type,... +0263 'Value',1,'Enable','on'); +0264 +0265 % polygon sides and corresponding angle beta +0266 set(gui.popup_handles.invjoint_polyN,'Enable','off',... +0267 'Value',data.invjoint.polyN-2); +0268 set(gui.edit_handles.invjoint_beta,'Enable','off'); +0269 +0270 % angles +0271 set(gui.edit_handles.invjoint_alpha,'String',''); +0272 set(gui.edit_handles.invjoint_beta,'String',''); +0273 set(gui.edit_handles.invjoint_gamma,'String',''); +0274 +0275 case 'ang' +0276 % geometry popup +0277 set(gui.popup_handles.invjoint_geometry_type,... +0278 'Value',2,'Enable','on'); +0279 +0280 % polygon sides and corresponding angle beta +0281 set(gui.popup_handles.invjoint_polyN,'Enable','off',... +0282 'Value',data.invjoint.polyN-2); +0283 set(gui.edit_handles.invjoint_beta,'Enable','on'); +0284 +0285 % angles +0286 set(gui.edit_handles.invjoint_alpha,... +0287 'String',num2str(data.invjoint.alpha)); +0288 set(gui.edit_handles.invjoint_beta,... +0289 'String',num2str(data.invjoint.beta)); +0290 set(gui.edit_handles.invjoint_gamma,... +0291 'String',num2str(data.invjoint.gamma)); +0292 +0293 case 'poly' +0294 % geometry popup +0295 set(gui.popup_handles.invjoint_geometry_type,... +0296 'Value',3,'Enable','on'); +0297 +0298 % polygon sides and corresponding angle beta +0299 set(gui.popup_handles.invjoint_polyN,'Enable','on',... +0300 'Value',data.invjoint.polyN-2); +0301 set(gui.edit_handles.invjoint_beta,'Enable','off'); +0302 +0303 % angles +0304 polyangle = ((data.invjoint.polyN-2)/data.invjoint.polyN)*180; +0305 set(gui.edit_handles.invjoint_alpha,... +0306 'String',''); +0307 set(gui.edit_handles.invjoint_beta,... +0308 'String',num2str(polyangle)); +0309 set(gui.edit_handles.invjoint_gamma,... +0310 'String',''); +0311 end +0312 +0313 case 'fixed' +0314 % inversion method popup +0315 set(gui.popup_handles.invjoint_InvType,'Value',2,'Enable','on'); +0316 +0317 % PSD limits +0318 gui = updateInvjointRadii(gui,data.invjoint.invtype,... +0319 data.invjoint.radii,data.invjoint.Nradii); +0320 +0321 % additional inversion settings +0322 set(gui.popup_handles.invjoint_InvTypeOpt,'Enable','off'); +0323 +0324 % regularization options +0325 switch data.invjoint.regtype +0326 case 'manual' +0327 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',1); +0328 case 'lcurve' +0329 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',2); +0330 end +0331 +0332 % smoothness constraint and lambda +0333 gui = updateLorderJoint(gui,data.invjoint.invtype,... +0334 data.invjoint.Lorder); +0335 gui = updateLambdaJoint(gui,'none',data.invjoint.lambda,... +0336 data.invjoint.lambdaR,data.invjoint.NlambdaR,... +0337 data.invstd.regtype); +0338 +0339 % start values +0340 set(gui.edit_handles.invjoint_rhostart,'Enable','on'); +0341 set(gui.edit_handles.invjoint_anglestart,'Enable','off'); +0342 +0343 % geometry type dependent +0344 switch data.invjoint.geometry_type +0345 case 'cyl' +0346 % geometry popup +0347 set(gui.popup_handles.invjoint_geometry_type,... +0348 'Value',1,'Enable','on'); +0349 +0350 % polygon sides and corresponding angle beta +0351 set(gui.popup_handles.invjoint_polyN,'Enable','off',... +0352 'Value',data.invjoint.polyN-2); +0353 set(gui.edit_handles.invjoint_beta,'Enable','off'); +0354 +0355 % angles +0356 set(gui.edit_handles.invjoint_alpha,'String',''); +0357 set(gui.edit_handles.invjoint_beta,'String',''); +0358 set(gui.edit_handles.invjoint_gamma,'String',''); +0359 +0360 case 'ang' +0361 % geometry popup +0362 set(gui.popup_handles.invjoint_geometry_type,... +0363 'Value',2,'Enable','on'); +0364 +0365 % polygon sides and corresponding angle beta +0366 set(gui.popup_handles.invjoint_polyN,'Enable','off',... +0367 'Value',data.invjoint.polyN-2); +0368 set(gui.edit_handles.invjoint_beta,'Enable','on'); +0369 +0370 % angles +0371 set(gui.edit_handles.invjoint_alpha,... +0372 'String',num2str(data.invjoint.alpha)); +0373 set(gui.edit_handles.invjoint_beta,... +0374 'String',num2str(data.invjoint.beta)); +0375 set(gui.edit_handles.invjoint_gamma,... +0376 'String',num2str(data.invjoint.gamma)); +0377 +0378 case 'poly' +0379 % geometry popup +0380 set(gui.popup_handles.invjoint_geometry_type,... +0381 'Value',3,'Enable','on'); +0382 +0383 % polygon sides and corresponding angle beta +0384 set(gui.popup_handles.invjoint_polyN,'Enable','on',... +0385 'Value',data.invjoint.polyN-2); +0386 set(gui.edit_handles.invjoint_beta,'Enable','off'); +0387 +0388 % angles +0389 polyangle = ((data.invjoint.polyN-2)/data.invjoint.polyN)*180; +0390 set(gui.edit_handles.invjoint_alpha,... +0391 'String',''); +0392 set(gui.edit_handles.invjoint_beta,... +0393 'String',num2str(polyangle)); +0394 set(gui.edit_handles.invjoint_gamma,... +0395 'String',''); +0396 end +0397 +0398 case 'shape' +0399 % inversion method popup +0400 set(gui.popup_handles.invjoint_InvType,'Value',3,'Enable','on'); +0401 +0402 % PSD limits +0403 gui = updateInvjointRadii(gui,data.invjoint.invtype,... +0404 data.invjoint.radii,data.invjoint.Nradii); +0405 +0406 % additional inversion settings +0407 set(gui.popup_handles.invjoint_InvTypeOpt,'Enable','off'); +0408 +0409 % regularization options +0410 switch data.invjoint.regtype +0411 case 'manual' +0412 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',1); +0413 case 'lcurve' +0414 set(gui.popup_handles.invjoint_InvTypeOpt,'Value',2); +0415 end +0416 +0417 % smoothness constraint and lambda +0418 gui = updateLorderJoint(gui,data.invjoint.invtype,... +0419 data.invjoint.Lorder); +0420 gui = updateLambdaJoint(gui,'none',data.invjoint.lambda,... +0421 data.invjoint.lambdaR,data.invjoint.NlambdaR,data.invstd.regtype); +0422 +0423 % start values +0424 set(gui.edit_handles.invjoint_rhostart,'Enable','on'); +0425 set(gui.edit_handles.invjoint_anglestart,'Enable','on'); +0426 +0427 % geometry type dependent +0428 switch data.invjoint.geometry_type +0429 case 'cyl' +0430 % geometry popup +0431 set(gui.popup_handles.invjoint_geometry_type,... +0432 'Value',1,'Enable','on'); +0433 +0434 % polygon sides and corresponding angle beta +0435 set(gui.popup_handles.invjoint_polyN,'Enable','off',... +0436 'Value',data.invjoint.polyN-2); +0437 set(gui.edit_handles.invjoint_beta,'Enable','off'); +0438 +0439 % angles +0440 set(gui.edit_handles.invjoint_alpha,'String',''); +0441 set(gui.edit_handles.invjoint_beta,'String',''); +0442 set(gui.edit_handles.invjoint_gamma,'String',''); +0443 +0444 case 'ang' +0445 % geometry popup +0446 set(gui.popup_handles.invjoint_geometry_type,... +0447 'Value',2,'Enable','on'); +0448 +0449 % polygon sides and corresponding angle beta +0450 set(gui.popup_handles.invjoint_polyN,'Enable','off',... +0451 'Value',data.invjoint.polyN-2); +0452 set(gui.edit_handles.invjoint_beta,'Enable','off'); +0453 +0454 % angles +0455 set(gui.edit_handles.invjoint_alpha,... +0456 'String',num2str(data.invjoint.alpha)); +0457 set(gui.edit_handles.invjoint_beta,... +0458 'String',num2str(data.invjoint.beta)); +0459 set(gui.edit_handles.invjoint_gamma,... +0460 'String',num2str(data.invjoint.gamma)); +0461 +0462 case 'poly' +0463 % geometry popup +0464 set(gui.popup_handles.invjoint_geometry_type,... +0465 'Value',3,'Enable','on'); +0466 +0467 % polygon sides and corresponding angle beta +0468 set(gui.popup_handles.invjoint_polyN,'Enable','on',... +0469 'Value',data.invjoint.polyN-2); +0470 set(gui.edit_handles.invjoint_beta,'Enable','off'); +0471 +0472 % angles +0473 polyangle = ((data.invjoint.polyN-2)/data.invjoint.polyN)*180; +0474 set(gui.edit_handles.invjoint_alpha,... +0475 'String',''); +0476 set(gui.edit_handles.invjoint_beta,... +0477 'String',num2str(polyangle)); +0478 set(gui.edit_handles.invjoint_gamma,... +0479 'String',''); +0480 end +0481 end +0482 +0483 case 'off' +0484 % inversion method popup +0485 set(gui.popup_handles.invjoint_InvType,'Value',1,'Enable','off'); +0486 +0487 % PSD limits +0488 gui = updateInvjointRadii(gui,'off',0,0); +0489 +0490 % additional inversion settings +0491 set(gui.popup_handles.invjoint_InvTypeOpt,'Enable','off'); +0492 +0493 % smoothness constraint and lambda +0494 gui = updateLorderJoint(gui,'off',0); +0495 gui = updateLambdaJoint(gui,'none',data.invjoint.lambda,... +0496 data.invjoint.lambdaR,data.invjoint.NlambdaR,data.invstd.regtype); +0497 +0498 % polygon sides and angles +0499 set(gui.popup_handles.invjoint_polyN,'Enable','off'); +0500 set(gui.edit_handles.invjoint_alpha,'Enable','off'); +0501 set(gui.edit_handles.invjoint_beta,'Enable','off'); +0502 set(gui.edit_handles.invjoint_gamma,'Enable','off'); +0503 +0504 % start values +0505 set(gui.edit_handles.invjoint_rhostart,'Enable','off'); +0506 set(gui.edit_handles.invjoint_anglestart,'Enable','off'); +0507 end +0508 +0509 % this is always updated +0510 switch data.pressure.unit +0511 case 'Pa' +0512 set(gui.popup_handles.invjoint_pressure_units,'Value',1); +0513 case 'kPa' +0514 set(gui.popup_handles.invjoint_pressure_units,'Value',2); +0515 case 'MPa' +0516 set(gui.popup_handles.invjoint_pressure_units,'Value',3); +0517 case 'bar' +0518 set(gui.popup_handles.invjoint_pressure_units,'Value',4); +0519 end +0520 set(gui.table_handles.invjoint_table,... +0521 'ColumnName',{'use',['p [',data.pressure.unit,']'],'S [-]','D / I'}) +0522 +0523 table = data.pressure.table; +0524 for i = 1:size(table,1) +0525 table{i,2} = table{i,2}.*data.pressure.unitfac; +0526 end +0527 set(gui.table_handles.invjoint_table,'Data',table); +0528 +0529 case 'off' +0530 %% update the processing panel +0531 set(gui.edit_handles.process_start,'Enable','on',... +0532 'String',num2str(data.process.start)); +0533 set(gui.edit_handles.process_end,'Enable','on',... +0534 'String',num2str(data.process.end)); +0535 set(gui.edit_handles.process_Nechoes,'Enable','on',... +0536 'String',num2str(data.process.Nechoes)); +0537 +0538 gui = updateGatetype(gui,data.process.gatetype); +0539 set(gui.radio_handles.process_normalize_on,'Enable','off','Value',0); +0540 set(gui.radio_handles.process_normalize_off,'Enable','off','Value',1); +0541 set(gui.radio_handles.process_timescale_s,'Enable','off','Value',1); +0542 set(gui.radio_handles.process_timescale_ms,'Enable','off','Value',0); +0543 +0544 if data.invstd.porosity <= 1 +0545 set(gui.edit_handles.invstd_porosity,'Enable','on',... +0546 'BackgroundColor','w',... +0547 'String',num2str(data.invstd.porosity)); +0548 else +0549 set(gui.edit_handles.invstd_porosity,'Enable','on',... +0550 'BackgroundColor','r',... +0551 'String',num2str(data.invstd.porosity)); +0552 end +0553 +0554 %% update standard inversion panel +0555 % inversion method popup +0556 istring = {'Mono exp.','Several free exp. (2-5)','Multi exp. (LSQ)'}; +0557 set(gui.popup_handles.invstd_InvType,'String',istring); +0558 switch data.invstd.invtype +0559 case 'mono' +0560 % inversion method popup +0561 set(gui.popup_handles.invstd_InvType,'Value',1,'Enable','on'); +0562 +0563 % additional inversion settings +0564 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','off',... +0565 'Value',1,'String','none'); +0566 set(gui.text_handles.invstd_InvTypeOpt,... +0567 'String','No extra options'); +0568 +0569 % lambda, smoothness constraint and RTD limits +0570 gui = updateLambda(gui,data.invstd.regtype,0,0,0); +0571 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); +0572 gui = updateInvstdTime(gui,data.invstd.invtype,0,0); +0573 +0574 % Tbulk & Tdiff +0575 set(gui.edit_handles.invstd_Tbulk,'Enable','off',... +0576 'String',num2str(data.invstd.Tbulk)); +0577 set(gui.edit_handles.invstd_Tdiff,'Enable','off',... +0578 'String',num2str(data.invstd.Tdiff)); 0579 -0580 % lambda, smoothness constraint and RTD limits -0581 gui = updateLambda(gui,data.invstd.regtype,data.invstd.lambda,... -0582 data.invstd.lambdaR,data.invstd.NlambdaR); -0583 data.invstd.Lorder = 1; -0584 set(gui.radio_handles.invstd_Lorder0,'Value',0,'Enable','off'); -0585 set(gui.radio_handles.invstd_Lorder1,'Value',1,'Enable','off'); -0586 set(gui.radio_handles.invstd_Lorder2,'Value',0,'Enable','off'); -0587 -0588 set(gui.edit_handles.invstd_time_min,'Enable','on',... -0589 'String',num2str(data.invstd.time(1))); -0590 set(gui.edit_handles.invstd_time_max,'Enable','on',... -0591 'String',num2str(data.invstd.time(2))); -0592 set(gui.edit_handles.invstd_Ntime,'Enable','off',... -0593 'String',num2str(data.invstd.Ntime)); -0594 -0595 % Tbulk -0596 set(gui.edit_handles.invstd_Tbulk,'Enable','on',... -0597 'String',num2str(data.invstd.Tbulk)); -0598 end -0599 -0600 %% update petro parameter panel -0601 data.param.CBWcutoff = 3; -0602 data.param.BVIcutoff = 33; -0603 data.param.rho = 10; -0604 data.param.a = 2; -0605 setappdata(fig,'data',data); -0606 set(gui.edit_handles.param_CBW,'Enable','off',... -0607 'String',num2str(data.param.CBWcutoff)); -0608 set(gui.edit_handles.param_BVI,'Enable','off',... -0609 'String',num2str(data.param.BVIcutoff)); -0610 set(gui.edit_handles.param_rho,'Enable','off',... -0611 'String',num2str(data.param.rho)); -0612 set(gui.edit_handles.param_geom,'Enable','off',... -0613 'String',num2str(data.param.a)); -0614 set(gui.edit_handles.param_calibVol,'Enable','on',... -0615 'String',num2str(data.param.calibVol)); -0616 set(gui.edit_handles.param_calibAmp,'Enable','on',... -0617 'String',num2str(data.param.calibAmp)); -0618 set(gui.edit_handles.param_sampVol,'Enable','on',... -0619 'String',num2str(data.param.sampVol)); -0620 end -0621 -0622 % Matlab needs some time -0623 pause(0.001); -0624 -0625 end -0626 -0627 %% sub functions -0628 function gui = updateGatetype(gui,gatetype) -0629 -0630 set(gui.radio_handles.process_gates_log,'Enable','on'); -0631 set(gui.radio_handles.process_gates_lin,'Enable','on'); -0632 set(gui.radio_handles.process_gates_none,'Enable','on'); -0633 -0634 switch gatetype -0635 -0636 case 'log' -0637 -0638 set(gui.radio_handles.process_gates_log,'Value',1); -0639 set(gui.radio_handles.process_gates_lin,'Value',0); -0640 set(gui.radio_handles.process_gates_none,'Value',0); -0641 set(gui.edit_handles.process_Nechoes,'Enable','on'); -0642 -0643 case 'lin' -0644 -0645 set(gui.radio_handles.process_gates_log,'Value',0); -0646 set(gui.radio_handles.process_gates_lin,'Value',1); -0647 set(gui.radio_handles.process_gates_none,'Value',0); -0648 set(gui.edit_handles.process_Nechoes,'Enable','on'); -0649 -0650 case 'raw' -0651 -0652 set(gui.radio_handles.process_gates_log,'Value',0); -0653 set(gui.radio_handles.process_gates_lin,'Value',0); -0654 set(gui.radio_handles.process_gates_none,'Value',1); -0655 set(gui.edit_handles.process_Nechoes,'Enable','off'); -0656 -0657 end -0658 -0659 end -0660 -0661 function gui = updateNormalize(gui,norm) -0662 -0663 switch norm -0664 case 0 -0665 set(gui.radio_handles.process_normalize_on,'Enable','on','Value',0); -0666 set(gui.radio_handles.process_normalize_off,'Enable','on','Value',1); -0667 -0668 case 1 -0669 set(gui.radio_handles.process_normalize_on,'Enable','on','Value',1); -0670 set(gui.radio_handles.process_normalize_off,'Enable','on','Value',0); -0671 end -0672 -0673 end -0674 -0675 function gui = updateTimescale(gui,timescale) -0676 -0677 switch timescale -0678 -0679 case 's' -0680 set(gui.radio_handles.process_timescale_s,'Enable','on','Value',1); -0681 set(gui.radio_handles.process_timescale_ms,'Enable','on','Value',0); -0682 set(gui.text_handles.invstd_RTDtimes,'String','RTD - min [s] | max [s] | # / dec',... -0683 'FontSize',10); -0684 set(gui.text_handles.petro_Tbulk,'String',... -0685 ['Tbulk [s] | ',char(hex2dec('03C1')),' [µm/s] | geom']); +0580 case 'free' +0581 % inversion method popup +0582 set(gui.popup_handles.invstd_InvType,'Value',2,'Enable','on'); +0583 +0584 % additional inversion settings +0585 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... +0586 'Value',data.invstd.freeDT,... +0587 'String',{'1','2','3','4','5'}); +0588 set(gui.text_handles.invstd_InvTypeOpt,... +0589 'String','No. of free decay times T'); +0590 +0591 % lambda, smoothness constraint and RTD limits +0592 gui = updateLambda(gui,data.invstd.regtype,0,0,0); +0593 gui = updateLorder(gui,data.invstd.invtype,data.invstd.Lorder); +0594 gui = updateInvstdTime(gui,data.invstd.invtype,0,0); +0595 +0596 % Tbulk & Tdiff +0597 set(gui.edit_handles.invstd_Tbulk,'Enable','off',... +0598 'String',num2str(data.invstd.Tbulk)); +0599 set(gui.edit_handles.invstd_Tdiff,'Enable','off',... +0600 'String',num2str(data.invstd.Tdiff)); +0601 +0602 case 'NNLS' +0603 % inversion method popup +0604 set(gui.popup_handles.invstd_InvType,'Value',3,'Enable','on'); +0605 +0606 % additional inversion settings +0607 set(gui.popup_handles.invstd_InvTypeOpt,'Enable','on',... +0608 'String',{'Manual','L-curve'}); +0609 set(gui.text_handles.invstd_InvTypeOpt,... +0610 'String','regularization options'); +0611 +0612 % regularization options +0613 switch data.invstd.regtype +0614 case 'manual' +0615 set(gui.popup_handles.invstd_InvTypeOpt,'Value',1); +0616 case 'lcurve' +0617 set(gui.popup_handles.invstd_InvTypeOpt,'Value',2); +0618 end +0619 +0620 % lambda, smoothness constraint and RTD limits +0621 gui = updateLambda(gui,data.invstd.regtype,data.invstd.lambda,... +0622 data.invstd.lambdaR,data.invstd.NlambdaR); +0623 data.invstd.Lorder = 1; +0624 set(gui.radio_handles.invstd_Lorder0,'Value',0,'Enable','off'); +0625 set(gui.radio_handles.invstd_Lorder1,'Value',1,'Enable','off'); +0626 set(gui.radio_handles.invstd_Lorder2,'Value',0,'Enable','off'); +0627 +0628 set(gui.edit_handles.invstd_time_min,'Enable','on',... +0629 'String',num2str(data.invstd.time(1))); +0630 set(gui.edit_handles.invstd_time_max,'Enable','on',... +0631 'String',num2str(data.invstd.time(2))); +0632 set(gui.edit_handles.invstd_Ntime,'Enable','off',... +0633 'String',num2str(data.invstd.Ntime)); +0634 +0635 % Tbulk & Tdiff +0636 set(gui.edit_handles.invstd_Tbulk,'Enable','on',... +0637 'String',num2str(data.invstd.Tbulk)); +0638 set(gui.edit_handles.invstd_Tdiff,'Enable','on',... +0639 'String',num2str(data.invstd.Tdiff)); +0640 end +0641 +0642 %% update petro parameter panel +0643 data.param.CBWcutoff = 3; +0644 data.param.BVIcutoff = 33; +0645 data.param.rho = 10; +0646 data.param.a = 2; +0647 setappdata(fig,'data',data); +0648 set(gui.edit_handles.param_CBW,'Enable','off',... +0649 'String',num2str(data.param.CBWcutoff)); +0650 set(gui.edit_handles.param_BVI,'Enable','off',... +0651 'String',num2str(data.param.BVIcutoff)); +0652 set(gui.edit_handles.param_rho,'Enable','off',... +0653 'String',num2str(data.param.rho)); +0654 set(gui.edit_handles.param_geom,'Enable','off',... +0655 'String',num2str(data.param.a)); +0656 set(gui.edit_handles.param_calibVol,'Enable','on',... +0657 'String',num2str(data.param.calibVol)); +0658 set(gui.edit_handles.param_calibAmp,'Enable','on',... +0659 'String',num2str(data.param.calibAmp)); +0660 set(gui.edit_handles.param_sampVol,'Enable','on',... +0661 'String',num2str(data.param.sampVol)); +0662 end +0663 +0664 % Matlab needs some time +0665 pause(0.001); +0666 +0667 end +0668 +0669 %% sub functions +0670 function gui = updateGatetype(gui,gatetype) +0671 +0672 set(gui.radio_handles.process_gates_log,'Enable','on'); +0673 set(gui.radio_handles.process_gates_lin,'Enable','on'); +0674 set(gui.radio_handles.process_gates_none,'Enable','on'); +0675 +0676 switch gatetype +0677 +0678 case 'log' +0679 +0680 set(gui.radio_handles.process_gates_log,'Value',1); +0681 set(gui.radio_handles.process_gates_lin,'Value',0); +0682 set(gui.radio_handles.process_gates_none,'Value',0); +0683 set(gui.edit_handles.process_Nechoes,'Enable','on'); +0684 +0685 case 'lin' 0686 -0687 case 'ms' -0688 set(gui.radio_handles.process_timescale_s,'Enable','on','Value',0); -0689 set(gui.radio_handles.process_timescale_ms,'Enable','on','Value',1); -0690 set(gui.text_handles.invstd_RTDtimes,'String','RTD - min [ms] | max [ms] | # / dec',... -0691 'FontSize',9); -0692 set(gui.text_handles.petro_Tbulk,'String',... -0693 ['Tbulk [ms] | ',char(hex2dec('03C1')),' [µm/s] | geom']); -0694 end -0695 -0696 end -0697 -0698 function gui = updateInvstdTime(gui,invtype,time,Ntime) -0699 -0700 switch invtype -0701 -0702 case {'mono','free'} -0703 set(gui.edit_handles.invstd_time_min,'Enable','off'); -0704 set(gui.edit_handles.invstd_time_max,'Enable','off'); -0705 set(gui.edit_handles.invstd_Ntime,'Enable','off'); -0706 -0707 case {'LU','NNLS'} -0708 set(gui.edit_handles.invstd_time_min,'Enable','on','String',num2str(time(1))); -0709 set(gui.edit_handles.invstd_time_max,'Enable','on','String',num2str(time(2))); -0710 set(gui.edit_handles.invstd_Ntime,'Enable','on','String',num2str(Ntime)); -0711 end -0712 +0687 set(gui.radio_handles.process_gates_log,'Value',0); +0688 set(gui.radio_handles.process_gates_lin,'Value',1); +0689 set(gui.radio_handles.process_gates_none,'Value',0); +0690 set(gui.edit_handles.process_Nechoes,'Enable','on'); +0691 +0692 case 'raw' +0693 +0694 set(gui.radio_handles.process_gates_log,'Value',0); +0695 set(gui.radio_handles.process_gates_lin,'Value',0); +0696 set(gui.radio_handles.process_gates_none,'Value',1); +0697 set(gui.edit_handles.process_Nechoes,'Enable','off'); +0698 +0699 end +0700 +0701 end +0702 +0703 function gui = updateNormalize(gui,norm) +0704 +0705 switch norm +0706 case 0 +0707 set(gui.radio_handles.process_normalize_on,'Enable','on','Value',0); +0708 set(gui.radio_handles.process_normalize_off,'Enable','on','Value',1); +0709 +0710 case 1 +0711 set(gui.radio_handles.process_normalize_on,'Enable','on','Value',1); +0712 set(gui.radio_handles.process_normalize_off,'Enable','on','Value',0); 0713 end 0714 -0715 function gui = updateInvjointRadii(gui,invtype,radii,Nradii) +0715 end 0716 -0717 switch invtype -0718 case {'fixed','shape','off'} -0719 set(gui.edit_handles.invjoint_radii_min,'Enable','off'); -0720 set(gui.edit_handles.invjoint_radii_max,'Enable','off'); -0721 set(gui.edit_handles.invjoint_Nradii,'Enable','off'); -0722 -0723 case {'free'} -0724 set(gui.edit_handles.invjoint_radii_min,'Enable','on','String',num2str(radii(1))); -0725 set(gui.edit_handles.invjoint_radii_max,'Enable','on','String',num2str(radii(2))); -0726 set(gui.edit_handles.invjoint_Nradii,'Enable','on','String',num2str(Nradii)); -0727 end -0728 -0729 end -0730 -0731 function gui = updateLambda(gui,regtype,lambda,lambdaR,NlambdaR) -0732 -0733 switch regtype -0734 case 'none' -0735 set(gui.edit_handles.invstd_lambda_min,'Enable','off'); -0736 set(gui.edit_handles.invstd_lambda_max,'Enable','off'); -0737 set(gui.edit_handles.invstd_NlambdaR,'Enable','off'); -0738 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; -0739 -0740 case 'manual' -0741 set(gui.edit_handles.invstd_lambda_min,'Enable','on','String',num2str(lambda)); -0742 set(gui.edit_handles.invstd_lambda_max,'Enable','off'); -0743 set(gui.edit_handles.invstd_NlambdaR,'Enable','off'); -0744 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; -0745 -0746 case 'auto' -0747 set(gui.edit_handles.invstd_lambda_min,'Enable','off','String',num2str(lambda)); -0748 set(gui.edit_handles.invstd_lambda_max,'Enable','off'); -0749 set(gui.edit_handles.invstd_NlambdaR,'Enable','off'); -0750 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; -0751 -0752 case 'lcurve' -0753 set(gui.edit_handles.invstd_lambda_min,'Enable','on','String',num2str(lambdaR(1))); -0754 set(gui.edit_handles.invstd_lambda_max,'Enable','on','String',num2str(lambdaR(2))); -0755 set(gui.edit_handles.invstd_NlambdaR,'Enable','on','String',num2str(NlambdaR)); -0756 gui.plots.DistPanel.TabTitles = {'L-CURVE','RMS','PSD (joint)'}; -0757 -0758 case {'gcv_tikh','gcv_trunc','gcv_damp','discrep'} -0759 set(gui.edit_handles.invstd_lambda_min,'Enable','off','String',num2str(lambda)); -0760 set(gui.edit_handles.invstd_lambda_max,'Enable','off'); -0761 set(gui.edit_handles.invstd_NlambdaR,'Enable','off'); -0762 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; -0763 end -0764 -0765 end -0766 -0767 function gui = updateLambdaJoint(gui,regtype,lambda,lambdaR,NlambdaR,regtypestd) -0768 -0769 switch regtype -0770 case 'none' -0771 switch regtypestd -0772 case 'lcurve' -0773 set(gui.edit_handles.invjoint_lambda_min,'Enable','off'); -0774 set(gui.edit_handles.invjoint_lambda_max,'Enable','off'); -0775 set(gui.edit_handles.invjoint_NlambdaR,'Enable','off'); -0776 gui.plots.DistPanel.TabTitles = {'L-CURVE','RMS','PSD (joint)'}; -0777 -0778 otherwise -0779 set(gui.edit_handles.invjoint_lambda_min,'Enable','off'); -0780 set(gui.edit_handles.invjoint_lambda_max,'Enable','off'); -0781 set(gui.edit_handles.invjoint_NlambdaR,'Enable','off'); -0782 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; -0783 end -0784 -0785 case 'manual' -0786 switch regtypestd -0787 case 'lcurve' -0788 set(gui.edit_handles.invjoint_lambda_min,'Enable','on','String',num2str(lambda)); -0789 set(gui.edit_handles.invjoint_lambda_max,'Enable','off'); -0790 set(gui.edit_handles.invjoint_NlambdaR,'Enable','off'); -0791 gui.plots.DistPanel.TabTitles = {'L-CURVE','RMS','PSD (joint)'}; -0792 -0793 otherwise -0794 set(gui.edit_handles.invjoint_lambda_min,'Enable','on','String',num2str(lambda)); -0795 set(gui.edit_handles.invjoint_lambda_max,'Enable','off'); -0796 set(gui.edit_handles.invjoint_NlambdaR,'Enable','off'); -0797 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; -0798 end +0717 function gui = updateTimescale(gui,timescale) +0718 +0719 switch timescale +0720 +0721 case 's' +0722 set(gui.radio_handles.process_timescale_s,'Enable','on','Value',1); +0723 set(gui.radio_handles.process_timescale_ms,'Enable','on','Value',0); +0724 set(gui.text_handles.invstd_RTDtimes,'String','RTD - min [s] | max [s] | # / dec',... +0725 'FontSize',10); +0726 set(gui.text_handles.petro_Tbulk,'String','Tbulk [s] | Tdiff [s]'); +0727 set(gui.text_handles.petro_rho,'String',[char(hex2dec('03C1')),' [µm/s] | geom ']); +0728 +0729 case 'ms' +0730 set(gui.radio_handles.process_timescale_s,'Enable','on','Value',0); +0731 set(gui.radio_handles.process_timescale_ms,'Enable','on','Value',1); +0732 set(gui.text_handles.invstd_RTDtimes,'String','RTD - min [ms] | max [ms] | # / dec',... +0733 'FontSize',9); +0734 set(gui.text_handles.petro_Tbulk,'String','Tbulk [ms] | Tdiff [ms]'); +0735 set(gui.text_handles.petro_rho,'String',[char(hex2dec('03C1')),' [µm/s] | geom ']); +0736 end +0737 +0738 end +0739 +0740 function gui = updateInvstdTime(gui,invtype,time,Ntime) +0741 +0742 switch invtype +0743 +0744 case {'mono','free'} +0745 set(gui.edit_handles.invstd_time_min,'Enable','off'); +0746 set(gui.edit_handles.invstd_time_max,'Enable','off'); +0747 set(gui.edit_handles.invstd_Ntime,'Enable','off'); +0748 +0749 case {'LU','NNLS','MUMO'} +0750 set(gui.edit_handles.invstd_time_min,'Enable','on','String',num2str(time(1))); +0751 set(gui.edit_handles.invstd_time_max,'Enable','on','String',num2str(time(2))); +0752 set(gui.edit_handles.invstd_Ntime,'Enable','on','String',num2str(Ntime)); +0753 end +0754 +0755 end +0756 +0757 function gui = updateInvjointRadii(gui,invtype,radii,Nradii) +0758 +0759 switch invtype +0760 case {'fixed','shape','off'} +0761 set(gui.edit_handles.invjoint_radii_min,'Enable','off'); +0762 set(gui.edit_handles.invjoint_radii_max,'Enable','off'); +0763 set(gui.edit_handles.invjoint_Nradii,'Enable','off'); +0764 +0765 case {'free'} +0766 set(gui.edit_handles.invjoint_radii_min,'Enable','on','String',num2str(radii(1))); +0767 set(gui.edit_handles.invjoint_radii_max,'Enable','on','String',num2str(radii(2))); +0768 set(gui.edit_handles.invjoint_Nradii,'Enable','on','String',num2str(Nradii)); +0769 end +0770 +0771 end +0772 +0773 function gui = updateLambda(gui,regtype,lambda,lambdaR,NlambdaR) +0774 +0775 switch regtype +0776 case 'none' +0777 set(gui.edit_handles.invstd_lambda_min,'Enable','off'); +0778 set(gui.edit_handles.invstd_lambda_max,'Enable','off'); +0779 set(gui.edit_handles.invstd_NlambdaR,'Enable','off'); +0780 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; +0781 +0782 case 'manual' +0783 set(gui.edit_handles.invstd_lambda_min,'Enable','on','String',num2str(lambda)); +0784 set(gui.edit_handles.invstd_lambda_max,'Enable','off'); +0785 set(gui.edit_handles.invstd_NlambdaR,'Enable','off'); +0786 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; +0787 +0788 case 'auto' +0789 set(gui.edit_handles.invstd_lambda_min,'Enable','off','String',num2str(lambda)); +0790 set(gui.edit_handles.invstd_lambda_max,'Enable','off'); +0791 set(gui.edit_handles.invstd_NlambdaR,'Enable','off'); +0792 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; +0793 +0794 case 'lcurve' +0795 set(gui.edit_handles.invstd_lambda_min,'Enable','on','String',num2str(lambdaR(1))); +0796 set(gui.edit_handles.invstd_lambda_max,'Enable','on','String',num2str(lambdaR(2))); +0797 set(gui.edit_handles.invstd_NlambdaR,'Enable','on','String',num2str(NlambdaR)); +0798 gui.plots.DistPanel.TabTitles = {'L-CURVE','RMS','PSD (joint)'}; 0799 -0800 case 'lcurve' -0801 set(gui.edit_handles.invjoint_lambda_min,'Enable','on','String',num2str(lambdaR(1))); -0802 set(gui.edit_handles.invjoint_lambda_max,'Enable','on','String',num2str(lambdaR(2))); -0803 set(gui.edit_handles.invjoint_NlambdaR,'Enable','on','String',num2str(NlambdaR)); -0804 gui.plots.DistPanel.TabTitles = {'L-CURVE','RMS','PSD (joint)'}; +0800 case {'gcv_tikh','gcv_trunc','gcv_damp','discrep'} +0801 set(gui.edit_handles.invstd_lambda_min,'Enable','off','String',num2str(lambda)); +0802 set(gui.edit_handles.invstd_lambda_max,'Enable','off'); +0803 set(gui.edit_handles.invstd_NlambdaR,'Enable','off'); +0804 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; 0805 end 0806 0807 end 0808 -0809 function gui = updateLorder(gui,invtype,Lorder) +0809 function gui = updateLambdaJoint(gui,regtype,lambda,lambdaR,NlambdaR,regtypestd) 0810 -0811 switch invtype -0812 case {'mono','free'} -0813 set(gui.radio_handles.invstd_Lorder0,'Enable','off'); -0814 set(gui.radio_handles.invstd_Lorder1,'Enable','off'); -0815 set(gui.radio_handles.invstd_Lorder2,'Enable','off'); -0816 -0817 case {'LU','NNLS'} -0818 set(gui.radio_handles.invstd_Lorder0,'Enable','on'); -0819 set(gui.radio_handles.invstd_Lorder1,'Enable','on'); -0820 set(gui.radio_handles.invstd_Lorder2,'Enable','on'); -0821 -0822 switch Lorder -0823 case 0 -0824 set(gui.radio_handles.invstd_Lorder0,'Value',1); -0825 set(gui.radio_handles.invstd_Lorder1,'Value',0); -0826 set(gui.radio_handles.invstd_Lorder2,'Value',0); -0827 -0828 case 1 -0829 set(gui.radio_handles.invstd_Lorder0,'Value',0); -0830 set(gui.radio_handles.invstd_Lorder1,'Value',1); -0831 set(gui.radio_handles.invstd_Lorder2,'Value',0); -0832 -0833 case 2 -0834 set(gui.radio_handles.invstd_Lorder0,'Value',0); -0835 set(gui.radio_handles.invstd_Lorder1,'Value',0); -0836 set(gui.radio_handles.invstd_Lorder2,'Value',1); -0837 end -0838 end -0839 -0840 end -0841 -0842 function gui = updateLorderJoint(gui,invtype,Lorder) -0843 -0844 switch invtype -0845 case {'fixed','shape','off'} -0846 set(gui.radio_handles.invjoint_Lorder0,'Enable','off'); -0847 set(gui.radio_handles.invjoint_Lorder1,'Enable','off'); -0848 set(gui.radio_handles.invjoint_Lorder2,'Enable','off'); -0849 -0850 case 'free' -0851 set(gui.radio_handles.invjoint_Lorder0,'Enable','on'); -0852 set(gui.radio_handles.invjoint_Lorder1,'Enable','on'); -0853 set(gui.radio_handles.invjoint_Lorder2,'Enable','on'); -0854 -0855 switch Lorder -0856 case 0 -0857 set(gui.radio_handles.invjoint_Lorder0,'Value',1); -0858 set(gui.radio_handles.invjoint_Lorder1,'Value',0); -0859 set(gui.radio_handles.invjoint_Lorder2,'Value',0); -0860 -0861 case 1 -0862 set(gui.radio_handles.invjoint_Lorder0,'Value',0); -0863 set(gui.radio_handles.invjoint_Lorder1,'Value',1); -0864 set(gui.radio_handles.invjoint_Lorder2,'Value',0); -0865 -0866 case 2 -0867 set(gui.radio_handles.invjoint_Lorder0,'Value',0); -0868 set(gui.radio_handles.invjoint_Lorder1,'Value',0); -0869 set(gui.radio_handles.invjoint_Lorder2,'Value',1); -0870 end -0871 end -0872 -0873 end -0874 -0875 function gui = updateParams(gui,invtype,p) -0876 -0877 switch invtype -0878 case {'mono','free'} -0879 set(gui.edit_handles.param_CBW,'Enable','off','String',num2str(p.CBWcutoff)); -0880 set(gui.edit_handles.param_BVI,'Enable','off','String',num2str(p.BVIcutoff)); -0881 set(gui.edit_handles.param_rho,'Enable','on','String',num2str(p.rho)); -0882 set(gui.edit_handles.param_geom,'Enable','on','String',num2str(p.a)); -0883 -0884 case {'LU','NNLS'} -0885 set(gui.edit_handles.param_CBW,'Enable','on','String',num2str(p.CBWcutoff)); -0886 set(gui.edit_handles.param_BVI,'Enable','on','String',num2str(p.BVIcutoff)); -0887 set(gui.edit_handles.param_rho,'Enable','on','String',num2str(p.rho)); -0888 set(gui.edit_handles.param_geom,'Enable','on','String',num2str(p.a)); -0889 -0890 end -0891 set(gui.edit_handles.param_calibVol,'Enable','on','String',num2str(p.calibVol)); -0892 set(gui.edit_handles.param_calibAmp,'Enable','on','String',num2str(p.calibAmp)); -0893 set(gui.edit_handles.param_sampVol,'Enable','on','String',num2str(p.sampVol)); -0894 -0895 end -0896 -0897 %------------- END OF CODE -------------- -0898 -0899 %% License: -0900 % MIT License -0901 % -0902 % Copyright (c) 2018 Thomas Hiller -0903 % -0904 % Permission is hereby granted, free of charge, to any person obtaining a copy -0905 % of this software and associated documentation files (the "Software"), to deal -0906 % in the Software without restriction, including without limitation the rights -0907 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0908 % copies of the Software, and to permit persons to whom the Software is -0909 % furnished to do so, subject to the following conditions: -0910 % -0911 % The above copyright notice and this permission notice shall be included in all -0912 % copies or substantial portions of the Software. -0913 % -0914 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0915 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0916 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0917 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0918 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0919 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0920 % SOFTWARE. +0811 switch regtype +0812 case 'none' +0813 switch regtypestd +0814 case 'lcurve' +0815 set(gui.edit_handles.invjoint_lambda_min,'Enable','off'); +0816 set(gui.edit_handles.invjoint_lambda_max,'Enable','off'); +0817 set(gui.edit_handles.invjoint_NlambdaR,'Enable','off'); +0818 gui.plots.DistPanel.TabTitles = {'L-CURVE','RMS','PSD (joint)'}; +0819 +0820 otherwise +0821 set(gui.edit_handles.invjoint_lambda_min,'Enable','off'); +0822 set(gui.edit_handles.invjoint_lambda_max,'Enable','off'); +0823 set(gui.edit_handles.invjoint_NlambdaR,'Enable','off'); +0824 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; +0825 end +0826 +0827 case 'manual' +0828 switch regtypestd +0829 case 'lcurve' +0830 set(gui.edit_handles.invjoint_lambda_min,'Enable','on','String',num2str(lambda)); +0831 set(gui.edit_handles.invjoint_lambda_max,'Enable','off'); +0832 set(gui.edit_handles.invjoint_NlambdaR,'Enable','off'); +0833 gui.plots.DistPanel.TabTitles = {'L-CURVE','RMS','PSD (joint)'}; +0834 +0835 otherwise +0836 set(gui.edit_handles.invjoint_lambda_min,'Enable','on','String',num2str(lambda)); +0837 set(gui.edit_handles.invjoint_lambda_max,'Enable','off'); +0838 set(gui.edit_handles.invjoint_NlambdaR,'Enable','off'); +0839 gui.plots.DistPanel.TabTitles = {'RTD','PSD','PSD (joint)'}; +0840 end +0841 +0842 case 'lcurve' +0843 set(gui.edit_handles.invjoint_lambda_min,'Enable','on','String',num2str(lambdaR(1))); +0844 set(gui.edit_handles.invjoint_lambda_max,'Enable','on','String',num2str(lambdaR(2))); +0845 set(gui.edit_handles.invjoint_NlambdaR,'Enable','on','String',num2str(NlambdaR)); +0846 gui.plots.DistPanel.TabTitles = {'L-CURVE','RMS','PSD (joint)'}; +0847 end +0848 +0849 end +0850 +0851 function gui = updateLorder(gui,invtype,Lorder) +0852 +0853 switch invtype +0854 case {'mono','free','MUMO'} +0855 set(gui.radio_handles.invstd_Lorder0,'Enable','off'); +0856 set(gui.radio_handles.invstd_Lorder1,'Enable','off'); +0857 set(gui.radio_handles.invstd_Lorder2,'Enable','off'); +0858 +0859 case {'LU','NNLS'} +0860 set(gui.radio_handles.invstd_Lorder0,'Enable','on'); +0861 set(gui.radio_handles.invstd_Lorder1,'Enable','on'); +0862 set(gui.radio_handles.invstd_Lorder2,'Enable','on'); +0863 +0864 switch Lorder +0865 case 0 +0866 set(gui.radio_handles.invstd_Lorder0,'Value',1); +0867 set(gui.radio_handles.invstd_Lorder1,'Value',0); +0868 set(gui.radio_handles.invstd_Lorder2,'Value',0); +0869 +0870 case 1 +0871 set(gui.radio_handles.invstd_Lorder0,'Value',0); +0872 set(gui.radio_handles.invstd_Lorder1,'Value',1); +0873 set(gui.radio_handles.invstd_Lorder2,'Value',0); +0874 +0875 case 2 +0876 set(gui.radio_handles.invstd_Lorder0,'Value',0); +0877 set(gui.radio_handles.invstd_Lorder1,'Value',0); +0878 set(gui.radio_handles.invstd_Lorder2,'Value',1); +0879 end +0880 end +0881 +0882 end +0883 +0884 function gui = updateLorderJoint(gui,invtype,Lorder) +0885 +0886 switch invtype +0887 case {'fixed','shape','off'} +0888 set(gui.radio_handles.invjoint_Lorder0,'Enable','off'); +0889 set(gui.radio_handles.invjoint_Lorder1,'Enable','off'); +0890 set(gui.radio_handles.invjoint_Lorder2,'Enable','off'); +0891 +0892 case 'free' +0893 set(gui.radio_handles.invjoint_Lorder0,'Enable','on'); +0894 set(gui.radio_handles.invjoint_Lorder1,'Enable','on'); +0895 set(gui.radio_handles.invjoint_Lorder2,'Enable','on'); +0896 +0897 switch Lorder +0898 case 0 +0899 set(gui.radio_handles.invjoint_Lorder0,'Value',1); +0900 set(gui.radio_handles.invjoint_Lorder1,'Value',0); +0901 set(gui.radio_handles.invjoint_Lorder2,'Value',0); +0902 +0903 case 1 +0904 set(gui.radio_handles.invjoint_Lorder0,'Value',0); +0905 set(gui.radio_handles.invjoint_Lorder1,'Value',1); +0906 set(gui.radio_handles.invjoint_Lorder2,'Value',0); +0907 +0908 case 2 +0909 set(gui.radio_handles.invjoint_Lorder0,'Value',0); +0910 set(gui.radio_handles.invjoint_Lorder1,'Value',0); +0911 set(gui.radio_handles.invjoint_Lorder2,'Value',1); +0912 end +0913 end +0914 +0915 end +0916 +0917 function gui = updateParams(gui,invtype,p) +0918 +0919 switch invtype +0920 case {'mono','free'} +0921 set(gui.edit_handles.param_CBW,'Enable','off','String',num2str(p.CBWcutoff)); +0922 set(gui.edit_handles.param_BVI,'Enable','off','String',num2str(p.BVIcutoff)); +0923 set(gui.edit_handles.param_rho,'Enable','on','String',num2str(p.rho)); +0924 set(gui.edit_handles.param_geom,'Enable','on','String',num2str(p.a)); +0925 +0926 case {'LU','NNLS','MUMO'} +0927 set(gui.edit_handles.param_CBW,'Enable','on','String',num2str(p.CBWcutoff)); +0928 set(gui.edit_handles.param_BVI,'Enable','on','String',num2str(p.BVIcutoff)); +0929 set(gui.edit_handles.param_rho,'Enable','on','String',num2str(p.rho)); +0930 set(gui.edit_handles.param_geom,'Enable','on','String',num2str(p.a)); +0931 +0932 end +0933 set(gui.edit_handles.param_calibVol,'Enable','on','String',num2str(p.calibVol)); +0934 set(gui.edit_handles.param_calibAmp,'Enable','on','String',num2str(p.calibAmp)); +0935 set(gui.edit_handles.param_sampVol,'Enable','on','String',num2str(p.sampVol)); +0936 +0937 end +0938 +0939 %------------- END OF CODE -------------- +0940 +0941 %% License: +0942 % MIT License +0943 % +0944 % Copyright (c) 2018 Thomas Hiller +0945 % +0946 % Permission is hereby granted, free of charge, to any person obtaining a copy +0947 % of this software and associated documentation files (the "Software"), to deal +0948 % in the Software without restriction, including without limitation the rights +0949 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0950 % copies of the Software, and to permit persons to whom the Software is +0951 % furnished to do so, subject to the following conditions: +0952 % +0953 % The above copyright notice and this permission notice shall be included in all +0954 % copies or substantial portions of the Software. +0955 % +0956 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0957 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0958 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0959 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0960 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0961 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0962 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod.html index c90580d..5df6cac 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod.html @@ -57,8 +57,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0031 % 0032 % See also: NUCLEUSinv -0033 % Author: Thomas Hiller -0034 % email: thomas.hiller[at]leibniz-liag.de +0033 % Author: see AUTHORS.md +0034 % email: see AUTHORS.md 0035 % License: MIT License (at end) 0036 0037 %------------- BEGIN CODE -------------- @@ -117,10 +117,10 @@

    SOURCE CODE ^if ~isempty(h0); close(h0); end 0042 0043 %% GUI 'header' info and defaults -0044 myui.version = '0.1.11'; -0045 myui.date = '12.03.2021'; -0046 myui.author = {'Thomas Hiller','Stephan Costabel'}; -0047 myui.email = 'thomas.hiller[at]leibniz-liag.de'; +0044 myui.version = '0.1.12'; +0045 myui.date = '17.02.2022'; +0046 myui.author = {'Stephan Costabel','Thomas Hiller'}; +0047 myui.email = 'thomas.hiller[at]bgr.de'; 0048 myui.fontsize = 10; 0049 0050 %% Default data settings diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createGUI.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createGUI.html index 98300ce..5e7becf 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createGUI.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createGUI.html @@ -56,15 +56,15 @@

    DESCRIPTION ^NUCLEUSmod - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end)

    CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • NUCLEUSmod_createMenus creates all GUI menus
  • NUCLEUSmod_createPanelCPS creates pressure panel
  • NUCLEUSmod_createPanelGeometry creates geometry panel
  • NUCLEUSmod_createPanelNMR creates NMR panel
  • NUCLEUSmod_createPanelPlots creates graphics panel
  • NUCLEUSmod_createStatusbar creates status bar
  • displayStatusText shows status information either in the GUI or on the
  • fixAxes fixes an ugly Matlab bug when resizing a box-panel which holds an
  • minimizePanel handles the minimization/maximization of all box-panels for
  • updateStatusInformation updates all fields inside the bottom status bar
  • This function is called by:
    • NUCLEUSmod is a graphical user interface (GUI) to forward model NMR
    @@ -104,8 +104,8 @@

    SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSmod -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createMenus.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createMenus.html index d05ba64..5f91bb1 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createMenus.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createMenus.html @@ -50,8 +50,8 @@

    DESCRIPTION ^NUCLEUSmod - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -92,8 +92,8 @@

    SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelCPS.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelCPS.html index ac3d7c7..7ee5e7a 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelCPS.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelCPS.html @@ -51,8 +51,8 @@

    DESCRIPTION ^NUCLEUSmod - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelGeometry.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelGeometry.html index 7932573..cafe391 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelGeometry.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelGeometry.html @@ -51,8 +51,8 @@

    DESCRIPTION ^NUCLEUSmod - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelNMR.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelNMR.html index 264bb6a..856520a 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelNMR.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelNMR.html @@ -51,15 +51,15 @@

    DESCRIPTION ^NUCLEUSmod - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end)

    CROSS-REFERENCE INFORMATION ^

    This function calls:
      -
    • onEditValue updates all edit field values, checks for wrong inputs and
    • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
    +
  • onEditValue updates all edit field values, checks for wrong inputs and
  • onPopupNMRNoiseType selects the noise type to be aplied to the forward
  • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
  • This function is called by: @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- @@ -104,10 +104,10 @@

    SOURCE CODE ^'Parent',gui.panels.nmr.main,... 0035 'Spacing',3,'Padding',3); 0036 -0037 % Tbulk & surface relaxivity rho +0037 % Tbulk & Tdiff 0038 gui.panels.nmr.HBox1 = uix.HBox('Parent',gui.panels.nmr.VBox,... 0039 'Spacing',3); -0040 % echo time TE & number of echos +0040 % surface relaxivity rho & echo time TE & number of echos 0041 gui.panels.nmr.HBox2 = uix.HBox('Parent',gui.panels.nmr.VBox,... 0042 'Spacing',3); 0043 % RUN button @@ -117,131 +117,145 @@

    SOURCE CODE ^'Parent',gui.panels.nmr.VBox,... 0048 'Spacing',3); 0049 -0050 %% Tbulk & surface relaxivity rho +0050 %% Tbulk & Tdiff 0051 gui.text_handles.Tbulk = uicontrol('Parent',gui.panels.nmr.HBox1,... 0052 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0053 'String','Tbulk [s]'); -0054 tstr = ['<HTML>Set relaxation time of bulk water.<br><br>',... -0055 '<u>Default value:</u><br>',... -0056 '<b>2 s</b><br>']; -0057 gui.edit_handles.Tbulk = uicontrol('Parent',gui.panels.nmr.HBox1,... -0058 'Style','edit','String',num2str(data.nmr.Tbulk),'FontSize',myui.fontsize,... -0059 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.Tbulk 1 1]),... -0060 'Tag','nmr_Tbulk','Enable','on','Callback',@onEditValue); -0061 gui.text_handles.rho = uicontrol('Parent',gui.panels.nmr.HBox1,... -0062 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0063 'String',[char(hex2dec('03C1')),' [µm/s]']); -0064 tstr = ['<HTML>Set surface relaxivity &rho .<br><br>',... -0065 '<u>Default value:</u><br>',... -0066 '<b>10 µm/s</b><br>']; -0067 gui.edit_handles.rho = uicontrol('Parent',gui.panels.nmr.HBox1,... -0068 'Style','edit','String',num2str(data.nmr.rho),'FontSize',myui.fontsize,... -0069 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.rho 1 1]),... -0070 'Tag','nmr_rho','Enable','on','Callback',@onEditValue); -0071 set(gui.panels.nmr.HBox1,'Widths',[100 -1 100 -1]); -0072 -0073 %% echo time TE & number of echoes -0074 gui.text_handles.TE = uicontrol('Parent',gui.panels.nmr.HBox2,... -0075 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0076 'String','echo time [µs]'); -0077 tstr = ['<HTML>Set echo time.<br><br>',... -0078 '<u>Default value:</u><br>',... -0079 '<b>1000 µs</b><br>']; -0080 gui.edit_handles.TE = uicontrol('Parent',gui.panels.nmr.HBox2,... -0081 'Style','edit','String',num2str(data.nmr.TE),'FontSize',myui.fontsize,... -0082 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.TE 1 1]),... -0083 'Tag','nmr_TE','Enable','on','Callback',@onEditValue); -0084 gui.text_handles.echosN = uicontrol('Parent',gui.panels.nmr.HBox2,... -0085 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0086 'String','# echoes'); -0087 tstr = ['<HTML>Set number of echoes.<br><br>',... -0088 '<u>Default value:</u><br>',... -0089 '<b>1001</b><br>']; -0090 gui.edit_handles.echosN = uicontrol('Parent',gui.panels.nmr.HBox2,... -0091 'Style','edit','String',num2str(data.nmr.echosN),'FontSize',myui.fontsize,... -0092 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.echosN 1 1]),... -0093 'Tag','nmr_echosN','Enable','on','Callback',@onEditValue); -0094 set(gui.panels.nmr.HBox2,'Widths',[100 -1 100 -1]); -0095 -0096 %% RUN button -0097 gui.text_handles.nmr_RUN = uicontrol('Parent',gui.panels.nmr.HBox3,... -0098 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0099 'String','calculate NMR'); -0100 gui.push_handles.nmr_RUN = uicontrol('Parent',gui.panels.nmr.HBox3,... -0101 'Style','pushbutton','String','RUN','FontSize',myui.fontsize,'Tag','nmr',... -0102 'BackgroundColor','g','Enable','on','Callback',@onPushRun); -0103 set(gui.panels.nmr.HBox3,'Widths',[200 -1]); -0104 -0105 %% noise & porosity -0106 gui.text_handles.noise = uicontrol('Parent',gui.panels.nmr.HBox4,... -0107 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0108 'String','add noise'); -0109 tstr = ['<HTML>Set NMR data noise.<br><br>',... -0110 '<u>Hint:</u><br>',... -0111 'You do not need to press RUN to add noise to the NMR signals.<br>',... -0112 'The raw NMR signals are stored internally and the noise is<br>',... -0113 'applied instantaneously.<br><br>',... -0114 '<u>Default value:</u><br>',... -0115 '<b>0</b><br>']; -0116 gui.edit_handles.noise = uicontrol('Parent',gui.panels.nmr.HBox4,... -0117 'Style','edit','String',num2str(data.nmr.noise),'FontSize',myui.fontsize,... -0118 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.noise 1 1]),... -0119 'Tag','nmr_noise','Enable','on','Callback',@onEditValue); -0120 gui.text_handles.porosity = uicontrol('Parent',gui.panels.nmr.HBox4,... -0121 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... -0122 'String','porosity'); -0123 tstr = ['<HTML>Set porosity value in the range [0, 1].<br><br>',... -0124 '<u>Note:</u><br>',... -0125 'This value is applied only as a scaling factor to the NMR amplitudes.<br>',... -0126 'Hence, saturation becomes water content.']; -0127 gui.edit_handles.porosity = uicontrol('Parent',gui.panels.nmr.HBox4,... -0128 'Style','edit','String',num2str(data.nmr.porosity),'FontSize',myui.fontsize,... -0129 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.porosity 1 1]),... -0130 'Tag','nmr_porosity','Enable','on','Callback',@onEditValue); -0131 set(gui.panels.nmr.HBox4,'Widths',[100 -1 100 -1]); -0132 -0133 %% Java Hack to adjust vertical alignment of text fields -0134 jh = findjobj(gui.text_handles.Tbulk); -0135 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0136 jh = findjobj(gui.text_handles.rho); -0137 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0138 jh = findjobj(gui.text_handles.TE ); -0139 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0140 jh = findjobj(gui.text_handles.echosN ); -0141 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0142 jh = findjobj(gui.text_handles.nmr_RUN); -0143 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0144 jh = findjobj(gui.text_handles.noise); -0145 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0146 jh = findjobj(gui.text_handles.porosity); -0147 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); -0148 -0149 return -0150 -0151 %------------- END OF CODE -------------- +0053 'String','Tbulk [s] | Tdiff [s]'); +0054 tstr = ['<HTML>Bulk relaxation time in [s].<br><br>',... +0055 '1/T = 1/Ts + 1/<b>Tb</b> + 1/Td<br><br>',... +0056 '<u>Default value:</u><br>',... +0057 '<b>2</b><br>']; +0058 gui.edit_handles.Tbulk = uicontrol('Parent',gui.panels.nmr.HBox1,... +0059 'Style','edit','String',num2str(data.nmr.Tbulk),'FontSize',myui.fontsize,... +0060 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.Tbulk 1 1]),... +0061 'Tag','nmr_Tbulk','Enable','on','Callback',@onEditValue); +0062 tstr = ['<HTML>Diffusion relaxation time in [s].<br><br>',... +0063 '1/T = 1/Ts + 1/Tb + 1/<b>Td</b><br><br>',... +0064 '<b>Td</b> can be caluclated by<br><br>',... +0065 '<b>Td</b> = 12 / (D*(',char(hex2dec('03B3')),'*G*TE)<sup>2</sup> )<br><br>',... +0066 'with<br><br>',... +0067 'D = diffusion coefficent of water<br>',... +0068 char(hex2dec('03B3')),' = gyromagnetic ratio of hydrogen<br>',... +0069 'G = magnetic gradient<br>',... +0070 'TE = echo time<br><br>',... +0071 '<u>Default value:</u><br>',... +0072 '<b>1e6</b> (so that 1/<b>Td</b> is ignored)<br>']; +0073 gui.edit_handles.Tdiff = uicontrol('Parent',gui.panels.nmr.HBox1,... +0074 'Style','edit','String',num2str(data.nmr.Tdiff),'FontSize',myui.fontsize,... +0075 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.Tdiff 1 1]),... +0076 'Tag','nmr_Tdiff','Enable','on','Callback',@onEditValue); +0077 set(gui.panels.nmr.HBox1,'Widths',[200 -1 -1]); +0078 +0079 %% surface relaxivity rho & echo time TE & number of echoes +0080 gui.text_handles.rho = uicontrol('Parent',gui.panels.nmr.HBox2,... +0081 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... +0082 'String',[char(hex2dec('03C1')),' [µm/s] | TE [µs] | # echoes']); +0083 tstr = ['<HTML>Surface relaxivity in [µm/s].<br><br>',... +0084 '1/Ts = <b>rho</b>*S/V = <b>rho</b>*a/R.<br><br>',... +0085 '<u>Default value:</u><br>',... +0086 '<b>10</b><br>']; +0087 gui.edit_handles.rho = uicontrol('Parent',gui.panels.nmr.HBox2,... +0088 'Style','edit','String',num2str(data.nmr.rho),'FontSize',myui.fontsize,... +0089 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.rho 1 1]),... +0090 'Tag','nmr_rho','Enable','on','Callback',@onEditValue); +0091 tstr = ['<HTML>Echo time TE in [µs].<br><br>',... +0092 '<u>Default value:</u><br>',... +0093 '<b>1000</b><br>']; +0094 gui.edit_handles.TE = uicontrol('Parent',gui.panels.nmr.HBox2,... +0095 'Style','edit','String',num2str(data.nmr.TE),'FontSize',myui.fontsize,... +0096 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.TE 1 1]),... +0097 'Tag','nmr_TE','Enable','on','Callback',@onEditValue); +0098 tstr = ['<HTML>Number of echoes.<br><br>',... +0099 '<u>Default value:</u><br>',... +0100 '<b>1001</b><br>']; +0101 gui.edit_handles.echosN = uicontrol('Parent',gui.panels.nmr.HBox2,... +0102 'Style','edit','String',num2str(data.nmr.echosN),'FontSize',myui.fontsize,... +0103 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.echosN 1 1]),... +0104 'Tag','nmr_echosN','Enable','on','Callback',@onEditValue); +0105 set(gui.panels.nmr.HBox2,'Widths',[200 -1 -1 -1]); +0106 +0107 %% RUN button +0108 gui.text_handles.nmr_RUN = uicontrol('Parent',gui.panels.nmr.HBox3,... +0109 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... +0110 'String','calculate NMR'); +0111 gui.push_handles.nmr_RUN = uicontrol('Parent',gui.panels.nmr.HBox3,... +0112 'Style','pushbutton','String','RUN','FontSize',myui.fontsize,'Tag','nmr',... +0113 'BackgroundColor','g','Enable','on','Callback',@onPushRun); +0114 set(gui.panels.nmr.HBox3,'Widths',[200 -1]); +0115 +0116 %% noise & porosity +0117 +0118 tstr = ['<HTML>NMR data noise method.<br><br>',... +0119 'A noise level will be used globally for all NMR signals.<br>',... +0120 'A signal-to-ratio will be used individually on every single NMR signal.<br><br>',... +0121 '<u>Available options:</u><br>',... +0122 '<b>noise level</b> or <b>SNR</b> <br><br>',... +0123 '<u>Default value:</u><br>',... +0124 '<b>noise level</b> <br>']; +0125 gui.popup_handles.noisetype = uicontrol('Parent',gui.panels.nmr.HBox4,... +0126 'Style','popup','String',{'noise level','SNR'},... +0127 'Value',1,'FontSize',myui.fontsize,'UserData',struct('Tooltipstr',tstr),... +0128 'Callback',@onPopupNMRNoiseType); +0129 tstr = ['<HTML>NMR data noise.<br><br>',... +0130 '<u>Hint:</u><br>',... +0131 'You do not need to press RUN to add noise to the NMR signals.<br>',... +0132 'The raw NMR signals are stored internally and the noise is<br>',... +0133 'applied instantaneously.<br><br>',... +0134 '<u>Default value:</u><br>',... +0135 '<b>0</b><br>']; +0136 gui.edit_handles.noise = uicontrol('Parent',gui.panels.nmr.HBox4,... +0137 'Style','edit','String',num2str(data.nmr.noise),'FontSize',myui.fontsize,... +0138 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.noise 1 1]),... +0139 'Tag','nmr_noise','Enable','on','Callback',@onEditValue); +0140 gui.text_handles.porosity = uicontrol('Parent',gui.panels.nmr.HBox4,... +0141 'Style','text','FontSize',myui.fontsize,'HorizontalAlignment','center',... +0142 'String','porosity'); +0143 tstr = ['<HTML>Porosity value in the range [0, 1].<br><br>',... +0144 '<u>Note:</u><br>',... +0145 'This value is applied only as a scaling factor to the NMR amplitudes.<br>',... +0146 'Hence, saturation becomes water content.']; +0147 gui.edit_handles.porosity = uicontrol('Parent',gui.panels.nmr.HBox4,... +0148 'Style','edit','String',num2str(data.nmr.porosity),'FontSize',myui.fontsize,... +0149 'UserData',struct('Tooltipstr',tstr,'defaults',[data.nmr.porosity 1 1]),... +0150 'Tag','nmr_porosity','Enable','on','Callback',@onEditValue); +0151 set(gui.panels.nmr.HBox4,'Widths',[100 -1 100 -1]); 0152 -0153 %% License: -0154 % MIT License -0155 % -0156 % Copyright (c) 2018 Thomas Hiller -0157 % -0158 % Permission is hereby granted, free of charge, to any person obtaining a copy -0159 % of this software and associated documentation files (the "Software"), to deal -0160 % in the Software without restriction, including without limitation the rights -0161 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0162 % copies of the Software, and to permit persons to whom the Software is -0163 % furnished to do so, subject to the following conditions: -0164 % -0165 % The above copyright notice and this permission notice shall be included in all -0166 % copies or substantial portions of the Software. -0167 % -0168 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0169 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0170 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0171 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0172 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0173 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0174 % SOFTWARE. +0153 %% Java Hack to adjust vertical alignment of text fields +0154 jh = findjobj(gui.text_handles.Tbulk); +0155 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0156 jh = findjobj(gui.text_handles.rho); +0157 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0158 jh = findjobj(gui.text_handles.nmr_RUN); +0159 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0160 jh = findjobj(gui.text_handles.porosity); +0161 jh.setVerticalAlignment(javax.swing.JLabel.CENTER); +0162 +0163 return +0164 +0165 %------------- END OF CODE -------------- +0166 +0167 %% License: +0168 % MIT License +0169 % +0170 % Copyright (c) 2018 Thomas Hiller +0171 % +0172 % Permission is hereby granted, free of charge, to any person obtaining a copy +0173 % of this software and associated documentation files (the "Software"), to deal +0174 % in the Software without restriction, including without limitation the rights +0175 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0176 % copies of the Software, and to permit persons to whom the Software is +0177 % furnished to do so, subject to the following conditions: +0178 % +0179 % The above copyright notice and this permission notice shall be included in all +0180 % copies or substantial portions of the Software. +0181 % +0182 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0183 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0184 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0185 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0186 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0187 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0188 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelPlots.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelPlots.html index e4bf449..92a0435 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelPlots.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createPanelPlots.html @@ -51,8 +51,8 @@

    DESCRIPTION ^NUCLEUSmod - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createStatusbar.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createStatusbar.html index 8d34348..c94ce91 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createStatusbar.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_createStatusbar.html @@ -90,8 +90,8 @@

    SOURCE CODE ^% 0025 % See also: NUCLEUSmod 0026 -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 0030 %------------- BEGIN CODE -------------- 0031 diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_loadDefaults.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_loadDefaults.html index 167b3d3..fd4e9d6 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_loadDefaults.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_loadDefaults.html @@ -48,8 +48,8 @@

    DESCRIPTION ^NUCLEUSmod - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -88,8 +88,8 @@

    SOURCE CODE ^% none 0022 % 0023 % See also: NUCLEUSmod -0024 % Author: Thomas Hiller -0025 % email: thomas.hiller[at]leibniz-liag.de +0024 % Author: see AUTHORS.md +0025 % email: see AUTHORS.md 0026 % License: MIT License (at end) 0027 0028 %------------- BEGIN CODE -------------- @@ -140,47 +140,51 @@

    SOURCE CODE ^% number of echoes 0075 out.nmr.echosN = 1001; -0076 % noise level [%] -0077 out.nmr.noise = 0; -0078 % water bulk relaxation time [s] -0079 out.nmr.Tbulk = 2; -0080 % surface relaxivity [µm/s] -0081 out.nmr.rho = 10; -0082 % porosity value between 0 and 1 [-] -0083 out.nmr.porosity = 1; -0084 % plot T2 data as default -0085 out.nmr.toplot = 'T2'; -0086 % use linear x-axes as default (log=1, lin=2) -0087 out.nmr.loglinx = 2; -0088 % use linear y-axes as default (log=1, lin=2) -0089 out.nmr.logliny = 2; -0090 -0091 return -0092 -0093 %------------- END OF CODE -------------- +0076 % noise creation type 'level' or 'SNR' +0077 out.nmr.noisetype = 'level'; +0078 % noise level [0:1] or SNR [-] +0079 out.nmr.noise = 0; +0080 % water bulk relaxation time [s] +0081 out.nmr.Tbulk = 2; +0082 % diffusion relaxation time [s] +0083 out.nmr.Tdiff = 1e6; +0084 % surface relaxivity [µm/s] +0085 out.nmr.rho = 10; +0086 % porosity value between 0 and 1 [-] +0087 out.nmr.porosity = 1; +0088 % plot T2 data as default +0089 out.nmr.toplot = 'T2'; +0090 % use linear x-axes as default (log=1, lin=2) +0091 out.nmr.loglinx = 2; +0092 % use linear y-axes as default (log=1, lin=2) +0093 out.nmr.logliny = 2; 0094 -0095 %% License: -0096 % MIT License -0097 % -0098 % Copyright (c) 2018 Thomas Hiller -0099 % -0100 % Permission is hereby granted, free of charge, to any person obtaining a copy -0101 % of this software and associated documentation files (the "Software"), to deal -0102 % in the Software without restriction, including without limitation the rights -0103 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0104 % copies of the Software, and to permit persons to whom the Software is -0105 % furnished to do so, subject to the following conditions: -0106 % -0107 % The above copyright notice and this permission notice shall be included in all -0108 % copies or substantial portions of the Software. -0109 % -0110 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0111 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0112 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0113 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0114 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0115 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0116 % SOFTWARE. +0095 return +0096 +0097 %------------- END OF CODE -------------- +0098 +0099 %% License: +0100 % MIT License +0101 % +0102 % Copyright (c) 2018 Thomas Hiller +0103 % +0104 % Permission is hereby granted, free of charge, to any person obtaining a copy +0105 % of this software and associated documentation files (the "Software"), to deal +0106 % in the Software without restriction, including without limitation the rights +0107 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0108 % copies of the Software, and to permit persons to whom the Software is +0109 % furnished to do so, subject to the following conditions: +0110 % +0111 % The above copyright notice and this permission notice shall be included in all +0112 % copies or substantial portions of the Software. +0113 % +0114 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0115 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0116 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0117 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0118 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0119 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0120 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_updateInterface.html b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_updateInterface.html index e3a4f0f..13fd8a7 100644 --- a/doc/nucleus/NUCLEUSmod/NUCLEUSmod_updateInterface.html +++ b/doc/nucleus/NUCLEUSmod/NUCLEUSmod_updateInterface.html @@ -49,8 +49,8 @@

    DESCRIPTION ^NUCLEUSmod - Author: Thomas Hiller - email: thomas.hiller[at]leibniz-liag.de + Author: see AUTHORS.md + email: see AUTHORS.md License: MIT License (at end) @@ -92,8 +92,8 @@

    SOURCE CODE ^% none 0023 % 0024 % See also: NUCLEUSmod -0025 % Author: Thomas Hiller -0026 % email: thomas.hiller[at]leibniz-liag.de +0025 % Author: see AUTHORS.md +0026 % email: see AUTHORS.md 0027 % License: MIT License (at end) 0028 0029 %------------- BEGIN CODE -------------- @@ -195,117 +195,125 @@

    SOURCE CODE ^end 0126 0127 %% update NMR panel -0128 % all edit fields -0129 set(gui.edit_handles.Tbulk,'String',num2str(data.nmr.Tbulk)); -0130 set(gui.edit_handles.rho,'String',num2str(data.nmr.rho)); -0131 set(gui.edit_handles.TE,'String',num2str(data.nmr.TE)); -0132 set(gui.edit_handles.echosN,'String',num2str(data.nmr.echosN)); -0133 set(gui.edit_handles.noise,'String',num2str(data.nmr.noise)); -0134 set(gui.edit_handles.porosity,'String',num2str(data.nmr.porosity)); +0128 % noise type +0129 switch data.nmr.noisetype +0130 case 'level' % noise level +0131 set(gui.popup_handles.noisetype,'Value',1); +0132 case 'SNR' % signal-to-noise ratio (SNR) +0133 set(gui.popup_handles.noisetype,'Value',2); +0134 end 0135 -0136 end -0137 -0138 %% sub functions -0139 function gui = updateGeometryRange(gui,ispsd,modesN) -0140 -0141 switch ispsd -0142 case 0 % single pore -0143 set(gui.popup_handles.singlepsd,'Value',1); -0144 set(gui.edit_handles.range_min,'Enable','off'); -0145 set(gui.edit_handles.range_max,'Enable','off'); -0146 set(gui.edit_handles.rangeN,'Enable','off'); -0147 set(gui.popup_handles.modesN,'Enable','off','Value',modesN); -0148 case 1 % PSD -0149 set(gui.popup_handles.singlepsd,'Value',2); -0150 set(gui.edit_handles.range_min,'Enable','on'); -0151 set(gui.edit_handles.range_max,'Enable','on'); -0152 set(gui.edit_handles.rangeN,'Enable','on'); -0153 set(gui.popup_handles.modesN,'Enable','on','Value',modesN); -0154 end -0155 end -0156 -0157 function gui = updateGeometryModesN(gui,ispsd,modesN,modes) -0158 -0159 % set the values -0160 set(gui.edit_handles.mode1,'String',num2str(modes(1,1))); -0161 set(gui.edit_handles.sig1,'String',num2str(modes(1,2))); -0162 set(gui.edit_handles.amp1,'String',num2str(modes(1,3))); -0163 set(gui.edit_handles.mode2,'String',num2str(modes(2,1))); -0164 set(gui.edit_handles.sig2,'String',num2str(modes(2,2))); -0165 set(gui.edit_handles.amp2,'String',num2str(modes(2,3))); -0166 set(gui.edit_handles.mode3,'String',num2str(modes(3,1))); -0167 set(gui.edit_handles.sig3,'String',num2str(modes(3,2))); -0168 set(gui.edit_handles.amp3,'String',num2str(modes(3,3))); -0169 -0170 % enable / disable -0171 switch modesN -0172 case 1 -0173 switch ispsd -0174 case 0 % single pore -0175 set(gui.edit_handles.sig1,'Enable','off'); -0176 set(gui.edit_handles.amp1,'Enable','off'); -0177 set(gui.edit_handles.mode2,'Enable','off'); -0178 set(gui.edit_handles.sig2,'Enable','off'); -0179 set(gui.edit_handles.amp2,'Enable','off'); -0180 set(gui.edit_handles.mode3,'Enable','off'); -0181 set(gui.edit_handles.sig3,'Enable','off'); -0182 set(gui.edit_handles.amp3,'Enable','off'); -0183 case 1 % PSD with 1 mode -0184 set(gui.edit_handles.sig1,'Enable','on'); -0185 set(gui.edit_handles.amp1,'Enable','on'); -0186 set(gui.edit_handles.mode2,'Enable','off'); -0187 set(gui.edit_handles.sig2,'Enable','off'); -0188 set(gui.edit_handles.amp2,'Enable','off'); -0189 set(gui.edit_handles.mode3,'Enable','off'); -0190 set(gui.edit_handles.sig3,'Enable','off'); -0191 set(gui.edit_handles.amp3,'Enable','off'); -0192 end -0193 case 2 % PSD with 2 modes -0194 set(gui.edit_handles.sig1,'Enable','on'); -0195 set(gui.edit_handles.amp1,'Enable','on'); -0196 set(gui.edit_handles.mode2,'Enable','on'); -0197 set(gui.edit_handles.sig2,'Enable','on'); -0198 set(gui.edit_handles.amp2,'Enable','on'); -0199 set(gui.edit_handles.mode3,'Enable','off'); -0200 set(gui.edit_handles.sig3,'Enable','off'); -0201 set(gui.edit_handles.amp3,'Enable','off'); -0202 case 3 % PSD with 3 modes -0203 set(gui.edit_handles.sig1,'Enable','on'); -0204 set(gui.edit_handles.amp1,'Enable','on'); -0205 set(gui.edit_handles.mode2,'Enable','on'); -0206 set(gui.edit_handles.sig2,'Enable','on'); -0207 set(gui.edit_handles.amp2,'Enable','on'); -0208 set(gui.edit_handles.mode3,'Enable','on'); -0209 set(gui.edit_handles.sig3,'Enable','on'); -0210 set(gui.edit_handles.amp3,'Enable','on'); -0211 end -0212 -0213 end -0214 -0215 %------------- END OF CODE -------------- -0216 -0217 %% License: -0218 % MIT License -0219 % -0220 % Copyright (c) 2018 Thomas Hiller -0221 % -0222 % Permission is hereby granted, free of charge, to any person obtaining a copy -0223 % of this software and associated documentation files (the "Software"), to deal -0224 % in the Software without restriction, including without limitation the rights -0225 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0226 % copies of the Software, and to permit persons to whom the Software is -0227 % furnished to do so, subject to the following conditions: -0228 % -0229 % The above copyright notice and this permission notice shall be included in all -0230 % copies or substantial portions of the Software. -0231 % -0232 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0233 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0234 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0235 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0236 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0237 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0238 % SOFTWARE. +0136 % all edit fields +0137 set(gui.edit_handles.Tbulk,'String',num2str(data.nmr.Tbulk)); +0138 set(gui.edit_handles.rho,'String',num2str(data.nmr.rho)); +0139 set(gui.edit_handles.TE,'String',num2str(data.nmr.TE)); +0140 set(gui.edit_handles.echosN,'String',num2str(data.nmr.echosN)); +0141 set(gui.edit_handles.noise,'String',num2str(data.nmr.noise)); +0142 set(gui.edit_handles.porosity,'String',num2str(data.nmr.porosity)); +0143 +0144 end +0145 +0146 %% sub functions +0147 function gui = updateGeometryRange(gui,ispsd,modesN) +0148 +0149 switch ispsd +0150 case 0 % single pore +0151 set(gui.popup_handles.singlepsd,'Value',1); +0152 set(gui.edit_handles.range_min,'Enable','off'); +0153 set(gui.edit_handles.range_max,'Enable','off'); +0154 set(gui.edit_handles.rangeN,'Enable','off'); +0155 set(gui.popup_handles.modesN,'Enable','off','Value',modesN); +0156 case 1 % PSD +0157 set(gui.popup_handles.singlepsd,'Value',2); +0158 set(gui.edit_handles.range_min,'Enable','on'); +0159 set(gui.edit_handles.range_max,'Enable','on'); +0160 set(gui.edit_handles.rangeN,'Enable','on'); +0161 set(gui.popup_handles.modesN,'Enable','on','Value',modesN); +0162 end +0163 end +0164 +0165 function gui = updateGeometryModesN(gui,ispsd,modesN,modes) +0166 +0167 % set the values +0168 set(gui.edit_handles.mode1,'String',num2str(modes(1,1))); +0169 set(gui.edit_handles.sig1,'String',num2str(modes(1,2))); +0170 set(gui.edit_handles.amp1,'String',num2str(modes(1,3))); +0171 set(gui.edit_handles.mode2,'String',num2str(modes(2,1))); +0172 set(gui.edit_handles.sig2,'String',num2str(modes(2,2))); +0173 set(gui.edit_handles.amp2,'String',num2str(modes(2,3))); +0174 set(gui.edit_handles.mode3,'String',num2str(modes(3,1))); +0175 set(gui.edit_handles.sig3,'String',num2str(modes(3,2))); +0176 set(gui.edit_handles.amp3,'String',num2str(modes(3,3))); +0177 +0178 % enable / disable +0179 switch modesN +0180 case 1 +0181 switch ispsd +0182 case 0 % single pore +0183 set(gui.edit_handles.sig1,'Enable','off'); +0184 set(gui.edit_handles.amp1,'Enable','off'); +0185 set(gui.edit_handles.mode2,'Enable','off'); +0186 set(gui.edit_handles.sig2,'Enable','off'); +0187 set(gui.edit_handles.amp2,'Enable','off'); +0188 set(gui.edit_handles.mode3,'Enable','off'); +0189 set(gui.edit_handles.sig3,'Enable','off'); +0190 set(gui.edit_handles.amp3,'Enable','off'); +0191 case 1 % PSD with 1 mode +0192 set(gui.edit_handles.sig1,'Enable','on'); +0193 set(gui.edit_handles.amp1,'Enable','on'); +0194 set(gui.edit_handles.mode2,'Enable','off'); +0195 set(gui.edit_handles.sig2,'Enable','off'); +0196 set(gui.edit_handles.amp2,'Enable','off'); +0197 set(gui.edit_handles.mode3,'Enable','off'); +0198 set(gui.edit_handles.sig3,'Enable','off'); +0199 set(gui.edit_handles.amp3,'Enable','off'); +0200 end +0201 case 2 % PSD with 2 modes +0202 set(gui.edit_handles.sig1,'Enable','on'); +0203 set(gui.edit_handles.amp1,'Enable','on'); +0204 set(gui.edit_handles.mode2,'Enable','on'); +0205 set(gui.edit_handles.sig2,'Enable','on'); +0206 set(gui.edit_handles.amp2,'Enable','on'); +0207 set(gui.edit_handles.mode3,'Enable','off'); +0208 set(gui.edit_handles.sig3,'Enable','off'); +0209 set(gui.edit_handles.amp3,'Enable','off'); +0210 case 3 % PSD with 3 modes +0211 set(gui.edit_handles.sig1,'Enable','on'); +0212 set(gui.edit_handles.amp1,'Enable','on'); +0213 set(gui.edit_handles.mode2,'Enable','on'); +0214 set(gui.edit_handles.sig2,'Enable','on'); +0215 set(gui.edit_handles.amp2,'Enable','on'); +0216 set(gui.edit_handles.mode3,'Enable','on'); +0217 set(gui.edit_handles.sig3,'Enable','on'); +0218 set(gui.edit_handles.amp3,'Enable','on'); +0219 end +0220 +0221 end +0222 +0223 %------------- END OF CODE -------------- +0224 +0225 %% License: +0226 % MIT License +0227 % +0228 % Copyright (c) 2018 Thomas Hiller +0229 % +0230 % Permission is hereby granted, free of charge, to any person obtaining a copy +0231 % of this software and associated documentation files (the "Software"), to deal +0232 % in the Software without restriction, including without limitation the rights +0233 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0234 % copies of the Software, and to permit persons to whom the Software is +0235 % furnished to do so, subject to the following conditions: +0236 % +0237 % The above copyright notice and this permission notice shall be included in all +0238 % copies or substantial portions of the Software. +0239 % +0240 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0241 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0242 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0243 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0244 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0245 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0246 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/callbacks/contextmenus/onContextAxisLogLin.html b/doc/nucleus/callbacks/contextmenus/onContextAxisLogLin.html index af5e2c2..22e1853 100644 --- a/doc/nucleus/callbacks/contextmenus/onContextAxisLogLin.html +++ b/doc/nucleus/callbacks/contextmenus/onContextAxisLogLin.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSmod, NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/contextmenus/onContextAxisT1T2.html b/doc/nucleus/callbacks/contextmenus/onContextAxisT1T2.html index 3812389..f892bd7 100644 --- a/doc/nucleus/callbacks/contextmenus/onContextAxisT1T2.html +++ b/doc/nucleus/callbacks/contextmenus/onContextAxisT1T2.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/contextmenus/onContextPlotsPSD.html b/doc/nucleus/callbacks/contextmenus/onContextPlotsPSD.html index 68a1a53..903db67 100644 --- a/doc/nucleus/callbacks/contextmenus/onContextPlotsPSD.html +++ b/doc/nucleus/callbacks/contextmenus/onContextPlotsPSD.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: NUCLEUSmod -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/contextmenus/onContextPlotsPSDJ.html b/doc/nucleus/callbacks/contextmenus/onContextPlotsPSDJ.html index 26953c4..8bb1399 100644 --- a/doc/nucleus/callbacks/contextmenus/onContextPlotsPSDJ.html +++ b/doc/nucleus/callbacks/contextmenus/onContextPlotsPSDJ.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/contextmenus/onContextPlotsRTD.html b/doc/nucleus/callbacks/contextmenus/onContextPlotsRTD.html index 8ba280e..453e9a7 100644 --- a/doc/nucleus/callbacks/contextmenus/onContextPlotsRTD.html +++ b/doc/nucleus/callbacks/contextmenus/onContextPlotsRTD.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/contextmenus/onContextSignalList.html b/doc/nucleus/callbacks/contextmenus/onContextSignalList.html index 1ad11b1..9303d99 100644 --- a/doc/nucleus/callbacks/contextmenus/onContextSignalList.html +++ b/doc/nucleus/callbacks/contextmenus/onContextSignalList.html @@ -58,8 +58,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0032 % 0033 % See also: NUCLEUSinv -0034 % Author: Thomas Hiller -0035 % email: thomas.hiller[at]leibniz-liag.de +0034 % Author: see AUTHORS.md +0035 % email: see AUTHORS.md 0036 % License: MIT License (at end) 0037 0038 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/contextmenus/onContextTableSelect.html b/doc/nucleus/callbacks/contextmenus/onContextTableSelect.html index 5e85b9d..feb50c1 100644 --- a/doc/nucleus/callbacks/contextmenus/onContextTableSelect.html +++ b/doc/nucleus/callbacks/contextmenus/onContextTableSelect.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSmod -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/edits/onEditCPSTable.html b/doc/nucleus/callbacks/edits/onEditCPSTable.html index 15d6f81..ac9ce15 100644 --- a/doc/nucleus/callbacks/edits/onEditCPSTable.html +++ b/doc/nucleus/callbacks/edits/onEditCPSTable.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/edits/onEditValue.html b/doc/nucleus/callbacks/edits/onEditValue.html index 43592c7..d31956c 100644 --- a/doc/nucleus/callbacks/edits/onEditValue.html +++ b/doc/nucleus/callbacks/edits/onEditValue.html @@ -53,7 +53,6 @@

    DESCRIPTION ^DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • NUCLEUSinv_updateInterface updates all GUI elements
  • NUCLEUSmod_updateInterface updates all GUI elements
  • calculateGeometry calculates the shape dependent geometry parameters
  • calibratePorosity determines a sample's porosity from a calibration
  • clearSingleAxis clears an individual axis
  • processNMRDataControl prepares simple NMR raw data processing
  • removeCalculationFields deletes corresponding fields from NUCLEUSmod
  • removeInversionFields deletes all inversion result fields from NUCLEUSinv
  • updateInfo updates the information shown in all information list boxes
  • updateNMRsignals adds noise to the forward NMR signals and scales the
  • updatePlotsDistribution plots the RTD and PSD curves into NUCLEUSinv
  • updatePlotsSignal plots the raw and processed NMR signals in NUCLEUSinv
  • This function is called by: @@ -110,265 +109,277 @@

    SOURCE CODE ^% updateInfo 0027 % updateNMRsignals 0028 % updatePlotsDistribution -0029 % updatePlotsNMR -0030 % updatePlotsSignal -0031 % -0032 % Subfunctions: -0033 % createDataString -0034 % -0035 % MAT-files required: -0036 % none -0037 % -0038 % See also: NUCLEUSinv -0039 % Author: Thomas Hiller -0040 % email: thomas.hiller[at]leibniz-liag.de -0041 % License: MIT License (at end) -0042 -0043 %------------- BEGIN CODE -------------- -0044 -0045 %% get GUI handle and data -0046 fig = ancestor(src,'figure','toplevel'); -0047 fig_tag = get(fig,'Tag'); -0048 gui = getappdata(fig,'gui'); -0049 data = getappdata(fig,'data'); -0050 INVdata = getappdata(fig,'INVdata'); -0051 -0052 %% the generic part works for both GUIS -0053 % get the value of the field -0054 value = str2double(get(src,'String')); -0055 % get the user data of the field -0056 userdata = get(src,'UserData'); -0057 -0058 % check if the value is numeric -0059 % if not reset to defaults stored in user data -0060 defaults = userdata.defaults; -0061 if isnan(value) -0062 set(src,'String',num2str(defaults(1))); -0063 value = str2double(get(src,'String')); -0064 end -0065 -0066 % get the tag -0067 tag = get(src,'Tag'); -0068 out = createDataString(tag); -0069 -0070 % update the corresponding data field -0071 updstr = [out.updstr,'(',num2str(defaults(2)),',',... -0072 num2str(defaults(3)),')','=value;']; -0073 eval(updstr); -0074 % update the data inside the GUI -0075 setappdata(fig,'data',data); -0076 -0077 % switch depending on what figure called -0078 switch fig_tag -0079 case 'INV' -0080 % id of the chosen NMR signal -0081 id = get(gui.listbox_handles.signal,'Value'); -0082 -0083 % switch depending on the parent panel -0084 switch out.panel -0085 case 'process' -0086 % remove temporary data fields -0087 data = removeInversionFields(data); -0088 setappdata(fig,'data',data); -0089 % process the current selected signal -0090 id = get(gui.listbox_handles.signal,'Value'); -0091 switch out.field -0092 case {'Nechoes'} -0093 if value == 0 -0094 data.process.Nechoes = 1; -0095 set(src,'String',num2str(data.process.Nechoes)); -0096 setappdata(fig,'data',data); -0097 end -0098 case 'end' -0099 % check if the first sample is really smaller than -0100 % the last one; if not reset everything -0101 first = str2double(get(gui.edit_handles.process_start,'String')); -0102 last = value; -0103 maxL = length(data.import.NMR.data{id}.signal); -0104 if last == 0 || last <= first || last > maxL -0105 data.process.end = maxL; -0106 set(src,'String',num2str(data.process.end)); -0107 setappdata(fig,'data',data); -0108 end -0109 end -0110 % process the current selected signal -0111 processNMRDataControl(fig,id); -0112 updatePlotsSignal; -0113 updateInfo(src); -0114 % clear axes -0115 clearSingleAxis(gui.axes_handles.rtd); -0116 clearSingleAxis(gui.axes_handles.psd); -0117 % set focus on data -0118 set(gui.plots.SignalPanel,'Selection',1); -0119 case 'param' -0120 switch out.field -0121 case {'rho','a','CBWcutoff','BVIcutoff'} -0122 if isstruct(INVdata{id}) -0123 eval(['INVdata{',num2str(id),'}.',... -0124 out.panel,'.',out.field,'=value;']); -0125 setappdata(fig,'INVdata',INVdata); -0126 end -0127 updatePlotsDistribution; -0128 updateInfo(gui.plots.SignalPanel); -0129 case 'calibAmp' -0130 data.calib.amp = data.param.calibAmp; -0131 setappdata(fig,'data',data); -0132 case 'calibVol' -0133 data.calib.vol = data.param.calibVol; -0134 setappdata(fig,'data',data); -0135 case 'sampVol' -0136 calibratePorosity; -0137 end -0138 case 'invstd' -0139 switch out.field -0140 case 'lambdaR' -0141 data.invstd.lambda = data.invstd.lambdaR(1); -0142 setappdata(fig,'data',data); -0143 case 'Tbulk' -0144 if data.invstd.Tbulk <=0 -0145 data.invstd.Tbulk = 2; -0146 setappdata(fig,'data',data); -0147 set(src,'String',num2str(data.invstd.Tbulk)); -0148 end -0149 case 'porosity' -0150 if data.invstd.porosity < 0 || data.invstd.porosity > 1 -0151 data.invstd.porosity = 1; -0152 setappdata(fig,'data',data); -0153 set(src,'String',num2str(data.invstd.porosity)); -0154 end -0155 updatePlotsDistribution; -0156 end -0157 case 'invjoint' -0158 switch out.field -0159 case 'lambdaR' -0160 data.invjoint.lambda = data.invjoint.lambdaR(1); -0161 setappdata(fig,'data',data); -0162 case 'beta' -0163 if value < 0.1 -0164 value = 1; -0165 elseif value > 89.9 -0166 value = 89; -0167 end -0168 eval(updstr); -0169 data.invjoint.gamma = data.invjoint.alpha - data.invjoint.beta; -0170 setappdata(fig,'data',data); -0171 NUCLEUSinv_updateInterface; -0172 case 'rhostart' -0173 case 'anglestart' -0174 if value < 0.1 -0175 value = 1; -0176 elseif value > 89.9 -0177 value = 89; -0178 end -0179 eval(updstr); -0180 data.invjoint.beta = value; -0181 data.invjoint.gamma = data.invjoint.alpha - data.invjoint.beta; -0182 setappdata(fig,'data',data); -0183 NUCLEUSinv_updateInterface; -0184 end -0185 end % switch out.panel -0186 setappdata(fig,'gui',gui); -0187 case 'MOD' -0188 % switch depending on the parent panel -0189 switch out.panel -0190 case 'geometry' -0191 switch out.field -0192 case 'beta' -0193 if value < 0.5 -0194 value = 1; -0195 elseif value > 89.5 -0196 value = 89; -0197 end -0198 eval(updstr); -0199 setappdata(fig,'data',data); -0200 otherwise -0201 % nothing to do -0202 end -0203 data = removeCalculationFields(data,'cps'); -0204 data = removeCalculationFields(data,'nmr'); -0205 clearSingleAxis(gui.axes_handles.cps); -0206 clearSingleAxis(gui.axes_handles.nmr); -0207 setappdata(fig,'data',data); -0208 calculateGeometry; -0209 -0210 case 'pressure' -0211 switch out.field -0212 case 'range' -0213 updstr = [out.updstr,'(',num2str(defaults(2)),... -0214 ',',num2str(defaults(3)),')',... -0215 '=value/data.pressure.unitfac;']; -0216 eval(updstr); -0217 end -0218 data = removeCalculationFields(data,'cps'); -0219 data = removeCalculationFields(data,'nmr'); -0220 clearSingleAxis(gui.axes_handles.cps); -0221 clearSingleAxis(gui.axes_handles.nmr); -0222 setappdata(fig,'data',data); -0223 NUCLEUSmod_updateInterface; -0224 -0225 case 'nmr' -0226 switch out.field -0227 case 'noise' -0228 if isfield(data.results,'NMR') -0229 updateNMRsignals; -0230 updatePlotsNMR; -0231 end -0232 case 'porosity' -0233 if data.nmr.porosity <= 0 || data.nmr.porosity > 1 -0234 data.nmr.porosity = 1; -0235 set(src,'String',num2str(data.nmr.porosity)); -0236 setappdata(fig,'data',data); -0237 end -0238 if isfield(data.results,'NMR') -0239 updateNMRsignals; -0240 updatePlotsNMR; -0241 end -0242 otherwise -0243 data = removeCalculationFields(data,'nmr'); -0244 clearSingleAxis(gui.axes_handles.nmr); -0245 setappdata(fig,'data',data); -0246 NUCLEUSmod_updateInterface; -0247 end -0248 end -0249 otherwise -0250 helpdlg({'function: onEditValue','Something is utterly wrong.'},... -0251 'wrong fig tag'); -0252 end -0253 -0254 end -0255 -0256 function out = createDataString(tag) -0257 ind = strfind(tag,'_'); -0258 out.panel = tag(1:ind(1)-1); -0259 out.field = tag(ind(1)+1:end); -0260 tag(ind) = '.'; -0261 out.updstr = ['data.',tag]; -0262 end -0263 -0264 %------------- END OF CODE -------------- +0029 % updatePlotsSignal +0030 % +0031 % Subfunctions: +0032 % createDataString +0033 % +0034 % MAT-files required: +0035 % none +0036 % +0037 % See also: NUCLEUSinv +0038 % Author: see AUTHORS.md +0039 % email: see AUTHORS.md +0040 % License: MIT License (at end) +0041 +0042 %------------- BEGIN CODE -------------- +0043 +0044 %% get GUI handle and data +0045 fig = ancestor(src,'figure','toplevel'); +0046 fig_tag = get(fig,'Tag'); +0047 gui = getappdata(fig,'gui'); +0048 data = getappdata(fig,'data'); +0049 INVdata = getappdata(fig,'INVdata'); +0050 +0051 %% the generic part works for both GUIS +0052 % get the value of the field +0053 value = str2double(get(src,'String')); +0054 % get the user data of the field +0055 userdata = get(src,'UserData'); +0056 +0057 % check if the value is numeric +0058 % if not reset to defaults stored in user data +0059 defaults = userdata.defaults; +0060 if isnan(value) +0061 set(src,'String',num2str(defaults(1))); +0062 value = str2double(get(src,'String')); +0063 end +0064 +0065 % get the tag +0066 tag = get(src,'Tag'); +0067 out = createDataString(tag); +0068 +0069 % update the corresponding data field +0070 updstr = [out.updstr,'(',num2str(defaults(2)),',',... +0071 num2str(defaults(3)),')','=value;']; +0072 eval(updstr); +0073 % update the data inside the GUI +0074 setappdata(fig,'data',data); +0075 +0076 % switch depending on what figure called +0077 switch fig_tag +0078 case 'INV' +0079 % id of the chosen NMR signal +0080 id = get(gui.listbox_handles.signal,'Value'); +0081 +0082 % switch depending on the parent panel +0083 switch out.panel +0084 case 'process' +0085 % remove temporary data fields +0086 data = removeInversionFields(data); +0087 setappdata(fig,'data',data); +0088 % process the current selected signal +0089 id = get(gui.listbox_handles.signal,'Value'); +0090 switch out.field +0091 case {'Nechoes'} +0092 if value == 0 +0093 data.process.Nechoes = 1; +0094 set(src,'String',num2str(data.process.Nechoes)); +0095 setappdata(fig,'data',data); +0096 end +0097 case 'end' +0098 % check if the first sample is really smaller than +0099 % the last one; if not reset everything +0100 first = str2double(get(gui.edit_handles.process_start,'String')); +0101 last = value; +0102 maxL = length(data.import.NMR.data{id}.signal); +0103 if last == 0 || last <= first || last > maxL +0104 data.process.end = maxL; +0105 set(src,'String',num2str(data.process.end)); +0106 setappdata(fig,'data',data); +0107 end +0108 end +0109 % process the current selected signal +0110 processNMRDataControl(fig,id); +0111 updatePlotsSignal; +0112 updateInfo(src); +0113 % clear axes +0114 clearSingleAxis(gui.axes_handles.rtd); +0115 clearSingleAxis(gui.axes_handles.psd); +0116 % set focus on data +0117 set(gui.plots.SignalPanel,'Selection',1); +0118 case 'param' +0119 switch out.field +0120 case {'rho','a','CBWcutoff','BVIcutoff'} +0121 if isstruct(INVdata{id}) +0122 eval(['INVdata{',num2str(id),'}.',... +0123 out.panel,'.',out.field,'=value;']); +0124 setappdata(fig,'INVdata',INVdata); +0125 end +0126 updatePlotsDistribution; +0127 updateInfo(gui.plots.SignalPanel); +0128 case 'calibAmp' +0129 data.calib.amp = data.param.calibAmp; +0130 setappdata(fig,'data',data); +0131 case 'calibVol' +0132 data.calib.vol = data.param.calibVol; +0133 setappdata(fig,'data',data); +0134 case 'sampVol' +0135 calibratePorosity; +0136 end +0137 case 'invstd' +0138 switch out.field +0139 case 'lambdaR' +0140 data.invstd.lambda = data.invstd.lambdaR(1); +0141 setappdata(fig,'data',data); +0142 case 'Tbulk' +0143 if data.invstd.Tbulk <=0 +0144 data.invstd.Tbulk = 2; +0145 setappdata(fig,'data',data); +0146 set(src,'String',num2str(data.invstd.Tbulk)); +0147 end +0148 case 'Tdiff' +0149 if data.invstd.Tdiff <=0 +0150 data.invstd.Tdiff = 1e6; +0151 setappdata(fig,'data',data); +0152 set(src,'String',num2str(data.invstd.Tdiff)); +0153 end +0154 case 'porosity' +0155 if data.invstd.porosity < 0 || data.invstd.porosity > 1 +0156 data.invstd.porosity = 1; +0157 setappdata(fig,'data',data); +0158 set(src,'String',num2str(data.invstd.porosity)); +0159 end +0160 updatePlotsDistribution; +0161 end +0162 case 'invjoint' +0163 switch out.field +0164 case 'lambdaR' +0165 data.invjoint.lambda = data.invjoint.lambdaR(1); +0166 setappdata(fig,'data',data); +0167 case 'beta' +0168 if value < 0.1 +0169 value = 1; +0170 elseif value > 89.9 +0171 value = 89; +0172 end +0173 eval(updstr); +0174 data.invjoint.gamma = data.invjoint.alpha - data.invjoint.beta; +0175 setappdata(fig,'data',data); +0176 NUCLEUSinv_updateInterface; +0177 case 'rhostart' +0178 case 'anglestart' +0179 if value < 0.1 +0180 value = 1; +0181 elseif value > 89.9 +0182 value = 89; +0183 end +0184 eval(updstr); +0185 data.invjoint.beta = value; +0186 data.invjoint.gamma = data.invjoint.alpha - data.invjoint.beta; +0187 setappdata(fig,'data',data); +0188 NUCLEUSinv_updateInterface; +0189 end +0190 end % switch out.panel +0191 setappdata(fig,'gui',gui); +0192 case 'MOD' +0193 % switch depending on the parent panel +0194 switch out.panel +0195 case 'geometry' +0196 switch out.field +0197 case 'beta' +0198 if value < 0.5 +0199 value = 1; +0200 elseif value > 89.5 +0201 value = 89; +0202 end +0203 eval(updstr); +0204 setappdata(fig,'data',data); +0205 otherwise +0206 % nothing to do +0207 end +0208 data = removeCalculationFields(data,'cps'); +0209 data = removeCalculationFields(data,'nmr'); +0210 clearSingleAxis(gui.axes_handles.cps); +0211 clearSingleAxis(gui.axes_handles.nmr); +0212 setappdata(fig,'data',data); +0213 calculateGeometry; +0214 +0215 case 'pressure' +0216 switch out.field +0217 case 'range' +0218 updstr = [out.updstr,'(',num2str(defaults(2)),... +0219 ',',num2str(defaults(3)),')',... +0220 '=value/data.pressure.unitfac;']; +0221 eval(updstr); +0222 end +0223 data = removeCalculationFields(data,'cps'); +0224 data = removeCalculationFields(data,'nmr'); +0225 clearSingleAxis(gui.axes_handles.cps); +0226 clearSingleAxis(gui.axes_handles.nmr); +0227 setappdata(fig,'data',data); +0228 NUCLEUSmod_updateInterface; +0229 +0230 case 'nmr' +0231 switch out.field +0232 case 'noise' +0233 switch data.nmr.noisetype +0234 case 'level' +0235 case 'SNR' +0236 if data.nmr.noise == 0 +0237 data.nmr.noise = Inf; +0238 set(src,'String',num2str(data.nmr.noise)); +0239 end +0240 end +0241 setappdata(fig,'data',data); +0242 if isfield(data.results,'NMR') +0243 updateNMRsignals; +0244 end +0245 case 'porosity' +0246 if data.nmr.porosity <= 0 || data.nmr.porosity > 1 +0247 data.nmr.porosity = 1; +0248 set(src,'String',num2str(data.nmr.porosity)); +0249 setappdata(fig,'data',data); +0250 end +0251 if isfield(data.results,'NMR') +0252 updateNMRsignals; +0253 end +0254 otherwise +0255 data = removeCalculationFields(data,'nmr'); +0256 clearSingleAxis(gui.axes_handles.nmr); +0257 setappdata(fig,'data',data); +0258 NUCLEUSmod_updateInterface; +0259 end +0260 end +0261 otherwise +0262 helpdlg({'function: onEditValue','Something is utterly wrong.'},... +0263 'wrong fig tag'); +0264 end 0265 -0266 %% License: -0267 % MIT License -0268 % -0269 % Copyright (c) 2018 Thomas Hiller -0270 % -0271 % Permission is hereby granted, free of charge, to any person obtaining a copy -0272 % of this software and associated documentation files (the "Software"), to deal -0273 % in the Software without restriction, including without limitation the rights -0274 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0275 % copies of the Software, and to permit persons to whom the Software is -0276 % furnished to do so, subject to the following conditions: -0277 % -0278 % The above copyright notice and this permission notice shall be included in all -0279 % copies or substantial portions of the Software. +0266 end +0267 +0268 function out = createDataString(tag) +0269 ind = strfind(tag,'_'); +0270 out.panel = tag(1:ind(1)-1); +0271 out.field = tag(ind(1)+1:end); +0272 tag(ind) = '.'; +0273 out.updstr = ['data.',tag]; +0274 end +0275 +0276 %------------- END OF CODE -------------- +0277 +0278 %% License: +0279 % MIT License 0280 % -0281 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0282 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0283 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0284 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0285 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0286 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0287 % SOFTWARE. +0281 % Copyright (c) 2018 Thomas Hiller +0282 % +0283 % Permission is hereby granted, free of charge, to any person obtaining a copy +0284 % of this software and associated documentation files (the "Software"), to deal +0285 % in the Software without restriction, including without limitation the rights +0286 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0287 % copies of the Software, and to permit persons to whom the Software is +0288 % furnished to do so, subject to the following conditions: +0289 % +0290 % The above copyright notice and this permission notice shall be included in all +0291 % copies or substantial portions of the Software. +0292 % +0293 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0294 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0295 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0296 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0297 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0298 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0299 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/callbacks/listboxes/onListboxData.html b/doc/nucleus/callbacks/listboxes/onListboxData.html index c158387..35d90c8 100644 --- a/doc/nucleus/callbacks/listboxes/onListboxData.html +++ b/doc/nucleus/callbacks/listboxes/onListboxData.html @@ -59,8 +59,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=NUCLEUSinv_updateInterface updates all GUI elements
  • onPopupInvstdType selects the inversion method for the standard inversion
  • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
  • PhaseView is an extra subGUI to visualize the phase of a T2 signal
  • clearSingleAxis clears an individual axis
  • processNMRDataControl prepares simple NMR raw data processing
  • removeInversionFields deletes all inversion result fields from NUCLEUSinv
  • showFitStatistics shows an extra fit statistics figure (for T2 data)
  • updateInfo updates the information shown in all information list boxes
  • updatePlotsDistribution plots the RTD and PSD curves into NUCLEUSinv
  • updatePlotsJointInversion plots the joint-inversion results in NUCLEUSinv
  • updatePlotsLcurve plots the results of the L-curve calculation
  • updatePlotsSignal plots the raw and processed NMR signals in NUCLEUSinv
  • This function is called by: +
  • NUCLEUSinv_createPanelData creates data panel
  • importINV2INV imports a previously saved NUCLEUSinv session
  • runInversionBatch batch processes the inversion using for all NMR signals
  • @@ -110,8 +110,8 @@

    SOURCE CODE ^% none 0033 % 0034 % See also: NUCLEUSinv -0035 % Author: Thomas Hiller -0036 % email: thomas.hiller[at]leibniz-liag.de +0035 % Author: see AUTHORS.md +0036 % email: see AUTHORS.md 0037 % License: MIT License (at end) 0038 0039 %------------- BEGIN CODE -------------- @@ -176,7 +176,7 @@

    SOURCE CODE ^case 'T2' 0100 switch data.import.fileformat -0101 case {'dart','field','mouse','NMRMOD','excel'} +0101 case {'dart','excel','field','helios','mouse','NMRMOD'} 0102 data.process.gatetype = 'raw'; 0103 data.process.start = 1; 0104 otherwise @@ -225,86 +225,87 @@

    SOURCE CODE ^end 0148 if isfield(data.import,'NMRMOD') 0149 data.param.rho = data.import.NMR.para{id}.rho*1e6; -0150 data.invstd.Tbulk = data.import.NMR.para{id}.Tbulk; -0151 data.invstd.porosity = data.import.NMR.para{id}.porosity; -0152 end -0153 % --- -0154 -0155 % update the figure data -0156 setappdata(fig,'data',data); -0157 -0158 % process the NMR data -0159 processNMRDataControl(fig,id); -0160 % update interface -0161 NUCLEUSinv_updateInterface; -0162 -0163 % update the data plot axes -0164 updatePlotsSignal; -0165 % update the info fields -0166 updateInfo(gui.plots.SignalPanel); -0167 gui = getappdata(fig,'gui'); -0168 -0169 % clear inversion axes -0170 clearSingleAxis(gui.axes_handles.rtd); -0171 clearSingleAxis(gui.axes_handles.psd); -0172 end -0173 -0174 % set focus on data -0175 % set(gui.plots.SignalPanel,'Selection',1); -0176 % set(gui.plots.DistPanel,'Selection',1); -0177 -0178 % reset all RUN buttons -0179 set(gui.push_handles.invstd_run,'String','<HTML><u>R</u>UN',... -0180 'BackgroundColor','g','Enable','on','Callback',@onPushRun); -0181 set(gui.push_handles.invjoint_run,'String','<HTML><u>R</u>UN',... -0182 'BackgroundColor','g','Enable','on','Callback',@onPushRun); -0183 -0184 % if the Fit Statistics window is open update it -0185 if ~isempty(findobj('Tag','FITSTATS')) -0186 showFitStatistics; -0187 end -0188 % if the PhaseView window is open update it -0189 if ~isempty(findobj('Tag','PHASEVIEW')) -0190 PhaseView(gui.menu.extra_phaseview); -0191 end -0192 else -0193 helpdlg({'onListboxData:','Only choose one data set at a time.'},... -0194 'too many data'); -0195 end -0196 else -0197 helpdlg('Nothing to do because there is no data loaded!',... -0198 'onListboxData: Load NMR data first.'); -0199 end -0200 -0201 % update the figure data -0202 setappdata(fig,'gui',gui); -0203 -0204 end -0205 -0206 %------------- END OF CODE -------------- -0207 -0208 %% License: -0209 % MIT License -0210 % -0211 % Copyright (c) 2018 Thomas Hiller -0212 % -0213 % Permission is hereby granted, free of charge, to any person obtaining a copy -0214 % of this software and associated documentation files (the "Software"), to deal -0215 % in the Software without restriction, including without limitation the rights -0216 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0217 % copies of the Software, and to permit persons to whom the Software is -0218 % furnished to do so, subject to the following conditions: -0219 % -0220 % The above copyright notice and this permission notice shall be included in all -0221 % copies or substantial portions of the Software. -0222 % -0223 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0224 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0225 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0226 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0227 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0228 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0229 % SOFTWARE. +0150 data.invstd.Tbulk = data.import.NMR.para{id}.Tbulk; +0151 data.invstd.Tdiff = data.import.NMR.para{id}.Tdiff; +0152 data.invstd.porosity = data.import.NMR.para{id}.porosity; +0153 end +0154 % --- +0155 +0156 % update the figure data +0157 setappdata(fig,'data',data); +0158 +0159 % process the NMR data +0160 processNMRDataControl(fig,id); +0161 % update interface +0162 NUCLEUSinv_updateInterface; +0163 +0164 % update the data plot axes +0165 updatePlotsSignal; +0166 % update the info fields +0167 updateInfo(gui.plots.SignalPanel); +0168 gui = getappdata(fig,'gui'); +0169 +0170 % clear inversion axes +0171 clearSingleAxis(gui.axes_handles.rtd); +0172 clearSingleAxis(gui.axes_handles.psd); +0173 end +0174 +0175 % set focus on data +0176 % set(gui.plots.SignalPanel,'Selection',1); +0177 % set(gui.plots.DistPanel,'Selection',1); +0178 +0179 % reset all RUN buttons +0180 set(gui.push_handles.invstd_run,'String','<HTML><u>R</u>UN',... +0181 'BackgroundColor','g','Enable','on','Callback',@onPushRun); +0182 set(gui.push_handles.invjoint_run,'String','<HTML><u>R</u>UN',... +0183 'BackgroundColor','g','Enable','on','Callback',@onPushRun); +0184 +0185 % if the Fit Statistics window is open update it +0186 if ~isempty(findobj('Tag','FITSTATS')) +0187 showFitStatistics; +0188 end +0189 % if the PhaseView window is open update it +0190 if ~isempty(findobj('Tag','PHASEVIEW')) +0191 PhaseView(gui.menu.extra_phaseview); +0192 end +0193 else +0194 helpdlg({'onListboxData:','Only choose one data set at a time.'},... +0195 'too many data'); +0196 end +0197 else +0198 helpdlg('Nothing to do because there is no data loaded!',... +0199 'onListboxData: Load NMR data first.'); +0200 end +0201 +0202 % update the figure data +0203 setappdata(fig,'gui',gui); +0204 +0205 end +0206 +0207 %------------- END OF CODE -------------- +0208 +0209 %% License: +0210 % MIT License +0211 % +0212 % Copyright (c) 2018 Thomas Hiller +0213 % +0214 % Permission is hereby granted, free of charge, to any person obtaining a copy +0215 % of this software and associated documentation files (the "Software"), to deal +0216 % in the Software without restriction, including without limitation the rights +0217 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0218 % copies of the Software, and to permit persons to whom the Software is +0219 % furnished to do so, subject to the following conditions: +0220 % +0221 % The above copyright notice and this permission notice shall be included in all +0222 % copies or substantial portions of the Software. +0223 % +0224 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0225 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0226 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0227 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0228 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0229 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0230 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/callbacks/menus/onMenuExpert.html b/doc/nucleus/callbacks/menus/onMenuExpert.html index 9adb255..982a24b 100644 --- a/doc/nucleus/callbacks/menus/onMenuExpert.html +++ b/doc/nucleus/callbacks/menus/onMenuExpert.html @@ -58,8 +58,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0032 % 0033 % See also: NUCLEUSinv -0034 % Author: Thomas Hiller -0035 % email: thomas.hiller[at]leibniz-liag.de +0034 % Author: see AUTHORS.md +0035 % email: see AUTHORS.md 0036 % License: MIT License (at end) 0037 0038 %------------- BEGIN CODE -------------- @@ -125,7 +125,7 @@

    SOURCE CODE ^% deactivate or activate expert mode 0050 switch onoff -0051 case 'on' % it it's on, switch it off +0051 case 'on' % if it's on, switch it off 0052 data.info.ExpertMode = 'off'; 0053 % menu entry 0054 set(gui.menu.extra_expert,'Checked','off'); diff --git a/doc/nucleus/callbacks/menus/onMenuExportData.html b/doc/nucleus/callbacks/menus/onMenuExportData.html index 96b9095..c1fb58a 100644 --- a/doc/nucleus/callbacks/menus/onMenuExportData.html +++ b/doc/nucleus/callbacks/menus/onMenuExportData.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuExportGraphics.html b/doc/nucleus/callbacks/menus/onMenuExportGraphics.html index 7892e5d..4fe1cd8 100644 --- a/doc/nucleus/callbacks/menus/onMenuExportGraphics.html +++ b/doc/nucleus/callbacks/menus/onMenuExportGraphics.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv, NUCLEUSmod -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuExtraColor.html b/doc/nucleus/callbacks/menus/onMenuExtraColor.html index 4158187..bdad2b5 100644 --- a/doc/nucleus/callbacks/menus/onMenuExtraColor.html +++ b/doc/nucleus/callbacks/menus/onMenuExtraColor.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv, NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuExtraRhoBounds.html b/doc/nucleus/callbacks/menus/onMenuExtraRhoBounds.html index a4c71a3..3864b30 100644 --- a/doc/nucleus/callbacks/menus/onMenuExtraRhoBounds.html +++ b/doc/nucleus/callbacks/menus/onMenuExtraRhoBounds.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuHelp.html b/doc/nucleus/callbacks/menus/onMenuHelp.html index 6bfa900..c4411f1 100644 --- a/doc/nucleus/callbacks/menus/onMenuHelp.html +++ b/doc/nucleus/callbacks/menus/onMenuHelp.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv, NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuImport.html b/doc/nucleus/callbacks/menus/onMenuImport.html index 5ef1d59..0c8c71e 100644 --- a/doc/nucleus/callbacks/menus/onMenuImport.html +++ b/doc/nucleus/callbacks/menus/onMenuImport.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSinv, NUCLEUSmod -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- @@ -143,55 +143,57 @@

    SOURCE CODE ^% activate the PhaseView GUI in case real data is imported 0070 switch menu_tag -0071 case {'NUCLEUSinv','NUCLEUSmod'} +0071 case 'NUCLEUSmod' 0072 set(gui.menu.extra_phaseview,'Enable','off'); 0073 otherwise 0074 set(gui.menu.extra_phaseview,'Enable','on'); 0075 end 0076 -0077 % update the "last import" value within the ini-file -0078 gui.myui.inidata.lastimport = [menu_tag,'_',label]; -0079 setappdata(fig,'gui',gui); -0080 gui = makeINIfile(gui,'update'); -0081 % and the menu entry itself -0082 switch label -0083 case 'LIAG from project' -0084 label = 'LIAG last project'; -0085 set(gui.menu.file_import_lastimport,'Label',label,... -0086 'Tag',menu_tag,'Callback',@onMenuImport) -0087 otherwise -0088 set(gui.menu.file_import_lastimport,'Label',label,... -0089 'Tag',menu_tag,'Callback',@onMenuImport); -0090 end -0091 setappdata(fig,'gui',gui); -0092 end -0093 +0077 % get updated gui data +0078 gui = getappdata(fig,'gui'); +0079 % update the "last import" value within the ini-file +0080 gui.myui.inidata.lastimport = [menu_tag,'_',label]; +0081 setappdata(fig,'gui',gui); +0082 gui = makeINIfile(gui,'update'); +0083 % and the menu entry itself +0084 switch label +0085 case 'LIAG from project' +0086 label = 'LIAG last project'; +0087 set(gui.menu.file_import_lastimport,'Label',label,... +0088 'Tag',menu_tag,'Callback',@onMenuImport) +0089 otherwise +0090 set(gui.menu.file_import_lastimport,'Label',label,... +0091 'Tag',menu_tag,'Callback',@onMenuImport); +0092 end +0093 setappdata(fig,'gui',gui); 0094 end 0095 -0096 %------------- END OF CODE -------------- +0096 end 0097 -0098 %% License: -0099 % MIT License -0100 % -0101 % Copyright (c) 2018 Thomas Hiller +0098 %------------- END OF CODE -------------- +0099 +0100 %% License: +0101 % MIT License 0102 % -0103 % Permission is hereby granted, free of charge, to any person obtaining a copy -0104 % of this software and associated documentation files (the "Software"), to deal -0105 % in the Software without restriction, including without limitation the rights -0106 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0107 % copies of the Software, and to permit persons to whom the Software is -0108 % furnished to do so, subject to the following conditions: -0109 % -0110 % The above copyright notice and this permission notice shall be included in all -0111 % copies or substantial portions of the Software. -0112 % -0113 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0114 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0115 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0116 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0117 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0118 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0119 % SOFTWARE. +0103 % Copyright (c) 2018 Thomas Hiller +0104 % +0105 % Permission is hereby granted, free of charge, to any person obtaining a copy +0106 % of this software and associated documentation files (the "Software"), to deal +0107 % in the Software without restriction, including without limitation the rights +0108 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0109 % copies of the Software, and to permit persons to whom the Software is +0110 % furnished to do so, subject to the following conditions: +0111 % +0112 % The above copyright notice and this permission notice shall be included in all +0113 % copies or substantial portions of the Software. +0114 % +0115 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0116 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0117 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0118 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0119 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0120 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0121 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/callbacks/menus/onMenuJointInversion.html b/doc/nucleus/callbacks/menus/onMenuJointInversion.html index 08bc671..0de3dc8 100644 --- a/doc/nucleus/callbacks/menus/onMenuJointInversion.html +++ b/doc/nucleus/callbacks/menus/onMenuJointInversion.html @@ -57,8 +57,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0031 % 0032 % See also: NUCLEUSinv -0033 % Author: Thomas Hiller -0034 % email: thomas.hiller[at]leibniz-liag.de +0033 % Author: see AUTHORS.md +0034 % email: see AUTHORS.md 0035 % License: MIT License (at end) 0036 0037 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuRestartQuit.html b/doc/nucleus/callbacks/menus/onMenuRestartQuit.html index 9d0eb42..61cfa82 100644 --- a/doc/nucleus/callbacks/menus/onMenuRestartQuit.html +++ b/doc/nucleus/callbacks/menus/onMenuRestartQuit.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv, NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuSolver.html b/doc/nucleus/callbacks/menus/onMenuSolver.html index b5add69..c497fb5 100644 --- a/doc/nucleus/callbacks/menus/onMenuSolver.html +++ b/doc/nucleus/callbacks/menus/onMenuSolver.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuView.html b/doc/nucleus/callbacks/menus/onMenuView.html index 450947a..82dcdec 100644 --- a/doc/nucleus/callbacks/menus/onMenuView.html +++ b/doc/nucleus/callbacks/menus/onMenuView.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv, NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/menus/onMenuViewFigures.html b/doc/nucleus/callbacks/menus/onMenuViewFigures.html index ba60aaa..7591d1a 100644 --- a/doc/nucleus/callbacks/menus/onMenuViewFigures.html +++ b/doc/nucleus/callbacks/menus/onMenuViewFigures.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/menu.html b/doc/nucleus/callbacks/popup/menu.html index 90864a8..505f02b 100644 --- a/doc/nucleus/callbacks/popup/menu.html +++ b/doc/nucleus/callbacks/popup/menu.html @@ -18,7 +18,7 @@

    Index for nucleus\callbacks\popup

    Matlab files in this directory:

    +
  • onPopupGeometryModesN
  • onPopupGeometryPolyN
  • onPopupGeometrySinglePSD
  • onPopupGeometryType
  • onPopupInvjointGeometryType
  • onPopupInvjointPolyN
  • onPopupInvjointType
  • onPopupInvjointTypeOptional
  • onPopupInvstdType
  • onPopupInvstdTypeOptional
  • onPopupNMRNoiseType
  • onPopupPressureLoglin
  • onPopupPressureUnits
  • diff --git a/doc/nucleus/callbacks/popup/onPopupGeometryModesN.html b/doc/nucleus/callbacks/popup/onPopupGeometryModesN.html index 25565c8..9c0cb44 100644 --- a/doc/nucleus/callbacks/popup/onPopupGeometryModesN.html +++ b/doc/nucleus/callbacks/popup/onPopupGeometryModesN.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSmod -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupGeometryPolyN.html b/doc/nucleus/callbacks/popup/onPopupGeometryPolyN.html index a2c16d1..405e7ce 100644 --- a/doc/nucleus/callbacks/popup/onPopupGeometryPolyN.html +++ b/doc/nucleus/callbacks/popup/onPopupGeometryPolyN.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSmod -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupGeometrySinglePSD.html b/doc/nucleus/callbacks/popup/onPopupGeometrySinglePSD.html index cbd3eab..e328cdf 100644 --- a/doc/nucleus/callbacks/popup/onPopupGeometrySinglePSD.html +++ b/doc/nucleus/callbacks/popup/onPopupGeometrySinglePSD.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSmod -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupGeometryType.html b/doc/nucleus/callbacks/popup/onPopupGeometryType.html index 52d9171..b2e116d 100644 --- a/doc/nucleus/callbacks/popup/onPopupGeometryType.html +++ b/doc/nucleus/callbacks/popup/onPopupGeometryType.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSmod -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupInvjointGeometryType.html b/doc/nucleus/callbacks/popup/onPopupInvjointGeometryType.html index 3c47ec4..86cd5bf 100644 --- a/doc/nucleus/callbacks/popup/onPopupInvjointGeometryType.html +++ b/doc/nucleus/callbacks/popup/onPopupInvjointGeometryType.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupInvjointPolyN.html b/doc/nucleus/callbacks/popup/onPopupInvjointPolyN.html index dad1dfa..8ccbb57 100644 --- a/doc/nucleus/callbacks/popup/onPopupInvjointPolyN.html +++ b/doc/nucleus/callbacks/popup/onPopupInvjointPolyN.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupInvjointType.html b/doc/nucleus/callbacks/popup/onPopupInvjointType.html index 5570608..d1384aa 100644 --- a/doc/nucleus/callbacks/popup/onPopupInvjointType.html +++ b/doc/nucleus/callbacks/popup/onPopupInvjointType.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupInvjointTypeOptional.html b/doc/nucleus/callbacks/popup/onPopupInvjointTypeOptional.html index 6205b64..0ce1742 100644 --- a/doc/nucleus/callbacks/popup/onPopupInvjointTypeOptional.html +++ b/doc/nucleus/callbacks/popup/onPopupInvjointTypeOptional.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupInvstdType.html b/doc/nucleus/callbacks/popup/onPopupInvstdType.html index 85a592b..37a51e5 100644 --- a/doc/nucleus/callbacks/popup/onPopupInvstdType.html +++ b/doc/nucleus/callbacks/popup/onPopupInvstdType.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- @@ -133,72 +133,82 @@

    SOURCE CODE ^'LU'; 0063 data.invstd.regtype = 'auto'; 0064 data.invstd.lambda = -1; -0065 end -0066 -0067 case 'off' -0068 switch value -0069 case 1 -0070 data.invstd.invtype = 'mono'; -0071 data.invstd.regtype = 'none'; -0072 data.invstd.lambda = 1; -0073 -0074 case 2 -0075 data.invstd.invtype = 'free'; +0065 +0066 case 5 +0067 data.invstd.invtype = 'MUMO'; +0068 data.invstd.regtype = 'none'; +0069 data.invstd.lambda = 1; +0070 end +0071 +0072 case 'off' +0073 switch value +0074 case 1 +0075 data.invstd.invtype = 'mono'; 0076 data.invstd.regtype = 'none'; 0077 data.invstd.lambda = 1; 0078 -0079 case 3 -0080 data.invstd.invtype = 'NNLS'; -0081 % for multi-exponential inversion log-gating is default -0082 data.process.gatetype = 'log'; +0079 case 2 +0080 data.invstd.invtype = 'free'; +0081 data.invstd.regtype = 'none'; +0082 data.invstd.lambda = 1; 0083 -0084 % set LIAG defaults -0085 if isfield(data.import,'LIAG') -0086 data.invstd.regtype = 'lcurve'; -0087 data.invstd.lambda = 1; -0088 data.invstd.lambdaR = [1e-5 1]; -0089 else -0090 data.invstd.regtype = 'manual'; -0091 data.invstd.lambda = 1e-2; -0092 end -0093 % update GUI data -0094 setappdata(fig,'data',data); -0095 % because the gate type could have changed update data -0096 onRadioGates(gui.radio_handles.process_gates_log); -0097 data = getappdata(fig,'data'); -0098 end -0099 end -0100 % update GUI data -0101 setappdata(fig,'data',data); -0102 % update interface -0103 NUCLEUSinv_updateInterface; -0104 -0105 end -0106 -0107 %------------- END OF CODE -------------- -0108 -0109 %% License: -0110 % MIT License -0111 % -0112 % Copyright (c) 2018 Thomas Hiller -0113 % -0114 % Permission is hereby granted, free of charge, to any person obtaining a copy -0115 % of this software and associated documentation files (the "Software"), to deal -0116 % in the Software without restriction, including without limitation the rights -0117 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0118 % copies of the Software, and to permit persons to whom the Software is -0119 % furnished to do so, subject to the following conditions: -0120 % -0121 % The above copyright notice and this permission notice shall be included in all -0122 % copies or substantial portions of the Software. +0084 case 3 +0085 data.invstd.invtype = 'NNLS'; +0086 % for multi-exponential inversion log-gating is default +0087 data.process.gatetype = 'log'; +0088 +0089 % set LIAG defaults +0090 if isfield(data.import,'LIAG') +0091 data.invstd.regtype = 'lcurve'; +0092 data.invstd.lambda = 1; +0093 data.invstd.lambdaR = [1e-5 1]; +0094 else +0095 data.invstd.regtype = 'manual'; +0096 data.invstd.lambda = 1e-2; +0097 end +0098 % update GUI data +0099 setappdata(fig,'data',data); +0100 % because the gate type could have changed update data +0101 onRadioGates(gui.radio_handles.process_gates_log); +0102 data = getappdata(fig,'data'); +0103 +0104 case 4 +0105 data.invstd.invtype = 'MUMO'; +0106 data.invstd.regtype = 'none'; +0107 data.invstd.lambda = 1; +0108 end +0109 end +0110 % update GUI data +0111 setappdata(fig,'data',data); +0112 % update interface +0113 NUCLEUSinv_updateInterface; +0114 +0115 end +0116 +0117 %------------- END OF CODE -------------- +0118 +0119 %% License: +0120 % MIT License +0121 % +0122 % Copyright (c) 2018 Thomas Hiller 0123 % -0124 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0125 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0126 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0127 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0128 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0129 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0130 % SOFTWARE. +0124 % Permission is hereby granted, free of charge, to any person obtaining a copy +0125 % of this software and associated documentation files (the "Software"), to deal +0126 % in the Software without restriction, including without limitation the rights +0127 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0128 % copies of the Software, and to permit persons to whom the Software is +0129 % furnished to do so, subject to the following conditions: +0130 % +0131 % The above copyright notice and this permission notice shall be included in all +0132 % copies or substantial portions of the Software. +0133 % +0134 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0135 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0136 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0137 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0138 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0139 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0140 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/callbacks/popup/onPopupInvstdTypeOptional.html b/doc/nucleus/callbacks/popup/onPopupInvstdTypeOptional.html index f895843..b4741b1 100644 --- a/doc/nucleus/callbacks/popup/onPopupInvstdTypeOptional.html +++ b/doc/nucleus/callbacks/popup/onPopupInvstdTypeOptional.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: NUCLEUSinv -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- @@ -208,39 +208,43 @@

    SOURCE CODE ^'auto'; 0136 data.invstd.lambda = -1; 0137 end -0138 end -0139 -0140 % update GUI data -0141 setappdata(fig,'data',data); -0142 % update interface -0143 NUCLEUSinv_updateInterface; -0144 -0145 end -0146 -0147 %------------- END OF CODE -------------- +0138 +0139 case 'MUMO' +0140 % # free distributions = value (1 to 4) +0141 data.invstd.freeDT = value; +0142 end +0143 +0144 % update GUI data +0145 setappdata(fig,'data',data); +0146 % update interface +0147 NUCLEUSinv_updateInterface; 0148 -0149 %% License: -0150 % MIT License -0151 % -0152 % Copyright (c) 2018 Thomas Hiller -0153 % -0154 % Permission is hereby granted, free of charge, to any person obtaining a copy -0155 % of this software and associated documentation files (the "Software"), to deal -0156 % in the Software without restriction, including without limitation the rights -0157 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0158 % copies of the Software, and to permit persons to whom the Software is -0159 % furnished to do so, subject to the following conditions: -0160 % -0161 % The above copyright notice and this permission notice shall be included in all -0162 % copies or substantial portions of the Software. -0163 % -0164 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0165 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0166 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0167 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0168 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0169 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0170 % SOFTWARE. +0149 end +0150 +0151 %------------- END OF CODE -------------- +0152 +0153 %% License: +0154 % MIT License +0155 % +0156 % Copyright (c) 2018 Thomas Hiller +0157 % +0158 % Permission is hereby granted, free of charge, to any person obtaining a copy +0159 % of this software and associated documentation files (the "Software"), to deal +0160 % in the Software without restriction, including without limitation the rights +0161 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0162 % copies of the Software, and to permit persons to whom the Software is +0163 % furnished to do so, subject to the following conditions: +0164 % +0165 % The above copyright notice and this permission notice shall be included in all +0166 % copies or substantial portions of the Software. +0167 % +0168 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0169 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0170 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0171 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0172 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0173 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0174 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/callbacks/popup/onPopupNMRNoiseType.html b/doc/nucleus/callbacks/popup/onPopupNMRNoiseType.html new file mode 100644 index 0000000..903caf3 --- /dev/null +++ b/doc/nucleus/callbacks/popup/onPopupNMRNoiseType.html @@ -0,0 +1,166 @@ + + + + Description of onPopupNMRNoiseType + + + + + + + + + + + +

    onPopupNMRNoiseType +

    + +

    PURPOSE ^

    +
    selects the noise type to be aplied to the forward
    + +

    SYNOPSIS ^

    +
    function onPopupNMRNoiseType(src,~)
    + +

    DESCRIPTION ^

    +
    onPopupNMRNoiseType selects the noise type to be aplied to the forward
    +modelled NMR data
    +
    + Syntax:
    +       onPopupNMRNoiseType
    +
    + Inputs:
    +       src - handle of the calling object
    +
    + Outputs:
    +       none
    +
    + Example:
    +       onPopupNMRNoiseType(src,~)
    +
    + Other m-files required:
    +       clearSingleAxis.m
    +       updateCPSTable.m
    +
    + Subfunctions:
    +       none
    +
    + MAT-files required:
    +       none
    +
    + See also: NUCLEUSmod
    + Author: see AUTHORS.md
    + email: see AUTHORS.md
    + License: MIT License (at end)
    + + +

    CROSS-REFERENCE INFORMATION ^

    +This function calls: + +This function is called by: + + + + + +

    SOURCE CODE ^

    +
    0001 function onPopupNMRNoiseType(src,~)
    +0002 %onPopupNMRNoiseType selects the noise type to be aplied to the forward
    +0003 %modelled NMR data
    +0004 %
    +0005 % Syntax:
    +0006 %       onPopupNMRNoiseType
    +0007 %
    +0008 % Inputs:
    +0009 %       src - handle of the calling object
    +0010 %
    +0011 % Outputs:
    +0012 %       none
    +0013 %
    +0014 % Example:
    +0015 %       onPopupNMRNoiseType(src,~)
    +0016 %
    +0017 % Other m-files required:
    +0018 %       clearSingleAxis.m
    +0019 %       updateCPSTable.m
    +0020 %
    +0021 % Subfunctions:
    +0022 %       none
    +0023 %
    +0024 % MAT-files required:
    +0025 %       none
    +0026 %
    +0027 % See also: NUCLEUSmod
    +0028 % Author: see AUTHORS.md
    +0029 % email: see AUTHORS.md
    +0030 % License: MIT License (at end)
    +0031 
    +0032 %------------- BEGIN CODE --------------
    +0033 
    +0034 %% get GUI handle and data
    +0035 fig = findobj('Tag','MOD');
    +0036 data = getappdata(fig,'data');
    +0037 gui = getappdata(fig,'gui');
    +0038 
    +0039 % get the value of the popup menu
    +0040 value = get(src,'Value');
    +0041 
    +0042 % change settings accordingly
    +0043 switch value
    +0044     case 1 % noise level
    +0045         data.nmr.noisetype = 'level';
    +0046         if data.nmr.noise > 0
    +0047             data.nmr.noise = 1/data.nmr.noise;
    +0048         end        
    +0049     case 2 % signal-to-noise ratio (SNR)
    +0050         data.nmr.noisetype = 'SNR';
    +0051         if data.nmr.noise == 0
    +0052             data.nmr.noise = inf;
    +0053         else
    +0054             data.nmr.noise = 1/data.nmr.noise;
    +0055         end        
    +0056 end
    +0057 % update the corresponding edit field
    +0058 set(gui.edit_handles.noise,'String',num2str(data.nmr.noise));
    +0059 
    +0060 % update GUI data
    +0061 setappdata(fig,'data',data);
    +0062 % update NMR data (if available)
    +0063 if isfield(data.results,'NMR')
    +0064     updateNMRsignals;
    +0065 end
    +0066 
    +0067 end
    +0068 
    +0069 %------------- END OF CODE --------------
    +0070 
    +0071 %% License:
    +0072 % MIT License
    +0073 %
    +0074 % Copyright (c) 2021 Thomas Hiller
    +0075 %
    +0076 % Permission is hereby granted, free of charge, to any person obtaining a copy
    +0077 % of this software and associated documentation files (the "Software"), to deal
    +0078 % in the Software without restriction, including without limitation the rights
    +0079 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +0080 % copies of the Software, and to permit persons to whom the Software is
    +0081 % furnished to do so, subject to the following conditions:
    +0082 %
    +0083 % The above copyright notice and this permission notice shall be included in all
    +0084 % copies or substantial portions of the Software.
    +0085 %
    +0086 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +0087 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +0088 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +0089 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +0090 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +0091 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +0092 % SOFTWARE.
    +
    Generated by m2html © 2005
    + + \ No newline at end of file diff --git a/doc/nucleus/callbacks/popup/onPopupPressureLoglin.html b/doc/nucleus/callbacks/popup/onPopupPressureLoglin.html index d2dd444..87ff18f 100644 --- a/doc/nucleus/callbacks/popup/onPopupPressureLoglin.html +++ b/doc/nucleus/callbacks/popup/onPopupPressureLoglin.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSmod -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/popup/onPopupPressureUnits.html b/doc/nucleus/callbacks/popup/onPopupPressureUnits.html index 05bc112..9aed5a1 100644 --- a/doc/nucleus/callbacks/popup/onPopupPressureUnits.html +++ b/doc/nucleus/callbacks/popup/onPopupPressureUnits.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/push/onPushCPSTable.html b/doc/nucleus/callbacks/push/onPushCPSTable.html index 7798c0f..fe029c6 100644 --- a/doc/nucleus/callbacks/push/onPushCPSTable.html +++ b/doc/nucleus/callbacks/push/onPushCPSTable.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/push/onPushRun.html b/doc/nucleus/callbacks/push/onPushRun.html index dbb9b2d..9efaa6b 100644 --- a/doc/nucleus/callbacks/push/onPushRun.html +++ b/doc/nucleus/callbacks/push/onPushRun.html @@ -54,8 +54,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=calculateNMR calculates the NMR signals for the full and partially saturated
  • caluclatePressureSaturation calculates the geometry dependent pressure
  • runInversionJoint controls the joint inversion process to infer a pore size
  • runInversionStd controls the standard inversion process to invert a
  • This function is called by: +
  • NUCLEUSinv_createPanelInversionJoint creates joint inversion panel
  • NUCLEUSinv_createPanelInversionStd creates standard inversion panel
  • NUCLEUSmod_createPanelCPS creates pressure panel
  • NUCLEUSmod_createPanelNMR creates NMR panel
  • onContextSignalList handles the calls from the context menu of the data
  • onListboxData handles the calls from the context menu of the data
  • onPushStop recognizes that a STOP push button was pressed and resets the
  • caluclatePressureSaturation calculates the geometry dependent pressure
  • runInversionBatch batch processes the inversion using for all NMR signals
  • runInversionJoint controls the joint inversion process to infer a pore size
  • runInversionStd controls the standard inversion process to invert a
  • @@ -100,8 +100,8 @@

    SOURCE CODE ^% calculateNMR 0028 % 0029 % See also: NUCLEUSinv -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/push/onPushShowHide.html b/doc/nucleus/callbacks/push/onPushShowHide.html index 1390482..a90cfa7 100644 --- a/doc/nucleus/callbacks/push/onPushShowHide.html +++ b/doc/nucleus/callbacks/push/onPushShowHide.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/push/onPushStop.html b/doc/nucleus/callbacks/push/onPushStop.html index 950fb37..5c6d797 100644 --- a/doc/nucleus/callbacks/push/onPushStop.html +++ b/doc/nucleus/callbacks/push/onPushStop.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/radio/onRadioGates.html b/doc/nucleus/callbacks/radio/onRadioGates.html index 193e5cc..6b576d9 100644 --- a/doc/nucleus/callbacks/radio/onRadioGates.html +++ b/doc/nucleus/callbacks/radio/onRadioGates.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/radio/onRadioLorder.html b/doc/nucleus/callbacks/radio/onRadioLorder.html index 35ac910..bc97afe 100644 --- a/doc/nucleus/callbacks/radio/onRadioLorder.html +++ b/doc/nucleus/callbacks/radio/onRadioLorder.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/radio/onRadioNormalize.html b/doc/nucleus/callbacks/radio/onRadioNormalize.html index 454d428..1ef34e5 100644 --- a/doc/nucleus/callbacks/radio/onRadioNormalize.html +++ b/doc/nucleus/callbacks/radio/onRadioNormalize.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/callbacks/radio/onRadioTimescale.html b/doc/nucleus/callbacks/radio/onRadioTimescale.html index c7ad599..5176a82 100644 --- a/doc/nucleus/callbacks/radio/onRadioTimescale.html +++ b/doc/nucleus/callbacks/radio/onRadioTimescale.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- @@ -127,68 +127,70 @@

    SOURCE CODE ^end -0059 -0060 case 'ms' -0061 data.process.timescale = 'ms'; -0062 if data.process.timefac == 1 -0063 data.process.timefac = 1000; -0064 data.invstd.time = data.invstd.time .* 1000; -0065 data.invstd.Tbulk = data.invstd.Tbulk .* 1000; -0066 end -0067 end -0068 -0069 % update GUI data -0070 setappdata(fig,'data',data); -0071 % update interface -0072 NUCLEUSinv_updateInterface; -0073 % process NMR signal -0074 processNMRDataControl(fig,id); -0075 % update plots -0076 updatePlotsSignal; -0077 % clear axes -0078 clearSingleAxis(gui.axes_handles.rtd); -0079 clearSingleAxis(gui.axes_handles.psd); -0080 % set focus on data -0081 set(gui.plots.SignalPanel,'Selection',1); -0082 -0083 else -0084 % reset to defaults -0085 data.process.timescale = 's'; -0086 % update GUI data -0087 setappdata(fig,'data',data); -0088 % update interface -0089 NUCLEUSinv_updateInterface; -0090 helpdlg('Nothing to do because no data set is selected!',... -0091 'onRadioTimescale: Select NMR data first.'); -0092 end -0093 +0058 data.invstd.Tdiff = data.invstd.Tdiff ./ 1000; +0059 end +0060 +0061 case 'ms' +0062 data.process.timescale = 'ms'; +0063 if data.process.timefac == 1 +0064 data.process.timefac = 1000; +0065 data.invstd.time = data.invstd.time .* 1000; +0066 data.invstd.Tbulk = data.invstd.Tbulk .* 1000; +0067 data.invstd.Tdiff = data.invstd.Tdiff .* 1000; +0068 end +0069 end +0070 +0071 % update GUI data +0072 setappdata(fig,'data',data); +0073 % update interface +0074 NUCLEUSinv_updateInterface; +0075 % process NMR signal +0076 processNMRDataControl(fig,id); +0077 % update plots +0078 updatePlotsSignal; +0079 % clear axes +0080 clearSingleAxis(gui.axes_handles.rtd); +0081 clearSingleAxis(gui.axes_handles.psd); +0082 % set focus on data +0083 set(gui.plots.SignalPanel,'Selection',1); +0084 +0085 else +0086 % reset to defaults +0087 data.process.timescale = 's'; +0088 % update GUI data +0089 setappdata(fig,'data',data); +0090 % update interface +0091 NUCLEUSinv_updateInterface; +0092 helpdlg('Nothing to do because no data set is selected!',... +0093 'onRadioTimescale: Select NMR data first.'); 0094 end 0095 -0096 %------------- END OF CODE -------------- +0096 end 0097 -0098 %% License: -0099 % MIT License -0100 % -0101 % Copyright (c) 2018 Thomas Hiller +0098 %------------- END OF CODE -------------- +0099 +0100 %% License: +0101 % MIT License 0102 % -0103 % Permission is hereby granted, free of charge, to any person obtaining a copy -0104 % of this software and associated documentation files (the "Software"), to deal -0105 % in the Software without restriction, including without limitation the rights -0106 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0107 % copies of the Software, and to permit persons to whom the Software is -0108 % furnished to do so, subject to the following conditions: -0109 % -0110 % The above copyright notice and this permission notice shall be included in all -0111 % copies or substantial portions of the Software. -0112 % -0113 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0114 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0115 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0116 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0117 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0118 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0119 % SOFTWARE. +0103 % Copyright (c) 2018 Thomas Hiller +0104 % +0105 % Permission is hereby granted, free of charge, to any person obtaining a copy +0106 % of this software and associated documentation files (the "Software"), to deal +0107 % in the Software without restriction, including without limitation the rights +0108 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0109 % copies of the Software, and to permit persons to whom the Software is +0110 % furnished to do so, subject to the following conditions: +0111 % +0112 % The above copyright notice and this permission notice shall be included in all +0113 % copies or substantial portions of the Software. +0114 % +0115 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0116 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0117 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0118 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0119 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0120 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0121 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/import/LoadNMRData_bamtom.html b/doc/nucleus/functions/import/LoadNMRData_bamtom.html index fb61596..6f3150d 100644 --- a/doc/nucleus/functions/import/LoadNMRData_bamtom.html +++ b/doc/nucleus/functions/import/LoadNMRData_bamtom.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSinv -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/LoadNMRData_bgr.html b/doc/nucleus/functions/import/LoadNMRData_bgr.html index ae440da..9286697 100644 --- a/doc/nucleus/functions/import/LoadNMRData_bgr.html +++ b/doc/nucleus/functions/import/LoadNMRData_bgr.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSinv -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/LoadNMRData_bgr2.html b/doc/nucleus/functions/import/LoadNMRData_bgr2.html index 0f4917a..fd41330 100644 --- a/doc/nucleus/functions/import/LoadNMRData_bgr2.html +++ b/doc/nucleus/functions/import/LoadNMRData_bgr2.html @@ -69,7 +69,7 @@

    CROSS-REFERENCE INFORMATION ^
 <li><a href=fixParameterString cleans parameter file lines when the properties have a
  • rotateT2phase rotateT2phase rotates the complex NMR T2 signal so that the imaginary
  • This function is called by: +

    SUBFUNCTIONS ^

    diff --git a/doc/nucleus/functions/import/LoadNMRData_bgrmat.html b/doc/nucleus/functions/import/LoadNMRData_bgrmat.html index c3b4d89..e8bb426 100644 --- a/doc/nucleus/functions/import/LoadNMRData_bgrmat.html +++ b/doc/nucleus/functions/import/LoadNMRData_bgrmat.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSinv -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/LoadNMRData_corelab.html b/doc/nucleus/functions/import/LoadNMRData_corelab.html index 95a3ab0..3696a9a 100644 --- a/doc/nucleus/functions/import/LoadNMRData_corelab.html +++ b/doc/nucleus/functions/import/LoadNMRData_corelab.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSinv -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/LoadNMRData_dart.html b/doc/nucleus/functions/import/LoadNMRData_dart.html index 673451c..2c987f7 100644 --- a/doc/nucleus/functions/import/LoadNMRData_dart.html +++ b/doc/nucleus/functions/import/LoadNMRData_dart.html @@ -58,8 +58,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0032 % 0033 % See also: NUCLEUSinv -0034 % Author: Thomas Hiller -0035 % email: thomas.hiller[at]leibniz-liag.de +0034 % Author: see AUTHORS.md +0035 % email: see AUTHORS.md 0036 % License: MIT License (at end) 0037 0038 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/LoadNMRData_driver.html b/doc/nucleus/functions/import/LoadNMRData_driver.html index 8344351..d264e57 100644 --- a/doc/nucleus/functions/import/LoadNMRData_driver.html +++ b/doc/nucleus/functions/import/LoadNMRData_driver.html @@ -54,8 +54,9 @@

    DESCRIPTION ^DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • LoadNMRData_bamtom loads BAM TOM data
  • LoadNMRData_bgr loads standard BGR NMR data
  • LoadNMRData_bgrmat loads already preprocessed BGR NMR data; check the
  • LoadNMRData_corelab loads NMR data as provided by Corelab
  • LoadNMRData_dart loads RWTH NMR data (recorded with the Dart device); the
  • LoadNMRData_field loads RWTH field NMR data (Blümich group bore-hole tool)
  • LoadNMRData_helios loads BGR NMR data from a typical folder structure
  • LoadNMRData_ibac imports NMR data from the PM5 and PM25
  • LoadNMRData_liag loads LIAG NMR data
  • LoadNMRData_mouse loads NMR data saved by the MOUSE
  • LoadNMRData_mouselift loads NMR Mouse data from an original folder structure as
  • LoadNMRData_rwth loads RWTH NMR data (saved by the old Prospa version)
  • fitDataFree is a control routine that uses 'lsqcurvefit' to fit NMR data
  • This function is called by: @@ -111,93 +112,100 @@

    SOURCE CODE ^% LoadNMRData_mouse 0028 % LoadNMRData_liag 0029 % LoadNMRData_bgr -0030 % LoadNMRData_bgr2 +0030 % LoadNMRData_mousecpmg 0031 % LoadNMRData_bgrmat -0032 % LoadNMRData_bamtom -0033 % -0034 % Subfunctions: -0035 % none -0036 % -0037 % MAT-files required: -0038 % none -0039 % -0040 % See also: NUCLEUSinv -0041 % Author: Thomas Hiller -0042 % email: thomas.hiller[at]leibniz-liag.de -0043 % License: MIT License (at end) -0044 -0045 %------------- BEGIN CODE -------------- -0046 -0047 %% select the routine depending on the file format -0048 switch in.fileformat -0049 case 'bamtom' -0050 out = LoadNMRData_bamtom(in); -0051 case 'bgr' -0052 out = LoadNMRData_bgr(in); -0053 case 'bgr2' -0054 out = LoadNMRData_bgr2(in); -0055 case 'bgrmat' -0056 out = LoadNMRData_bgrmat(in); -0057 case 'corelab' -0058 out = LoadNMRData_corelab(in); -0059 case 'dart' -0060 in.version = 2; % use the updated mat-file format -0061 out = LoadNMRData_dart(in); -0062 case 'field' -0063 out = LoadNMRData_field(in); -0064 case 'liag' -0065 out = LoadNMRData_liag(in); -0066 case 'mouse' -0067 out = LoadNMRData_mouse(in); -0068 case 'rwth' -0069 out = LoadNMRData_rwth(in); -0070 case 'pm5' -0071 out = LoadNMRData_ibac(in); -0072 case 'pm25' -0073 out = LoadNMRData_ibac(in); -0074 end -0075 -0076 % if an imported T2 signal has no imaginary part, the noise is estimated -0077 % from an exponential fit -0078 for i = 1:numel(out.nmrData) -0079 if strcmp(out.nmrData{i}.flag,'T2') && isreal(out.nmrData{i}.signal) -0080 disp('NUCLUESinv import: Estimating noise from exponential fit ...'); -0081 param.T1IRfac = out.nmrData{i}.T1IRfac; -0082 param.noise = 0; -0083 param.optim = 'off'; -0084 invstd = fitDataFree(out.nmrData{i}.time,out.nmrData{i}.signal,... -0085 'T2',param,5); -0086 out.nmrData{i}.noise = invstd.rms; -0087 disp('NUCLUESinv import: done.') -0088 end -0089 end -0090 -0091 return -0092 -0093 %------------- END OF CODE -------------- -0094 -0095 %% License: -0096 % MIT License -0097 % -0098 % Copyright (c) 2018 Thomas Hiller -0099 % -0100 % Permission is hereby granted, free of charge, to any person obtaining a copy -0101 % of this software and associated documentation files (the "Software"), to deal -0102 % in the Software without restriction, including without limitation the rights -0103 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0104 % copies of the Software, and to permit persons to whom the Software is -0105 % furnished to do so, subject to the following conditions: +0032 % LoadNMRData_helios +0033 % LoadNMRData_bamtom +0034 % +0035 % Subfunctions: +0036 % none +0037 % +0038 % MAT-files required: +0039 % none +0040 % +0041 % See also: NUCLEUSinv +0042 % Author: see AUTHORS.md +0043 % email: see AUTHORS.md +0044 % License: MIT License (at end) +0045 +0046 %------------- BEGIN CODE -------------- +0047 +0048 %% select the routine depending on the file format +0049 switch in.fileformat +0050 case 'bamtom' +0051 out = LoadNMRData_bamtom(in); +0052 case 'bgr' +0053 out = LoadNMRData_bgr(in); +0054 case 'MouseCPMG' +0055 out = LoadNMRData_mousecpmg(in); +0056 case 'bgrmat' +0057 out = LoadNMRData_bgrmat(in); +0058 case {'MouseLiftSingle','MouseLiftAll'} +0059 out = LoadNMRData_mouselift(in); +0060 case 'helios' +0061 out = LoadNMRData_helios(in); +0062 case 'corelab' +0063 out = LoadNMRData_corelab(in); +0064 case 'dart' +0065 in.version = 2; % use the updated mat-file format +0066 out = LoadNMRData_dart(in); +0067 case 'field' +0068 out = LoadNMRData_field(in); +0069 case 'liag' +0070 out = LoadNMRData_liag(in); +0071 case 'mouse' +0072 out = LoadNMRData_mouse(in); +0073 case 'rwth' +0074 out = LoadNMRData_rwth(in); +0075 case 'pm5' +0076 out = LoadNMRData_ibac(in); +0077 case 'pm25' +0078 out = LoadNMRData_ibac(in); +0079 end +0080 +0081 % if an imported T2 signal has no imaginary part, the noise is estimated +0082 % from an exponential fit +0083 if ~strcmp(in.fileformat,'helios') +0084 for i = 1:numel(out.nmrData) +0085 if isreal(out.nmrData{i}.signal) +0086 disp('NUCLUESinv import: Estimating noise from exponential fit ...'); +0087 param.T1IRfac = out.nmrData{i}.T1IRfac; +0088 param.noise = 0; +0089 param.optim = 'off'; +0090 invstd = fitDataFree(out.nmrData{i}.time,out.nmrData{i}.signal,... +0091 out.nmrData{i}.flag,param,5); +0092 out.nmrData{i}.noise = invstd.rms; +0093 disp('NUCLUESinv import: done.') +0094 end +0095 end +0096 end +0097 +0098 return +0099 +0100 %------------- END OF CODE -------------- +0101 +0102 %% License: +0103 % MIT License +0104 % +0105 % Copyright (c) 2018 Thomas Hiller 0106 % -0107 % The above copyright notice and this permission notice shall be included in all -0108 % copies or substantial portions of the Software. -0109 % -0110 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0111 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0112 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0113 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0114 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0115 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0116 % SOFTWARE. +0107 % Permission is hereby granted, free of charge, to any person obtaining a copy +0108 % of this software and associated documentation files (the "Software"), to deal +0109 % in the Software without restriction, including without limitation the rights +0110 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0111 % copies of the Software, and to permit persons to whom the Software is +0112 % furnished to do so, subject to the following conditions: +0113 % +0114 % The above copyright notice and this permission notice shall be included in all +0115 % copies or substantial portions of the Software. +0116 % +0117 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0118 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0119 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0120 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0121 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0122 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0123 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/import/LoadNMRData_field.html b/doc/nucleus/functions/import/LoadNMRData_field.html index c5df338..fffb32a 100644 --- a/doc/nucleus/functions/import/LoadNMRData_field.html +++ b/doc/nucleus/functions/import/LoadNMRData_field.html @@ -57,8 +57,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0031 % 0032 % See also: NUCLEUSinv -0033 % Author: Thomas Hiller -0034 % email: thomas.hiller[at]leibniz-liag.de +0033 % Author: see AUTHORS.md +0034 % email: see AUTHORS.md 0035 % License: MIT License (at end) 0036 0037 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/LoadNMRData_helios.html b/doc/nucleus/functions/import/LoadNMRData_helios.html new file mode 100644 index 0000000..42ebcea --- /dev/null +++ b/doc/nucleus/functions/import/LoadNMRData_helios.html @@ -0,0 +1,195 @@ + + + + Description of LoadNMRData_helios + + + + + + + + + + + +

    LoadNMRData_helios +

    + +

    PURPOSE ^

    +
    loads BGR NMR data from a typical folder structure
    + +

    SYNOPSIS ^

    +
    function out = LoadNMRData_helios(in)
    + +

    DESCRIPTION ^

    +
    LoadNMRData_helios loads BGR NMR data from a typical folder structure 
    +produced by the Helios NMR Scanner 
    +
    + Syntax:
    +       out = LoadNMRData_helios(in)
    +
    + Inputs:
    +       in - input structure
    +       in.path - data path
    +       in.T1T2 - T1 / T2 flag
    +       in.fileformat - 'helios'
    +
    + Outputs:
    +       out - output structure
    +       out.parData - parameter file data
    +       out.nmrData - NMR data
    +
    + Example:
    +       out = LoadNMRData_helios(in)
    +
    + Other m-files required:
    +       fixParameterString
    +
    + Subfunctions:
    +       LoadDataFile
    +
    + MAT-files required:
    +       none
    +
    + See also: NUCLEUSinv
    + Author: see AUTHORS.md
    + email: see AUTHORS.md
    + License: MIT License (at end)
    + + +

    CROSS-REFERENCE INFORMATION ^

    +This function calls: +
      +
    • rotateT2phase rotateT2phase rotates the complex NMR T2 signal so that the imaginary
    +This function is called by: + + + +

    SUBFUNCTIONS ^

    + + +

    SOURCE CODE ^

    +
    0001 function out = LoadNMRData_helios(in)
    +0002 %LoadNMRData_helios loads BGR NMR data from a typical folder structure
    +0003 %produced by the Helios NMR Scanner
    +0004 %
    +0005 % Syntax:
    +0006 %       out = LoadNMRData_helios(in)
    +0007 %
    +0008 % Inputs:
    +0009 %       in - input structure
    +0010 %       in.path - data path
    +0011 %       in.T1T2 - T1 / T2 flag
    +0012 %       in.fileformat - 'helios'
    +0013 %
    +0014 % Outputs:
    +0015 %       out - output structure
    +0016 %       out.parData - parameter file data
    +0017 %       out.nmrData - NMR data
    +0018 %
    +0019 % Example:
    +0020 %       out = LoadNMRData_helios(in)
    +0021 %
    +0022 % Other m-files required:
    +0023 %       fixParameterString
    +0024 %
    +0025 % Subfunctions:
    +0026 %       LoadDataFile
    +0027 %
    +0028 % MAT-files required:
    +0029 %       none
    +0030 %
    +0031 % See also: NUCLEUSinv
    +0032 % Author: see AUTHORS.md
    +0033 % email: see AUTHORS.md
    +0034 % License: MIT License (at end)
    +0035 
    +0036 %------------- BEGIN CODE --------------
    +0037 
    +0038 %% start processing the files
    +0039 
    +0040 % read the data file
    +0041 datafile = dir(fullfile(in.path,in.name));
    +0042 [data,parData] = LoadDataFile(in.path,in.name,in.T1T2);
    +0043 
    +0044 % get file statistics
    +0045 nmrData.datfile = datafile.name;
    +0046 nmrData.date = datafile.date;
    +0047 nmrData.datenum = datafile.datenum;
    +0048 nmrData.bytes = datafile.bytes;
    +0049 
    +0050 % save the NMR data
    +0051 nmrData.flag = data.flag;
    +0052 nmrData.T1IRfac = 1;
    +0053 nmrData.time = data.time;
    +0054 nmrData.signal = data.signal;
    +0055 nmrData.raw = data.raw;
    +0056 if strcmp(in.T1T2,'T2')
    +0057     nmrData.phase = data.phase;
    +0058 end
    +0059 
    +0060 % save data to output struct
    +0061 out.parData = parData;
    +0062 out.nmrData = nmrData;
    +0063 
    +0064 end
    +0065 
    +0066 %% load NMR data file
    +0067 function [data,pardata] = LoadDataFile(datapath,fname,flag)
    +0068 
    +0069 A = importdata(fullfile(datapath,fname),'\t');
    +0070 t_echo = A(1,2);
    +0071 n_echo = A(1,3);
    +0072 
    +0073 time = t_echo:t_echo:t_echo*n_echo;
    +0074 time = time(:);
    +0075 re = -A(2,1:length(time));
    +0076 im = -A(3,1:length(time));
    +0077 re = re(:);
    +0078 im = im(:);
    +0079 
    +0080 data.flag = flag;
    +0081 data.time = time;
    +0082 data.signal = complex(re,im);
    +0083 [data.signal,data.phase] = rotateT2phase(data.signal);
    +0084 
    +0085 data.raw.time = data.time;
    +0086 data.raw.signal = data.signal;
    +0087 
    +0088 pardata.t_echo = t_echo; 
    +0089 pardata.n_echo = n_echo; 
    +0090 
    +0091 end
    +0092 %------------- END OF CODE --------------
    +0093 
    +0094 %% License:
    +0095 % MIT License
    +0096 %
    +0097 % Copyright (c) 2021 Stephan Costabel
    +0098 %
    +0099 % Permission is hereby granted, free of charge, to any person obtaining a copy
    +0100 % of this software and associated documentation files (the "Software"), to deal
    +0101 % in the Software without restriction, including without limitation the rights
    +0102 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +0103 % copies of the Software, and to permit persons to whom the Software is
    +0104 % furnished to do so, subject to the following conditions:
    +0105 %
    +0106 % The above copyright notice and this permission notice shall be included in all
    +0107 % copies or substantial portions of the Software.
    +0108 %
    +0109 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +0110 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +0111 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +0112 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +0113 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +0114 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +0115 % SOFTWARE.
    +
    Generated by m2html © 2005
    + + \ No newline at end of file diff --git a/doc/nucleus/functions/import/LoadNMRData_ibac.html b/doc/nucleus/functions/import/LoadNMRData_ibac.html index ff41bbd..3a0a2bc 100644 --- a/doc/nucleus/functions/import/LoadNMRData_ibac.html +++ b/doc/nucleus/functions/import/LoadNMRData_ibac.html @@ -59,8 +59,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0033 % 0034 % See also: NUCLEUSinv -0035 % Author: Thomas Hiller -0036 % email: thomas.hiller[at]leibniz-liag.de +0035 % Author: see AUTHORS.md +0036 % email: see AUTHORS.md 0037 % License: MIT License (at end) 0038 0039 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/LoadNMRData_liag.html b/doc/nucleus/functions/import/LoadNMRData_liag.html index 9c9a4eb..6b3f19d 100644 --- a/doc/nucleus/functions/import/LoadNMRData_liag.html +++ b/doc/nucleus/functions/import/LoadNMRData_liag.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: NUCLEUSinv -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/LoadNMRData_mouse.html b/doc/nucleus/functions/import/LoadNMRData_mouse.html index cce8ec3..7000acd 100644 --- a/doc/nucleus/functions/import/LoadNMRData_mouse.html +++ b/doc/nucleus/functions/import/LoadNMRData_mouse.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: NUCLEUSinv -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- @@ -210,7 +210,7 @@

    SOURCE CODE ^%% License: 0135 % MIT License 0136 % -0137 % Copyright (c) 2018 Thomas Hiller +0137 % Copyright (c) 2021 Stephan Costabel 0138 % 0139 % Permission is hereby granted, free of charge, to any person obtaining a copy 0140 % of this software and associated documentation files (the "Software"), to deal diff --git a/doc/nucleus/functions/import/LoadNMRData_mouselift.html b/doc/nucleus/functions/import/LoadNMRData_mouselift.html new file mode 100644 index 0000000..5fe5694 --- /dev/null +++ b/doc/nucleus/functions/import/LoadNMRData_mouselift.html @@ -0,0 +1,232 @@ + + + + Description of LoadNMRData_mouselift + + + + + + + + + + + +

    LoadNMRData_mouselift +

    + +

    PURPOSE ^

    +
    loads NMR Mouse data from an original folder structure as
    + +

    SYNOPSIS ^

    +
    function out = LoadNMRData_mouselift(in)
    + +

    DESCRIPTION ^

    +
    LoadNMRData_mouselift loads NMR Mouse data from an original folder structure as
    +generated by the NMR MOUSE when using it wogether with the lift
    +
    + Syntax:
    +       out = LoadNMRData_mouselift(in)
    +
    + Inputs:
    +       in - input structure
    +       in.path - data path
    +       in.T1T2 - T1 / T2 flag
    +       in.fileformat - 'mouse'
    +
    + Outputs:
    +       out - output structure
    +       out.parData - parameter file data
    +       out.nmrData - NMR data
    +
    + Example:
    +       out = LoadNMRData_mouselift(in)
    +
    + Other m-files required:
    +       fixParameterString
    +
    + Subfunctions:
    +       LoadDataFile
    +       LoadParameterFile
    +
    + MAT-files required:
    +       none
    +
    + See also: NUCLEUSinv
    + Author: see AUTHORS.md
    + email: see AUTHORS.md
    + License: MIT License (at end)
    + + +

    CROSS-REFERENCE INFORMATION ^

    +This function calls: +
      +
    • fixParameterString cleans parameter file lines when the properties have a
    • rotateT2phase rotateT2phase rotates the complex NMR T2 signal so that the imaginary
    +This function is called by: + + + +

    SUBFUNCTIONS ^

    + + +

    SOURCE CODE ^

    +
    0001 function out = LoadNMRData_mouselift(in)
    +0002 %LoadNMRData_mouselift loads NMR Mouse data from an original folder structure as
    +0003 %generated by the NMR MOUSE when using it wogether with the lift
    +0004 %
    +0005 % Syntax:
    +0006 %       out = LoadNMRData_mouselift(in)
    +0007 %
    +0008 % Inputs:
    +0009 %       in - input structure
    +0010 %       in.path - data path
    +0011 %       in.T1T2 - T1 / T2 flag
    +0012 %       in.fileformat - 'mouse'
    +0013 %
    +0014 % Outputs:
    +0015 %       out - output structure
    +0016 %       out.parData - parameter file data
    +0017 %       out.nmrData - NMR data
    +0018 %
    +0019 % Example:
    +0020 %       out = LoadNMRData_mouselift(in)
    +0021 %
    +0022 % Other m-files required:
    +0023 %       fixParameterString
    +0024 %
    +0025 % Subfunctions:
    +0026 %       LoadDataFile
    +0027 %       LoadParameterFile
    +0028 %
    +0029 % MAT-files required:
    +0030 %       none
    +0031 %
    +0032 % See also: NUCLEUSinv
    +0033 % Author: see AUTHORS.md
    +0034 % email: see AUTHORS.md
    +0035 % License: MIT License (at end)
    +0036 
    +0037 %------------- BEGIN CODE --------------
    +0038 
    +0039 %% start processing the files
    +0040 % load Parameter file
    +0041 [parData] = LoadParameterFile(in.path,'acq.par');
    +0042 
    +0043 % find all data files
    +0044 files = dir(fullfile(in.path,'*.dat'));
    +0045 
    +0046 % remove not needed dat-files
    +0047 switch in.T1T2
    +0048     case 'T1'
    +0049         files = files(~ismember({files.name},...
    +0050             {'data2D.dat','T1Axis.dat'}));
    +0051     case 'T2'
    +0052         files = files(~ismember({files.name},...
    +0053             {'data2D.dat','T2Axis.dat'}));
    +0054 end
    +0055 
    +0056 nmrData = cell(1,size(files,1));
    +0057 for i = 1:size(files,1)
    +0058     % read the data file
    +0059     data  = LoadDataFile(in.path,files(i).name,in.T1T2);
    +0060     
    +0061     % get file statistics
    +0062     nmrData{i}.datfile = files(i).name;
    +0063     nmrData{i}.date = files(i).date;
    +0064     nmrData{i}.datenum = files(i).datenum;
    +0065     nmrData{i}.bytes = files(i).bytes;
    +0066     
    +0067     % save the NMR data
    +0068     nmrData{i}.flag = data.flag;
    +0069     nmrData{i}.T1IRfac = 1;
    +0070     nmrData{i}.time = data.time;
    +0071     nmrData{i}.signal = data.signal;
    +0072     nmrData{i}.raw = data.raw;
    +0073     if strcmp(in.T1T2,'T2')
    +0074         nmrData{i}.phase = data.phase;
    +0075     end
    +0076     clear data
    +0077 end
    +0078 
    +0079 % save data to output struct
    +0080 out.parData = parData;
    +0081 out.nmrData = nmrData;
    +0082 
    +0083 end
    +0084 
    +0085 %% load NMR data file
    +0086 function [data] = LoadDataFile(datapath,fname,flag)
    +0087 
    +0088 d = load(fullfile(datapath,fname));
    +0089 
    +0090 if size(d,2) == 3
    +0091     data.flag = flag;
    +0092     data.time = d(:,1);
    +0093     switch flag
    +0094         case 'T1'
    +0095             data.signal = d(:,2);
    +0096         case 'T2'
    +0097             data.signal = complex(d(:,2),d(:,3));
    +0098             [data.signal,data.phase] = rotateT2phase(data.signal);
    +0099     end
    +0100 else
    +0101     data.flag = '0';
    +0102     data.time = 0;
    +0103     data.signal = 0;
    +0104     data.phase = 0;
    +0105 end
    +0106 
    +0107 data.raw.time = data.time;
    +0108 data.raw.signal = data.signal;
    +0109 
    +0110 end
    +0111 
    +0112 %% load parameter file
    +0113 function [data] = LoadParameterFile(datapath,fname)
    +0114 
    +0115 fid = fopen(fullfile(datapath,fname));
    +0116 d = textscan(fid,'%s','Delimiter','\n');
    +0117 fclose(fid);
    +0118 
    +0119 for i = 1:size(d{1},1)
    +0120     str = char(d{1}(i));
    +0121     str = fixParameterString(str);
    +0122     eval(['data.',str,';']);
    +0123 end
    +0124 data.all = d;
    +0125 
    +0126 end
    +0127 
    +0128 %------------- END OF CODE --------------
    +0129 
    +0130 %% License:
    +0131 % MIT License
    +0132 %
    +0133 % Copyright (c) 2021 Stephan Costabel
    +0134 %
    +0135 % Permission is hereby granted, free of charge, to any person obtaining a copy
    +0136 % of this software and associated documentation files (the "Software"), to deal
    +0137 % in the Software without restriction, including without limitation the rights
    +0138 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +0139 % copies of the Software, and to permit persons to whom the Software is
    +0140 % furnished to do so, subject to the following conditions:
    +0141 %
    +0142 % The above copyright notice and this permission notice shall be included in all
    +0143 % copies or substantial portions of the Software.
    +0144 %
    +0145 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +0146 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +0147 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +0148 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +0149 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +0150 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +0151 % SOFTWARE.
    +
    Generated by m2html © 2005
    + + \ No newline at end of file diff --git a/doc/nucleus/functions/import/LoadNMRData_rwth.html b/doc/nucleus/functions/import/LoadNMRData_rwth.html index 551e87b..4c0fcd9 100644 --- a/doc/nucleus/functions/import/LoadNMRData_rwth.html +++ b/doc/nucleus/functions/import/LoadNMRData_rwth.html @@ -57,15 +57,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • fixParameterString cleans parameter file lines when the properties have a
  • rotateT2phase rotateT2phase rotates the complex NMR T2 signal so that the imaginary
  • displayStatusText shows status information either in the GUI or on the
  • This function is called by: @@ -108,8 +108,8 @@

    SOURCE CODE ^% none 0031 % 0032 % See also: NUCLEUSinv -0033 % Author: Thomas Hiller -0034 % email: thomas.hiller[at]leibniz-liag.de +0033 % Author: see AUTHORS.md +0034 % email: see AUTHORS.md 0035 % License: MIT License (at end) 0036 0037 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/fixParameterString.html b/doc/nucleus/functions/import/fixParameterString.html index c5a5080..94844f9 100644 --- a/doc/nucleus/functions/import/fixParameterString.html +++ b/doc/nucleus/functions/import/fixParameterString.html @@ -51,8 +51,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 </ul>
 This function is called by:
 <ul style= -
  • LoadNMRData_bamtom loads BAM TOM data
  • LoadNMRData_bgr loads standard BGR NMR data
  • LoadNMRData_bgr2 loads BGR NMR data from an original folder structure as
  • LoadNMRData_field loads RWTH field NMR data (Blümich group bore-hole tool)
  • LoadNMRData_ibac imports NMR data from the PM5 and PM25
  • LoadNMRData_liag loads LIAG NMR data
  • LoadNMRData_mouse loads NMR data saved by the MOUSE
  • LoadNMRData_rwth loads RWTH NMR data (saved by the old Prospa version)
  • importNMRdata is the general import routine for NMR data
  • +
  • LoadNMRData_bamtom loads BAM TOM data
  • LoadNMRData_bgr loads standard BGR NMR data
  • LoadNMRData_bgr2 loads BGR NMR data from an original folder structure as
  • LoadNMRData_field loads RWTH field NMR data (Blümich group bore-hole tool)
  • LoadNMRData_ibac imports NMR data from the PM5 and PM25
  • LoadNMRData_liag loads LIAG NMR data
  • LoadNMRData_mouse loads NMR data saved by the MOUSE
  • LoadNMRData_mouselift loads NMR Mouse data from an original folder structure as
  • LoadNMRData_rwth loads RWTH NMR data (saved by the old Prospa version)
  • importNMRdata is the general import routine for NMR data
  • @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/import/menu.html b/doc/nucleus/functions/import/menu.html index 4f497f3..af10a67 100644 --- a/doc/nucleus/functions/import/menu.html +++ b/doc/nucleus/functions/import/menu.html @@ -18,7 +18,7 @@

    Index for nucleus\functions\import

    Matlab files in this directory:

    +
  • LoadNMRData_bamtom
  • LoadNMRData_bgr
  • LoadNMRData_bgr2
  • LoadNMRData_bgrmat
  • LoadNMRData_corelab
  • LoadNMRData_dart
  • LoadNMRData_driver
  • LoadNMRData_field
  • LoadNMRData_helios
  • LoadNMRData_ibac
  • LoadNMRData_liag
  • LoadNMRData_mouse
  • LoadNMRData_mouselift
  • LoadNMRData_rwth
  • fixParameterString
  • rotateT2phase
  • diff --git a/doc/nucleus/functions/import/rotateT2phase.html b/doc/nucleus/functions/import/rotateT2phase.html index f31c946..2a5c8a1 100644 --- a/doc/nucleus/functions/import/rotateT2phase.html +++ b/doc/nucleus/functions/import/rotateT2phase.html @@ -52,8 +52,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 </ul>
 This function is called by:
 <ul style= -
  • LoadNMRData_bamtom loads BAM TOM data
  • LoadNMRData_bgr loads standard BGR NMR data
  • LoadNMRData_bgr2 loads BGR NMR data from an original folder structure as
  • LoadNMRData_bgrmat loads already preprocessed BGR NMR data; check the
  • LoadNMRData_corelab loads NMR data as provided by Corelab
  • LoadNMRData_field loads RWTH field NMR data (Blümich group bore-hole tool)
  • LoadNMRData_ibac imports NMR data from the PM5 and PM25
  • LoadNMRData_liag loads LIAG NMR data
  • LoadNMRData_mouse loads NMR data saved by the MOUSE
  • LoadNMRData_rwth loads RWTH NMR data (saved by the old Prospa version)
  • importASCIIdata imports NMR data from ASCII files
  • importEXCELdata imports NMR data from Excel files
  • importNMRdata is the general import routine for NMR data
  • +
  • LoadNMRData_bamtom loads BAM TOM data
  • LoadNMRData_bgr loads standard BGR NMR data
  • LoadNMRData_bgr2 loads BGR NMR data from an original folder structure as
  • LoadNMRData_bgrmat loads already preprocessed BGR NMR data; check the
  • LoadNMRData_corelab loads NMR data as provided by Corelab
  • LoadNMRData_field loads RWTH field NMR data (Blümich group bore-hole tool)
  • LoadNMRData_helios loads BGR NMR data from a typical folder structure
  • LoadNMRData_ibac imports NMR data from the PM5 and PM25
  • LoadNMRData_liag loads LIAG NMR data
  • LoadNMRData_mouse loads NMR data saved by the MOUSE
  • LoadNMRData_mouselift loads NMR Mouse data from an original folder structure as
  • LoadNMRData_rwth loads RWTH NMR data (saved by the old Prospa version)
  • importASCIIdata imports NMR data from ASCII files
  • importEXCELdata imports NMR data from Excel files
  • importNMRdata is the general import routine for NMR data
  • SUBFUNCTIONS ^

    @@ -98,8 +98,8 @@

    SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/ConductView.html b/doc/nucleus/functions/interface/ConductView.html index b347b5d..e38b508 100644 --- a/doc/nucleus/functions/interface/ConductView.html +++ b/doc/nucleus/functions/interface/ConductView.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: NUCLEUSmod, NUCLEUSinv -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/PhaseView.html b/doc/nucleus/functions/interface/PhaseView.html index d6d1c13..68bd035 100644 --- a/doc/nucleus/functions/interface/PhaseView.html +++ b/doc/nucleus/functions/interface/PhaseView.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: NUCLEUSinv -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/beautifyAxes.html b/doc/nucleus/functions/interface/beautifyAxes.html index abfedfc..86d5663 100644 --- a/doc/nucleus/functions/interface/beautifyAxes.html +++ b/doc/nucleus/functions/interface/beautifyAxes.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv, NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/calculateGeometry.html b/doc/nucleus/functions/interface/calculateGeometry.html index 3c03d1f..28ce2e2 100644 --- a/doc/nucleus/functions/interface/calculateGeometry.html +++ b/doc/nucleus/functions/interface/calculateGeometry.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSmod -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/calculateGuiOnMonitorPosition.html b/doc/nucleus/functions/interface/calculateGuiOnMonitorPosition.html index 38f644a..a030a50 100644 --- a/doc/nucleus/functions/interface/calculateGuiOnMonitorPosition.html +++ b/doc/nucleus/functions/interface/calculateGuiOnMonitorPosition.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv, NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- @@ -103,66 +103,52 @@

    SOURCE CODE ^%% get the monitor layout 0034 scr = get(0,'MonitorPosition'); 0035 if size(scr,1) > 1 -0036 ind = find(scr(:,1)==1 & scr(:,2)==1); -0037 sw = scr(ind,3); % width -0038 sh = scr(ind,4); % height -0039 else -0040 sw = scr(3); % width -0041 sh = scr(4); % height -0042 end -0043 -0044 %% positioning of the GUI -0045 if numel(scr) > 4 -0046 % dual screen mode -0047 % GUI on second screen -0048 gh = 730; % reference height -0049 gw = ceil(gh*aspect_ratio); % reference width (1152) -0050 if any(scr(:,1)<0) -0051 pos = [-sw+(sw-gw)/2 (sh-gh)/3 gw gh]; -0052 else -0053 pos = [sw+(sw-gw)/2 (sh-gh)/3 gw gh]; -0054 end -0055 % if any screen is smaller than 800 -0056 if any(scr(:,4)<800) -0057 pos = [(sw-gw)/2 (sh-gh)/3 gw gh]; -0058 end -0059 else -0060 % single screen mode -0061 if any(scr(:,4)<800) -0062 gh = 600; % reference height for small screens -0063 else -0064 gh = 730; % reference height -0065 end -0066 gw = ceil(gh*aspect_ratio); % reference width (960) -0067 pos = [(sw-gw)/2 (sh-gh)/2 gw gh]; -0068 end -0069 -0070 return -0071 -0072 %------------- END OF CODE -------------- -0073 -0074 % License: -0075 % MIT License -0076 % -0077 % Copyright (c) 2018 Thomas Hiller -0078 % -0079 % Permission is hereby granted, free of charge, to any person obtaining a copy -0080 % of this software and associated documentation files (the "Software"), to deal -0081 % in the Software without restriction, including without limitation the rights -0082 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0083 % copies of the Software, and to permit persons to whom the Software is -0084 % furnished to do so, subject to the following conditions: -0085 % -0086 % The above copyright notice and this permission notice shall be included in all -0087 % copies or substantial portions of the Software. -0088 % -0089 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0090 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0091 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0092 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0093 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0094 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0095 % SOFTWARE. +0036 % find main screen +0037 ind = find(scr(:,1)==1 & scr(:,2)==1); +0038 sw = scr(ind,3); % width +0039 sh = scr(ind,4); % height +0040 else +0041 sw = scr(3); % width +0042 sh = scr(4); % height +0043 end +0044 +0045 %% GUI positioning +0046 if any(sh<800) +0047 gh = 600; % reference height for small screens +0048 else +0049 gh = 730; % reference height +0050 end +0051 % reference width +0052 gw = ceil(gh*aspect_ratio); % 960 or 1152 +0053 % GUI position +0054 pos = round([(sw-gw)/2 (sh-gh)/3 gw gh]); +0055 +0056 return +0057 +0058 %------------- END OF CODE -------------- +0059 +0060 % License: +0061 % MIT License +0062 % +0063 % Copyright (c) 2018 Thomas Hiller +0064 % +0065 % Permission is hereby granted, free of charge, to any person obtaining a copy +0066 % of this software and associated documentation files (the "Software"), to deal +0067 % in the Software without restriction, including without limitation the rights +0068 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0069 % copies of the Software, and to permit persons to whom the Software is +0070 % furnished to do so, subject to the following conditions: +0071 % +0072 % The above copyright notice and this permission notice shall be included in all +0073 % copies or substantial portions of the Software. +0074 % +0075 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0076 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0077 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0078 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0079 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0080 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0081 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/calculateNMR.html b/doc/nucleus/functions/interface/calculateNMR.html index f9abbd4..0e20915 100644 --- a/doc/nucleus/functions/interface/calculateNMR.html +++ b/doc/nucleus/functions/interface/calculateNMR.html @@ -55,15 +55,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • displayStatusText shows status information either in the GUI or on the
  • updateNMRsignals adds noise to the forward NMR signals and scales the
  • updatePlotsNMR plots the forward modeled NMR data in NUCLEUSmod
  • getNMRSignal calculates the NMR signal of a fully or partially saturated
  • getNMRTimeVector Creates a NMR time vector depending on the given echo
  • This function is called by:
    • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
    @@ -102,8 +102,8 @@

    SOURCE CODE ^% none 0029 % 0030 % See also: NUCLEUSmod -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- @@ -119,62 +119,63 @@

    SOURCE CODE ^% generate a time vector from the echo time 'TE' and number of echoes 'echosN' 0046 nmr.t = getNMRTimeVector(data.nmr.TE,'µs','N',data.nmr.echosN); 0047 nmr.Tb = data.nmr.Tbulk; -0048 nmr.rho = data.nmr.rho/1e6; % µm/s to m/s -0049 -0050 % wait-bar option -0051 wbopts.show = true; -0052 wbopts.tag = 'MOD'; -0053 -0054 % disable the RUN button to indicate a running calculation -0055 set(gui.push_handles.nmr_RUN,'String','RUNNING ...','Enable','inactive'); -0056 -0057 % calculate the NMR signals for ALL pressure / saturation steps -0058 displayStatusText(gui,'Calculating NMR signals ... '); -0059 NMR = getNMRSignal(nmr,data.geometry.type,data.results.SAT,data.results.psddata,wbopts); -0060 % always keep a copy of the raw data (without noise) -0061 NMR.raw = NMR; -0062 -0063 % update the global GUI data -0064 data.results.NMR = NMR; -0065 setappdata(fig,'data',data); -0066 -0067 % add noise to the NMR signals -0068 updateNMRsignals; -0069 displayStatusText(gui,'Calculating NMR signals ... done'); -0070 updatePlotsNMR; -0071 % enable the RUN button again -0072 set(gui.push_handles.nmr_RUN,'String','RUN','Enable','on'); -0073 -0074 else -0075 helpdlg({'calculateNMR:','Create CPS data first.'}); -0076 end -0077 -0078 end -0079 -0080 %------------- END OF CODE -------------- -0081 -0082 %% License: -0083 % MIT License -0084 % -0085 % Copyright (c) 2018 Thomas Hiller -0086 % -0087 % Permission is hereby granted, free of charge, to any person obtaining a copy -0088 % of this software and associated documentation files (the "Software"), to deal -0089 % in the Software without restriction, including without limitation the rights -0090 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0091 % copies of the Software, and to permit persons to whom the Software is -0092 % furnished to do so, subject to the following conditions: -0093 % -0094 % The above copyright notice and this permission notice shall be included in all -0095 % copies or substantial portions of the Software. -0096 % -0097 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0098 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0099 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0100 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0101 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0102 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0103 % SOFTWARE. +0048 nmr.Td = data.nmr.Tdiff; +0049 nmr.rho = data.nmr.rho/1e6; % µm/s to m/s +0050 +0051 % wait-bar option +0052 wbopts.show = true; +0053 wbopts.tag = 'MOD'; +0054 +0055 % disable the RUN button to indicate a running calculation +0056 set(gui.push_handles.nmr_RUN,'String','RUNNING ...','Enable','inactive'); +0057 +0058 % calculate the NMR signals for ALL pressure / saturation steps +0059 displayStatusText(gui,'Calculating NMR signals ... '); +0060 NMR = getNMRSignal(nmr,data.geometry.type,data.results.SAT,data.results.psddata,wbopts); +0061 % always keep a copy of the raw data (without noise) +0062 NMR.raw = NMR; +0063 +0064 % update the global GUI data +0065 data.results.NMR = NMR; +0066 setappdata(fig,'data',data); +0067 +0068 % add noise to the NMR signals +0069 updateNMRsignals; +0070 displayStatusText(gui,'Calculating NMR signals ... done'); +0071 updatePlotsNMR; +0072 % enable the RUN button again +0073 set(gui.push_handles.nmr_RUN,'String','RUN','Enable','on'); +0074 +0075 else +0076 helpdlg({'calculateNMR:','Create CPS data first.'}); +0077 end +0078 +0079 end +0080 +0081 %------------- END OF CODE -------------- +0082 +0083 %% License: +0084 % MIT License +0085 % +0086 % Copyright (c) 2018 Thomas Hiller +0087 % +0088 % Permission is hereby granted, free of charge, to any person obtaining a copy +0089 % of this software and associated documentation files (the "Software"), to deal +0090 % in the Software without restriction, including without limitation the rights +0091 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0092 % copies of the Software, and to permit persons to whom the Software is +0093 % furnished to do so, subject to the following conditions: +0094 % +0095 % The above copyright notice and this permission notice shall be included in all +0096 % copies or substantial portions of the Software. +0097 % +0098 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0099 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0100 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0101 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0102 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0103 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0104 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/calibratePorosity.html b/doc/nucleus/functions/interface/calibratePorosity.html index eaec0ab..61353a6 100644 --- a/doc/nucleus/functions/interface/calibratePorosity.html +++ b/doc/nucleus/functions/interface/calibratePorosity.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/caluclatePressureSaturation.html b/doc/nucleus/functions/interface/caluclatePressureSaturation.html index ff71cb6..028a089 100644 --- a/doc/nucleus/functions/interface/caluclatePressureSaturation.html +++ b/doc/nucleus/functions/interface/caluclatePressureSaturation.html @@ -56,15 +56,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
  • clearSingleAxis clears an individual axis
  • displayStatusText shows status information either in the GUI or on the
  • updateCPSTable updates the CPS table in NUCLEUSmod
  • updatePlotsCPS plots the CPS curve into the corresponding NUCLEUSmod axis
  • getConstants provides some physical constants to the forward calculation
  • getSaturationFromPressureBatch
  • This function is called by:
    • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
    @@ -106,8 +106,8 @@

    SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSmod -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- @@ -164,57 +164,60 @@

    SOURCE CODE ^%% reset NMR plots 0088 clearSingleAxis(gui.axes_handles.nmr); 0089 displayStatusText(gui,'Calculating saturation ... done'); -0090 % enable the RUN button again +0090 % enable the pressure RUN button again 0091 set(gui.push_handles.press_RUN,'String','RUN','Enable','on'); -0092 % enable hydraulic conductivity GUI menu only for PSD data -0093 if data.geometry.ispsd -0094 set(gui.menu.view_conduct,'Enable','on'); -0095 else -0096 set(gui.menu.view_conduct,'Enable','off'); -0097 end -0098 -0099 end -0100 -0101 function [indd,indi] = getInitialSatLevels(SAT,N) -0102 % initially there are 5 saturation levels on each branch -0103 SatLevels = linspace(1/N,1,N); -0104 indd = zeros(size(SatLevels)); -0105 indi = zeros(size(SatLevels)); -0106 for i = 1:5 -0107 indd(i) = find(abs(SAT.Sdfull-SatLevels(i))==min(abs(SAT.Sdfull-SatLevels(i))),1,'last'); -0108 indi(i) = find(abs(SAT.Sifull-SatLevels(i))==min(abs(SAT.Sifull-SatLevels(i))),1,'last'); -0109 end -0110 indd = unique(indd); -0111 indi = unique(indi); -0112 % the full saturation one is always the first one -0113 indd(1) = 1; -0114 indi(1) = 1; -0115 end -0116 -0117 %------------- END OF CODE -------------- -0118 -0119 %% License: -0120 % MIT License -0121 % -0122 % Copyright (c) 2018 Thomas Hiller -0123 % -0124 % Permission is hereby granted, free of charge, to any person obtaining a copy -0125 % of this software and associated documentation files (the "Software"), to deal -0126 % in the Software without restriction, including without limitation the rights -0127 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0128 % copies of the Software, and to permit persons to whom the Software is -0129 % furnished to do so, subject to the following conditions: -0130 % -0131 % The above copyright notice and this permission notice shall be included in all -0132 % copies or substantial portions of the Software. +0092 % reset the NMR RUN button +0093 set(gui.push_handles.nmr_RUN,'String','RUN','Enable','on',... +0094 'BackgroundColor','g','Callback',@onPushRun); +0095 % enable hydraulic conductivity GUI menu only for PSD data +0096 if data.geometry.ispsd +0097 set(gui.menu.view_conduct,'Enable','on'); +0098 else +0099 set(gui.menu.view_conduct,'Enable','off'); +0100 end +0101 +0102 end +0103 +0104 function [indd,indi] = getInitialSatLevels(SAT,N) +0105 % initially there are 5 saturation levels on each branch +0106 SatLevels = linspace(1/N,1,N); +0107 indd = zeros(size(SatLevels)); +0108 indi = zeros(size(SatLevels)); +0109 for i = 1:5 +0110 indd(i) = find(abs(SAT.Sdfull-SatLevels(i))==min(abs(SAT.Sdfull-SatLevels(i))),1,'last'); +0111 indi(i) = find(abs(SAT.Sifull-SatLevels(i))==min(abs(SAT.Sifull-SatLevels(i))),1,'last'); +0112 end +0113 indd = unique(indd); +0114 indi = unique(indi); +0115 % the full saturation one is always the first one +0116 indd(1) = 1; +0117 indi(1) = 1; +0118 end +0119 +0120 %------------- END OF CODE -------------- +0121 +0122 %% License: +0123 % MIT License +0124 % +0125 % Copyright (c) 2018 Thomas Hiller +0126 % +0127 % Permission is hereby granted, free of charge, to any person obtaining a copy +0128 % of this software and associated documentation files (the "Software"), to deal +0129 % in the Software without restriction, including without limitation the rights +0130 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0131 % copies of the Software, and to permit persons to whom the Software is +0132 % furnished to do so, subject to the following conditions: 0133 % -0134 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0135 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0136 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0137 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0138 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0139 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0140 % SOFTWARE. +0134 % The above copyright notice and this permission notice shall be included in all +0135 % copies or substantial portions of the Software. +0136 % +0137 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0138 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0139 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0140 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0141 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0142 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0143 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/changeColorTheme.html b/doc/nucleus/functions/interface/changeColorTheme.html index 558c3cb..e25643e 100644 --- a/doc/nucleus/functions/interface/changeColorTheme.html +++ b/doc/nucleus/functions/interface/changeColorTheme.html @@ -58,8 +58,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=getColorTheme returns the colors of the selected color theme
  • makeINIfile creates or updates the ini-File
  • updatePlotsCPS plots the CPS curve into the corresponding NUCLEUSmod axis
  • updatePlotsDistribution plots the RTD and PSD curves into NUCLEUSinv
  • updatePlotsJointInversion plots the joint-inversion results in NUCLEUSinv
  • updatePlotsNMR plots the forward modeled NMR data in NUCLEUSmod
  • updatePlotsPSD plots the pore size distribution in NUCLEUSmod
  • updatePlotsSignal plots the raw and processed NMR signals in NUCLEUSinv
  • This function is called by: +
  • NUCLEUSinv_createGUI controls the creation of all GUI elements
  • onMenuExtraColor handles the color theme menu of both GUIs
  • @@ -108,8 +108,8 @@

    SOURCE CODE ^% none 0032 % 0033 % See also: NUCLEUSinv, NUCLEUSmod -0034 % Author: Thomas Hiller -0035 % email: thomas.hiller[at]leibniz-liag.de +0034 % Author: see AUTHORS.md +0035 % email: see AUTHORS.md 0036 % License: MIT License (at end) 0037 0038 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/checkIfInversionExists.html b/doc/nucleus/functions/interface/checkIfInversionExists.html index ee01a5f..50bec8a 100644 --- a/doc/nucleus/functions/interface/checkIfInversionExists.html +++ b/doc/nucleus/functions/interface/checkIfInversionExists.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/cleanupGUIData.html b/doc/nucleus/functions/interface/cleanupGUIData.html index ff131f5..cd3e468 100644 --- a/doc/nucleus/functions/interface/cleanupGUIData.html +++ b/doc/nucleus/functions/interface/cleanupGUIData.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: NUCLEUSinv -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/clearAllAxes.html b/doc/nucleus/functions/interface/clearAllAxes.html index eded74d..72ebb9f 100644 --- a/doc/nucleus/functions/interface/clearAllAxes.html +++ b/doc/nucleus/functions/interface/clearAllAxes.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv, NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/clearInversion.html b/doc/nucleus/functions/interface/clearInversion.html index 0b74d42..7921d54 100644 --- a/doc/nucleus/functions/interface/clearInversion.html +++ b/doc/nucleus/functions/interface/clearInversion.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: NUCLEUSinv -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/clearSingleAxis.html b/doc/nucleus/functions/interface/clearSingleAxis.html index 8c67355..97ff03f 100644 --- a/doc/nucleus/functions/interface/clearSingleAxis.html +++ b/doc/nucleus/functions/interface/clearSingleAxis.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/displayStatusText.html b/doc/nucleus/functions/interface/displayStatusText.html index e7faf54..a76d9bd 100644 --- a/doc/nucleus/functions/interface/displayStatusText.html +++ b/doc/nucleus/functions/interface/displayStatusText.html @@ -4,7 +4,7 @@ Description of displayStatusText - + @@ -20,13 +20,14 @@

    displayStatusText

    PURPOSE ^

    -
    clears all axes of a given figure
    +
    shows status information either in the GUI or on the

    SYNOPSIS ^

    function displayStatusText(gui,string)

    DESCRIPTION ^

    -
    displayStatusText clears all axes of a given figure
    +
    displayStatusText shows status information either in the GUI or on the
    +commandline
     
      Syntax:
            displayStatusText(gui,string)
    @@ -51,8 +52,8 @@ 

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 </ul>
 This function is called by:
 <ul style= -
  • NUCLEUSinv_createGUI controls the creation of all GUI elements
  • NUCLEUSmod_createGUI controls the creation of all GUI elements
  • LoadNMRData_rwth loads RWTH NMR data (saved by the old Prospa version)
  • calculateNMR calculates the NMR signals for the full and partially saturated
  • caluclatePressureSaturation calculates the geometry dependent pressure
  • exportData exports data from both GUIs into various formats
  • exportGraphics exports graphics from both GUIs into various formats
  • exportINV exports NUCLEUSinv GUI data to a mat-file
  • importCalibrationData
  • importNMRdata is the general import routine for NMR data
  • runInversionBatch batch processes the inversion using for all NMR signals
  • runInversionJoint controls the joint inversion process to infer a pore size
  • runInversionStd controls the standard inversion process to invert a
  • useSignalAsCalibration uses E0 as porosity calibration factor.
  • +
  • NUCLEUSinv_createGUI controls the creation of all GUI elements
  • NUCLEUSmod_createGUI controls the creation of all GUI elements
  • LoadNMRData_rwth loads RWTH NMR data (saved by the old Prospa version)
  • calculateNMR calculates the NMR signals for the full and partially saturated
  • caluclatePressureSaturation calculates the geometry dependent pressure
  • exportData exports data from both GUIs into various formats
  • exportGraphics exports graphics from both GUIs into various formats
  • exportINV exports NUCLEUSinv GUI data to a mat-file
  • importCalibrationData
  • importINV2INV imports a previously saved NUCLEUSinv session
  • importNMRdata is the general import routine for NMR data
  • runInversionBatch batch processes the inversion using for all NMR signals
  • runInversionJoint controls the joint inversion process to infer a pore size
  • runInversionStd controls the standard inversion process to invert a
  • useSignalAsCalibration uses E0 as porosity calibration factor.
  • estimateUncertainty calculates pseudo uncertainty estimates for multi
  • SOURCE CODE ^

    0001 function displayStatusText(gui,string)
    -0002 %displayStatusText clears all axes of a given figure
    -0003 %
    -0004 % Syntax:
    -0005 %       displayStatusText(gui,string)
    -0006 %
    -0007 % Inputs:
    -0008 %       gui - figure gui elements structure
    -0009 %       string - string to show in status bar
    -0010 %
    -0011 % Outputs:
    -0012 %       none
    -0013 %
    -0014 % Example:
    -0015 %       displayStatusText(gui,string)
    -0016 %
    -0017 % Other m-files required:
    -0018 %       none
    -0019 %
    -0020 % Subfunctions:
    -0021 %       none
    -0022 %
    -0023 % MAT-files required:
    -0024 %       none
    -0025 %
    -0026 % See also: NUCLEUSinv, NUCLEUSmod
    -0027 % Author: Thomas Hiller
    -0028 % email: thomas.hiller[at]leibniz-liag.de
    -0029 % License: MIT License (at end)
    -0030 
    -0031 %------------- BEGIN CODE --------------
    -0032 
    -0033 %% display status / info text
    -0034 set(gui.textStatus,'String',string);
    -0035 pause(0.001);
    -0036 
    -0037 end
    -0038 
    -0039 %------------- END OF CODE --------------
    -0040 
    -0041 %% License:
    -0042 % MIT License
    -0043 %
    -0044 % Copyright (c) 2018 Thomas Hiller
    -0045 %
    -0046 % Permission is hereby granted, free of charge, to any person obtaining a copy
    -0047 % of this software and associated documentation files (the "Software"), to deal
    -0048 % in the Software without restriction, including without limitation the rights
    -0049 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    -0050 % copies of the Software, and to permit persons to whom the Software is
    -0051 % furnished to do so, subject to the following conditions:
    -0052 %
    -0053 % The above copyright notice and this permission notice shall be included in all
    -0054 % copies or substantial portions of the Software.
    -0055 %
    -0056 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    -0057 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    -0058 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    -0059 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    -0060 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    -0061 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    -0062 % SOFTWARE.
    +0002 %displayStatusText shows status information either in the GUI or on the +0003 %commandline +0004 % +0005 % Syntax: +0006 % displayStatusText(gui,string) +0007 % +0008 % Inputs: +0009 % gui - figure gui elements structure +0010 % string - string to show in status bar +0011 % +0012 % Outputs: +0013 % none +0014 % +0015 % Example: +0016 % displayStatusText(gui,string) +0017 % +0018 % Other m-files required: +0019 % none +0020 % +0021 % Subfunctions: +0022 % none +0023 % +0024 % MAT-files required: +0025 % none +0026 % +0027 % See also: NUCLEUSinv, NUCLEUSmod +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md +0030 % License: MIT License (at end) +0031 +0032 %------------- BEGIN CODE -------------- +0033 +0034 %% display status / info text +0035 if isstruct(gui) +0036 set(gui.textStatus,'String',string); +0037 pause(0.001); +0038 else +0039 disp(string); +0040 end +0041 +0042 end +0043 +0044 %------------- END OF CODE -------------- +0045 +0046 %% License: +0047 % MIT License +0048 % +0049 % Copyright (c) 2018 Thomas Hiller +0050 % +0051 % Permission is hereby granted, free of charge, to any person obtaining a copy +0052 % of this software and associated documentation files (the "Software"), to deal +0053 % in the Software without restriction, including without limitation the rights +0054 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0055 % copies of the Software, and to permit persons to whom the Software is +0056 % furnished to do so, subject to the following conditions: +0057 % +0058 % The above copyright notice and this permission notice shall be included in all +0059 % copies or substantial portions of the Software. +0060 % +0061 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0062 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0063 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0064 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0065 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0066 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0067 % SOFTWARE.

    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/enableGUIelements.html b/doc/nucleus/functions/interface/enableGUIelements.html index 7bdc60b..0583b02 100644 --- a/doc/nucleus/functions/interface/enableGUIelements.html +++ b/doc/nucleus/functions/interface/enableGUIelements.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- @@ -124,7 +124,7 @@

    SOURCE CODE ^% process panel 0055 data.process.end = 0; 0056 switch data.import.fileformat -0057 case {'field','dart'} +0057 case {'dart','field','helios'} 0058 data.process.gatetype = 'raw'; 0059 otherwise 0060 data.process.gatetype = 'log'; diff --git a/doc/nucleus/functions/interface/exportData.html b/doc/nucleus/functions/interface/exportData.html index 7883cd9..96e5aae 100644 --- a/doc/nucleus/functions/interface/exportData.html +++ b/doc/nucleus/functions/interface/exportData.html @@ -56,15 +56,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • displayStatusText shows status information either in the GUI or on the
  • exportGraphics exports graphics from both GUIs into various formats
  • exportINV exports NUCLEUSinv GUI data to a mat-file
  • This function is called by: @@ -106,8 +106,8 @@

    SOURCE CODE ^% none 0030 % 0031 % See also: NUCLEUSinv, NUCLEUSmod -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- @@ -226,7 +226,7 @@

    SOURCE CODE ^'results'); 0150 0151 % save to file -0152 save(fullfile(spath,sfile),'idata'); +0152 save(fullfile(spath,sfile),'idata','-v7.3'); 0153 0154 % display info text 0155 displayStatusText(gui,... @@ -260,7 +260,7 @@

    SOURCE CODE ^'results'); 0184 0185 % save to file -0186 save(fullfile(spath,sfile),'idata'); +0186 save(fullfile(spath,sfile),'idata','-v7.3'); 0187 0188 % display info text 0189 displayStatusText(gui,... @@ -407,7 +407,7 @@

    SOURCE CODE ^if ~isequal(FileName,0) || ~isequal(PathName,0) 0331 clear data 0332 data = out; %#ok<NASGU> -0333 save(fullfile(PathName,FileName),'data'); +0333 save(fullfile(PathName,FileName),'data','-v7.3'); 0334 displayStatusText(gui,'Saving to MAT-file ... done.'); 0335 else 0336 displayStatusText(gui,'Saving to MAT-file ... canceled.'); @@ -501,7 +501,7 @@

    SOURCE CODE ^'T2 [',unit,']'],'amplitude [a.u.]'}; 0425 end 0426 -0427 case {'LU','NNLS'} +0427 case {'LU','NNLS','MUMO'} 0428 tmp4 = [INVdata{id}.results.invstd.T1T2me(:)... 0429 INVdata{id}.results.invstd.T1T2f(:)]; 0430 header4 = {['relaxation times [',unit,']'],'amplitudes [a.u.]'}; diff --git a/doc/nucleus/functions/interface/exportGraphics.html b/doc/nucleus/functions/interface/exportGraphics.html index a34ee25..c16a77e 100644 --- a/doc/nucleus/functions/interface/exportGraphics.html +++ b/doc/nucleus/functions/interface/exportGraphics.html @@ -51,15 +51,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • displayStatusText shows status information either in the GUI or on the
  • This function is called by: @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv, NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- @@ -373,61 +373,71 @@

    SOURCE CODE ^switch fig_tag 0305 case 'INV' -0306 [FileName,PathName,~] = uiputfile({putext,put1},... -0307 ['NUCLEUSinv: Save ',statstr,' Graphics'],... -0308 fullfile(pwd,'NUCLEUSinv_inversion')); -0309 case 'MOD' -0310 [FileName,PathName,~] = uiputfile({putext,put1},... -0311 ['NUCLEUSmod: Save ',statstr,' Graphics'],... -0312 fullfile(pwd,'NUCLEUSmod_forward')); -0313 end -0314 if ~isequal(FileName,0) || ~isequal(PathName,0) -0315 print(expfig,fullfile(PathName,FileName),'-r300',driver); -0316 close(expfig); -0317 displayStatusText(gui,['Saving ',statstr,'-file ... done.']); -0318 else -0319 displayStatusText(gui,['Saving ',statstr,'-file ... canceled.']); -0320 figure(expfig); -0321 end -0322 otherwise -0323 % nothing to do ... fig-files are not saved automatically -0324 end -0325 -0326 if nargout > 0 -0327 varargout{1} = expfig; -0328 if isjoint -0329 varargout{2} = [ax1 ax2 ax3]; -0330 else -0331 varargout{2} = [ax1 ax2]; -0332 end -0333 end -0334 -0335 end -0336 -0337 %------------- END OF CODE -------------- -0338 -0339 %% License: -0340 % MIT License -0341 % -0342 % Copyright (c) 2018 Thomas Hiller -0343 % -0344 % Permission is hereby granted, free of charge, to any person obtaining a copy -0345 % of this software and associated documentation files (the "Software"), to deal -0346 % in the Software without restriction, including without limitation the rights -0347 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0348 % copies of the Software, and to permit persons to whom the Software is -0349 % furnished to do so, subject to the following conditions: -0350 % -0351 % The above copyright notice and this permission notice shall be included in all -0352 % copies or substantial portions of the Software. +0306 % which NMR signal +0307 id = get(gui.listbox_handles.signal,'Value'); +0308 % get the new file name +0309 sfilename = data.import.NMR.filesShort{id}; +0310 ind1 = strfind(sfilename,'.'); +0311 if isempty(ind1) +0312 sfilename = [sfilename,'_INV']; +0313 else +0314 sfilename = [sfilename(1:ind1-1),'_INV']; +0315 end +0316 [FileName,PathName,~] = uiputfile({putext,put1},... +0317 ['NUCLEUSinv: Save ',statstr,' Graphics'],... +0318 fullfile(data.import.path,sfilename)); +0319 case 'MOD' +0320 [FileName,PathName,~] = uiputfile({putext,put1},... +0321 ['NUCLEUSmod: Save ',statstr,' Graphics'],... +0322 fullfile(pwd,'NUCLEUSmod_forward')); +0323 end +0324 if ~isequal(FileName,0) || ~isequal(PathName,0) +0325 print(expfig,fullfile(PathName,FileName),'-r300',driver); +0326 close(expfig); +0327 displayStatusText(gui,['Saving ',statstr,'-file ... done.']); +0328 else +0329 displayStatusText(gui,['Saving ',statstr,'-file ... canceled.']); +0330 figure(expfig); +0331 end +0332 otherwise +0333 % nothing to do ... fig-files are not saved automatically +0334 end +0335 +0336 if nargout > 0 +0337 varargout{1} = expfig; +0338 if isjoint +0339 varargout{2} = [ax1 ax2 ax3]; +0340 else +0341 varargout{2} = [ax1 ax2]; +0342 end +0343 end +0344 +0345 end +0346 +0347 %------------- END OF CODE -------------- +0348 +0349 %% License: +0350 % MIT License +0351 % +0352 % Copyright (c) 2018 Thomas Hiller 0353 % -0354 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0355 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0356 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0357 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0358 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0359 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0360 % SOFTWARE.

    +0354 % Permission is hereby granted, free of charge, to any person obtaining a copy +0355 % of this software and associated documentation files (the "Software"), to deal +0356 % in the Software without restriction, including without limitation the rights +0357 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0358 % copies of the Software, and to permit persons to whom the Software is +0359 % furnished to do so, subject to the following conditions: +0360 % +0361 % The above copyright notice and this permission notice shall be included in all +0362 % copies or substantial portions of the Software. +0363 % +0364 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0365 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0366 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0367 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0368 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0369 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0370 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/exportINV.html b/doc/nucleus/functions/interface/exportINV.html index f8c7d40..65b06ab 100644 --- a/doc/nucleus/functions/interface/exportINV.html +++ b/doc/nucleus/functions/interface/exportINV.html @@ -57,15 +57,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • displayStatusText shows status information either in the GUI or on the
  • This function is called by: @@ -106,8 +106,8 @@

    SOURCE CODE ^% none 0031 % 0032 % See also: NUCLEUSinv -0033 % Author: Thomas Hiller -0034 % email: thomas.hiller[at]leibniz-liag.de +0033 % Author: see AUTHORS.md +0034 % email: see AUTHORS.md 0035 % License: MIT License (at end) 0036 0037 %------------- BEGIN CODE -------------- @@ -139,7 +139,7 @@

    SOURCE CODE ^% save to default file at local data path -0066 save(fullfile(data.import.path,'NUCLEUSinv_raw.mat'),'savedata'); +0066 save(fullfile(data.import.path,'NUCLEUSinv_raw.mat'),'savedata','-v7.3'); 0067 clear savedata; 0068 0069 % display info text @@ -166,7 +166,7 @@

    SOURCE CODE ^if dosilent -0093 save(fullfile(sfile),'savedata'); +0093 save(fullfile(sfile),'savedata','-v7.3'); 0094 clear savedata; 0095 else 0096 % session file name @@ -185,7 +185,7 @@

    SOURCE CODE ^% if user didn't cancel save session 0111 if sum([sfile spath]) > 0 -0112 save(fullfile(spath,sfile),'savedata'); +0112 save(fullfile(spath,sfile),'savedata','-v7.3'); 0113 clear savedata; 0114 0115 % display info text diff --git a/doc/nucleus/functions/interface/findParentOfType.html b/doc/nucleus/functions/interface/findParentOfType.html index cd7f0f7..ca8c4b2 100644 --- a/doc/nucleus/functions/interface/findParentOfType.html +++ b/doc/nucleus/functions/interface/findParentOfType.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: NUCLEUSinv, NUCLEUSmod -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/fixAxes.html b/doc/nucleus/functions/interface/fixAxes.html index 69c3551..2eecf92 100644 --- a/doc/nucleus/functions/interface/fixAxes.html +++ b/doc/nucleus/functions/interface/fixAxes.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: NUCLEUSinv, NUCLEUSmod -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/getColorIndex.html b/doc/nucleus/functions/interface/getColorIndex.html index 65f9e0c..c4b048b 100644 --- a/doc/nucleus/functions/interface/getColorIndex.html +++ b/doc/nucleus/functions/interface/getColorIndex.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv, NUCLEUSmod -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/getColorTheme.html b/doc/nucleus/functions/interface/getColorTheme.html index 3ce09f5..d230002 100644 --- a/doc/nucleus/functions/interface/getColorTheme.html +++ b/doc/nucleus/functions/interface/getColorTheme.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv, NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/getVersionNoFromString.html b/doc/nucleus/functions/interface/getVersionNoFromString.html index f0331f0..0b599b5 100644 --- a/doc/nucleus/functions/interface/getVersionNoFromString.html +++ b/doc/nucleus/functions/interface/getVersionNoFromString.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv, NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/importASCIIdata.html b/doc/nucleus/functions/interface/importASCIIdata.html index cc28e0d..f7b750c 100644 --- a/doc/nucleus/functions/interface/importASCIIdata.html +++ b/doc/nucleus/functions/interface/importASCIIdata.html @@ -53,15 +53,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • NUCLEUSinv_updateInterface updates all GUI elements
  • rotateT2phase rotateT2phase rotates the complex NMR T2 signal so that the imaginary
  • cleanupGUIData removes unnecessary fields from the global "data" struct
  • clearAllAxes clears all axes of a given figure
  • enableGUIelements activates all necessary GUI elements after successful
  • makeINIfile creates or updates the ini-File
  • fitDataFree is a control routine that uses 'lsqcurvefit' to fit NMR data
  • This function is called by: @@ -98,8 +98,8 @@

    SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- @@ -201,71 +201,79 @@

    SOURCE CODE ^else 0131 data.import.NMR.data{c}.signal = tmp_data(:,2); -0132 end -0133 data.import.NMR.data{c}.T1IRfac = 1; -0134 data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; -0135 data.import.NMR.data{c}.raw.signal = data.import.NMR.data{c}.signal; -0136 -0137 % dummy parameter data -0138 data.import.NMR.para{c} = 0; -0139 end -0140 end -0141 -0142 % save file names -0143 data.import.NMR.files = fnames; -0144 data.import.NMR.filesShort = shownames; -0145 -0146 % update the ini-file -0147 gui.myui.inidata.importpath = data.import.path; -0148 gui = makeINIfile(gui,'update'); +0132 data.import.NMR.data{c}.phase = 0; +0133 +0134 param.T1IRfac = 1; +0135 param.noise = 0; +0136 param.optim = 'off'; +0137 invstd = fitDataFree(data.import.NMR.data{c}.time,data.import.NMR.data{c}.signal,... +0138 'T2',param,5); +0139 data.import.NMR.data{c}.noise = invstd.rms; +0140 end +0141 data.import.NMR.data{c}.T1IRfac = 1; +0142 data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; +0143 data.import.NMR.data{c}.raw.signal = data.import.NMR.data{c}.signal; +0144 +0145 % dummy parameter data +0146 data.import.NMR.para{c} = 0; +0147 end +0148 end 0149 -0150 % update the list of file names -0151 set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); -0152 set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); +0150 % save file names +0151 data.import.NMR.files = fnames; +0152 data.import.NMR.filesShort = shownames; 0153 -0154 % create a global INVdata struct for every file in the list -0155 if isstruct(getappdata(fig,'INVdata')) -0156 setappdata(fig,'INVdata',[]); -0157 end -0158 INVdata = cell(length(data.import.NMR.filesShort),1); -0159 setappdata(fig,'INVdata',INVdata); -0160 -0161 % clear all axes -0162 clearAllAxes(gui.figh); -0163 -0164 % update GUI data and interface -0165 setappdata(fig,'data',data); -0166 setappdata(fig,'gui',gui); -0167 enableGUIelements('ASCII'); -0168 NUCLEUSinv_updateInterface; -0169 end -0170 -0171 end -0172 -0173 %------------- END OF CODE -------------- -0174 -0175 %% License: -0176 % MIT License -0177 % -0178 % Copyright (c) 2018 Thomas Hiller -0179 % -0180 % Permission is hereby granted, free of charge, to any person obtaining a copy -0181 % of this software and associated documentation files (the "Software"), to deal -0182 % in the Software without restriction, including without limitation the rights -0183 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0184 % copies of the Software, and to permit persons to whom the Software is -0185 % furnished to do so, subject to the following conditions: -0186 % -0187 % The above copyright notice and this permission notice shall be included in all -0188 % copies or substantial portions of the Software. -0189 % -0190 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0191 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0192 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0193 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0194 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0195 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0196 % SOFTWARE. +0154 % update the ini-file +0155 gui.myui.inidata.importpath = data.import.path; +0156 gui = makeINIfile(gui,'update'); +0157 +0158 % update the list of file names +0159 set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); +0160 set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); +0161 +0162 % create a global INVdata struct for every file in the list +0163 if isstruct(getappdata(fig,'INVdata')) +0164 setappdata(fig,'INVdata',[]); +0165 end +0166 INVdata = cell(length(data.import.NMR.filesShort),1); +0167 setappdata(fig,'INVdata',INVdata); +0168 +0169 % clear all axes +0170 clearAllAxes(gui.figh); +0171 +0172 % update GUI data and interface +0173 setappdata(fig,'data',data); +0174 setappdata(fig,'gui',gui); +0175 enableGUIelements('ASCII'); +0176 NUCLEUSinv_updateInterface; +0177 end +0178 +0179 end +0180 +0181 %------------- END OF CODE -------------- +0182 +0183 %% License: +0184 % MIT License +0185 % +0186 % Copyright (c) 2018 Thomas Hiller +0187 % +0188 % Permission is hereby granted, free of charge, to any person obtaining a copy +0189 % of this software and associated documentation files (the "Software"), to deal +0190 % in the Software without restriction, including without limitation the rights +0191 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0192 % copies of the Software, and to permit persons to whom the Software is +0193 % furnished to do so, subject to the following conditions: +0194 % +0195 % The above copyright notice and this permission notice shall be included in all +0196 % copies or substantial portions of the Software. +0197 % +0198 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0199 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0200 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0201 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0202 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0203 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0204 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/importCPSdata.html b/doc/nucleus/functions/interface/importCPSdata.html index 9b5b08c..8623c42 100644 --- a/doc/nucleus/functions/interface/importCPSdata.html +++ b/doc/nucleus/functions/interface/importCPSdata.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv, NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/importCalibrationData.html b/doc/nucleus/functions/interface/importCalibrationData.html index f4abf20..f67a1b2 100644 --- a/doc/nucleus/functions/interface/importCalibrationData.html +++ b/doc/nucleus/functions/interface/importCalibrationData.html @@ -60,7 +60,7 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • NUCLEUSinv_updateInterface updates all GUI elements
  • displayStatusText shows status information either in the GUI or on the
  • This function is called by:
    diff --git a/doc/nucleus/functions/interface/importEXCELdata.html b/doc/nucleus/functions/interface/importEXCELdata.html index a0fbe55..0f4e5d0 100644 --- a/doc/nucleus/functions/interface/importEXCELdata.html +++ b/doc/nucleus/functions/interface/importEXCELdata.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: NUCLEUSinv -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/importINV2INV.html b/doc/nucleus/functions/interface/importINV2INV.html index cbbaf78..734b1de 100644 --- a/doc/nucleus/functions/interface/importINV2INV.html +++ b/doc/nucleus/functions/interface/importINV2INV.html @@ -54,15 +54,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • NUCLEUSinv_updateInterface updates all GUI elements
  • onListboxData handles the calls from the context menu of the data
  • onMenuExpert handles the call from the menu that activates / deactivates
  • onMenuJointInversion handles the call from the menu that activates / deactivates
  • onMenuView handles the view menu entries
  • displayStatusText shows status information either in the GUI or on the
  • enableGUIelements activates all necessary GUI elements after successful
  • getVersionNoFromString converts the version string to a numeric value
  • makeINIfile creates or updates the ini-File
  • This function is called by: @@ -100,8 +100,8 @@

    SOURCE CODE ^% none 0028 % 0029 % See also: NUCLEUSinv -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- @@ -128,177 +128,191 @@

    SOURCE CODE ^end 0056 0057 % only continue if user didn't cancel -0058 if sum(Sessionpath) > 0 -0059 % check if it is a valid session file -0060 tmp = load(fullfile(Sessionpath,Sessionfile),'savedata'); -0061 if isfield(tmp,'savedata') && isfield(tmp.savedata,'data') && ... -0062 isfield(tmp.savedata,'id') && isfield(tmp.savedata,'INVdata') -0063 savedata = tmp.savedata; -0064 -0065 % check import uimenu -0066 set(src,'Checked','on'); +0058 if sum(Sessionpath) > 0 +0059 % display info text +0060 displayStatusText(gui,'Importing GUI session from mat-file ...'); +0061 +0062 % check if it is a valid session file +0063 tmp = load(fullfile(Sessionpath,Sessionfile),'savedata'); +0064 if isfield(tmp,'savedata') && isfield(tmp.savedata,'data') && ... +0065 isfield(tmp.savedata,'id') && isfield(tmp.savedata,'INVdata') +0066 savedata = tmp.savedata; 0067 -0068 % adjust menu entry for expert mode -0069 switch savedata.data.info.ExpertMode -0070 case 'on' -0071 set(gui.menu.extra_expert,'Checked','off'); -0072 case 'off' -0073 set(gui.menu.extra_expert,'Checked','on'); -0074 end -0075 onMenuExpert(gui.menu.extra_expert); -0076 -0077 % adjust menu entry for joint inversion -0078 switch savedata.data.info.JointInv -0079 case 'on' -0080 set(gui.menu.extra_joint,'Checked','off'); -0081 case 'off' -0082 set(gui.menu.extra_joint,'Checked','on'); -0083 end -0084 onMenuJointInversion(gui.menu.extra_joint); -0085 enableGUIelements('NMR'); -0086 -0087 % adjust menu entry for comand line inversion info -0088 switch savedata.data.info.InvInfo -0089 case 'on' -0090 set(gui.menu.view_invinfo,'Checked','off'); -0091 case 'off' -0092 set(gui.menu.view_invinfo,'Checked','on'); -0093 end -0094 onMenuView(gui.menu.view_invinfo); -0095 -0096 % adjust menu entry for tool tips -0097 switch savedata.data.info.ToolTips -0098 case 'on' -0099 set(gui.menu.view_tooltips,'Checked','off'); -0100 case 'off' -0101 set(gui.menu.view_tooltips,'Checked','on'); -0102 end -0103 onMenuView(gui.menu.view_tooltips); -0104 -0105 % update GUI data from session mat-file -0106 data = savedata.data; -0107 INVdata = savedata.INVdata; -0108 -0109 % backward compatibility with older versions -0110 % current GUI version -0111 version = getVersionNoFromString(gui.myui.version); -0112 % import GUI version -0113 version_in = getVersionNoFromString(savedata.myui.version); -0114 if version_in < version -0115 if version_in < 19 % changes introduced with v.0.1.9 -0116 if strcmp(savedata.data.invstd.invtype,'ILA') -0117 data.invstd.invtype = 'LU'; -0118 end -0119 for i = 1:numel(savedata.INVdata) -0120 if strcmp(savedata.INVdata{i}.invstd.invtype,'ILA') -0121 INVdata{i}.invstd.invtype = 'LU'; -0122 end -0123 end -0124 end -0125 end -0126 -0127 % check if the import path exists on this machine -0128 isdir_import = dir(data.import.path); -0129 % if not replace it with the path the session-file was loaded from -0130 if isempty(isdir_import) -0131 data.import.path = Sessionpath; -0132 end -0133 % update the path info field with "path" ("file") -0134 if data.import.file > 0 -0135 tmpstr = fullfile(data.import.path,data.import.file); -0136 else -0137 tmpstr = data.import.path; -0138 end -0139 % update GUI data -0140 setappdata(fig,'data',data); -0141 setappdata(fig,'gui',gui); -0142 setappdata(fig,'INVdata',INVdata); -0143 -0144 % update the ini-file -0145 gui.myui.inidata.importpath = data.import.path; -0146 gui = makeINIfile(gui,'update'); -0147 setappdata(fig,'gui',gui); -0148 -0149 if length(tmpstr)>50 -0150 set(gui.text_handles.data_path,'String',['...',tmpstr(end-50:end)],... -0151 'HorizontalAlignment','left'); -0152 else -0153 set(gui.text_handles.data_path,'String',tmpstr,... -0154 'HorizontalAlignment','left'); -0155 end -0156 set(gui.text_handles.data_path,'TooltipString',tmpstr); -0157 -0158 % update the list of file names -0159 set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); -0160 set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); -0161 -0162 % update GUI interface -0163 NUCLEUSinv_updateInterface; -0164 -0165 % color the file names where there is an inversion set -0166 for id = 1:size(INVdata,1) -0167 if isstruct(INVdata{id}) -0168 strL = get(gui.listbox_handles.signal,'String'); -0169 str1 = strL{id}; -0170 str2 = ['<HTML><BODY bgcolor="rgb(',... -0171 sprintf('%d,%d,%d',gui.myui.colors.listINV.*255),')">',... -0172 str1,'</BODY></HTML>']; -0173 strL{id} = str2; -0174 set(gui.listbox_handles.signal,'String',strL); -0175 end -0176 end -0177 -0178 % set focus on last file used in previous session -0179 set(gui.listbox_handles.signal,'Value',savedata.id); -0180 -0181 % show corresponding file data -0182 updatePlotsSignal; -0183 if isstruct(INVdata{savedata.id}) -0184 if isfield(data,'results') -0185 if isfield(data.results,'invstd') -0186 updatePlotsDistribution; -0187 updateInfo(gui.plots.SignalPanel); -0188 end -0189 if isfield(data.results,'invjoint') -0190 updatePlotsJointInversion; -0191 end -0192 if isfield(data.results,'lcurve') -0193 updatePlotsLcurve; -0194 end -0195 end -0196 end -0197 else -0198 helpdlg({'importINV2INV:';... -0199 'This seems to be not a valid NUCLEUSinv session file'},... -0200 'No session data found'); -0201 end -0202 -0203 end -0204 -0205 %------------- END OF CODE -------------- -0206 -0207 %% License: -0208 % MIT License -0209 % -0210 % Copyright (c) 2018 Thomas Hiller -0211 % -0212 % Permission is hereby granted, free of charge, to any person obtaining a copy -0213 % of this software and associated documentation files (the "Software"), to deal -0214 % in the Software without restriction, including without limitation the rights -0215 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0216 % copies of the Software, and to permit persons to whom the Software is -0217 % furnished to do so, subject to the following conditions: -0218 % -0219 % The above copyright notice and this permission notice shall be included in all -0220 % copies or substantial portions of the Software. -0221 % -0222 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0223 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0224 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0225 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0226 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0227 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0228 % SOFTWARE. +0068 % check import uimenu +0069 set(src,'Checked','on'); +0070 +0071 % backward compatibility with older versions +0072 % display info text +0073 displayStatusText(gui,'Importing GUI session from mat-file ... backward compatibility.'); +0074 % current GUI version +0075 version = getVersionNoFromString(gui.myui.version); +0076 % import GUI version +0077 version_in = getVersionNoFromString(savedata.myui.version); +0078 if version_in < version +0079 if version_in < 19 % changes introduced with v.0.1.9 +0080 % rename 'ILA' to 'LU' in savedata +0081 if strcmp(savedata.data.invstd.invtype,'ILA') +0082 savedata.data.invstd.invtype = 'LU'; +0083 end +0084 for i = 1:numel(savedata.INVdata) +0085 if isstruct(savedata.INVdata{i}) && ... +0086 strcmp(savedata.INVdata{i}.invstd.invtype,'ILA') +0087 savedata.INVdata{i}.invstd.invtype = 'LU'; +0088 end +0089 end +0090 end +0091 if version_in < 112 % changes introduced with v.0.1.12 +0092 % add 'Tdiff' field to savedata +0093 savedata.data.invstd.Tdiff = data.invstd.Tdiff; +0094 for i = 1:numel(savedata.INVdata) +0095 if isstruct(savedata.INVdata{i}) +0096 savedata.INVdata{i}.invstd.Tdiff = data.invstd.Tdiff; +0097 end +0098 end +0099 end +0100 end +0101 +0102 % update GUI data from session mat-file +0103 data = savedata.data; +0104 INVdata = savedata.INVdata; +0105 +0106 % display info text +0107 displayStatusText(gui,'Importing GUI session from mat-file ... update GUI data.'); +0108 % check if the import path exists on this machine +0109 isdir_import = dir(data.import.path); +0110 % if not replace it with the path the session-file was loaded from +0111 if isempty(isdir_import) +0112 data.import.path = Sessionpath; +0113 end +0114 % update the path info field with "path" ("file") +0115 if data.import.file > 0 +0116 tmpstr = fullfile(data.import.path,data.import.file); +0117 else +0118 tmpstr = data.import.path; +0119 end +0120 % update GUI data +0121 setappdata(fig,'data',data); +0122 setappdata(fig,'gui',gui); +0123 setappdata(fig,'INVdata',INVdata); +0124 +0125 % update the ini-file +0126 gui.myui.inidata.importpath = data.import.path; +0127 gui = makeINIfile(gui,'update'); +0128 setappdata(fig,'gui',gui); +0129 +0130 if length(tmpstr)>50 +0131 set(gui.text_handles.data_path,'String',['...',tmpstr(end-50:end)],... +0132 'HorizontalAlignment','left'); +0133 else +0134 set(gui.text_handles.data_path,'String',tmpstr,... +0135 'HorizontalAlignment','left'); +0136 end +0137 set(gui.text_handles.data_path,'TooltipString',tmpstr); +0138 +0139 % update the list of file names +0140 set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); +0141 set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); +0142 +0143 % display info text +0144 displayStatusText(gui,'Importing GUI session from mat-file ... update GUI interface.'); +0145 % update GUI interface +0146 NUCLEUSinv_updateInterface; +0147 +0148 % color the file names where there is an inversion set +0149 for id = 1:size(INVdata,1) +0150 if isstruct(INVdata{id}) +0151 strL = get(gui.listbox_handles.signal,'String'); +0152 str1 = strL{id}; +0153 str2 = ['<HTML><BODY bgcolor="rgb(',... +0154 sprintf('%d,%d,%d',gui.myui.colors.listINV.*255),')">',... +0155 str1,'</BODY></HTML>']; +0156 strL{id} = str2; +0157 set(gui.listbox_handles.signal,'String',strL); +0158 end +0159 end +0160 +0161 % display info text +0162 displayStatusText(gui,'Importing GUI session from mat-file ... update GUI menus.'); +0163 % adjust menu entry for expert mode +0164 switch savedata.data.info.ExpertMode +0165 case 'on' +0166 set(gui.menu.extra_expert,'Checked','off'); +0167 case 'off' +0168 set(gui.menu.extra_expert,'Checked','on'); +0169 end +0170 onMenuExpert(gui.menu.extra_expert); +0171 +0172 % adjust menu entry for joint inversion +0173 switch savedata.data.info.JointInv +0174 case 'on' +0175 set(gui.menu.extra_joint,'Checked','off'); +0176 case 'off' +0177 set(gui.menu.extra_joint,'Checked','on'); +0178 end +0179 onMenuJointInversion(gui.menu.extra_joint); +0180 enableGUIelements('NMR'); +0181 +0182 % adjust menu entry for comand line inversion info +0183 switch savedata.data.info.InvInfo +0184 case 'on' +0185 set(gui.menu.view_invinfo,'Checked','off'); +0186 case 'off' +0187 set(gui.menu.view_invinfo,'Checked','on'); +0188 end +0189 onMenuView(gui.menu.view_invinfo); +0190 +0191 % adjust menu entry for tool tips +0192 switch savedata.data.info.ToolTips +0193 case 'on' +0194 set(gui.menu.view_tooltips,'Checked','off'); +0195 case 'off' +0196 set(gui.menu.view_tooltips,'Checked','on'); +0197 end +0198 onMenuView(gui.menu.view_tooltips); +0199 +0200 % display info text +0201 displayStatusText(gui,'Importing GUI session from mat-file ... show last file.'); +0202 % set focus on last file used in previous session +0203 set(gui.listbox_handles.signal,'Value',savedata.id); +0204 % and simulate click to update all relevant GUI elements +0205 onListboxData(gui.listbox_handles.signal); +0206 +0207 % display info text +0208 displayStatusText(gui,'Importing GUI session from mat-file ... done.'); +0209 else +0210 % display info text +0211 displayStatusText(gui,'Importing GUI session from mat-file ... cancelled.'); +0212 +0213 helpdlg({'importINV2INV:';... +0214 'This seems to be not a valid NUCLEUSinv session file'},... +0215 'No session data found'); +0216 end +0217 end +0218 +0219 %------------- END OF CODE -------------- +0220 +0221 %% License: +0222 % MIT License +0223 % +0224 % Copyright (c) 2018 Thomas Hiller +0225 % +0226 % Permission is hereby granted, free of charge, to any person obtaining a copy +0227 % of this software and associated documentation files (the "Software"), to deal +0228 % in the Software without restriction, including without limitation the rights +0229 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0230 % copies of the Software, and to permit persons to whom the Software is +0231 % furnished to do so, subject to the following conditions: +0232 % +0233 % The above copyright notice and this permission notice shall be included in all +0234 % copies or substantial portions of the Software. +0235 % +0236 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0237 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0238 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0239 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0240 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0241 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0242 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/importMOD2INV.html b/doc/nucleus/functions/interface/importMOD2INV.html index 955985b..8b7b82f 100644 --- a/doc/nucleus/functions/interface/importMOD2INV.html +++ b/doc/nucleus/functions/interface/importMOD2INV.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSinv -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- @@ -245,122 +245,136 @@

    SOURCE CODE ^switch T1T2 0174 case 'T1' 0175 data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EdT1(dL(i),:)'; -0176 case 'T2' -0177 data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EdT2(dL(i),:)'; -0178 end -0179 data.import.NMR.data{c}.phase = 0; -0180 data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; -0181 data.import.NMR.data{c}.raw.signal = data.import.NMR.data{c}.signal; -0182 -0183 data.import.NMR.para{c}.geom = data.import.NMRMOD.geom.type; -0184 data.import.NMR.para{c}.Tbulk = data.import.NMRMOD.nmr.Tb; -0185 data.import.NMR.para{c}.rho = data.import.NMRMOD.nmr.rho; -0186 data.import.NMR.para{c}.porosity = data.import.NMRMOD.nmr.porosity; -0187 -0188 table{c,1} = true; -0189 table{c,2} = data.import.NMRMOD.p(dL(i)); -0190 table{c,3} = data.import.NMRMOD.Sd(dL(i)); -0191 table{c,4} = 'D'; -0192 end -0193 -0194 % now we import imbibition NMR data -0195 for i = 1:numel(iL) -0196 % the individual file names -0197 c = c + 1; -0198 fnames(c).parfile = ''; -0199 fnames(c).datafile = data.import.file; -0200 fnames(c).T2specfile = ''; -0201 -0202 shownames{c} = ['NUCLEUSmod_',T1T2,'_imb_',num2str(i)]; -0203 -0204 % the 'header' data -0205 data.import.NMR.data{c}.datfile = fileID.name; -0206 data.import.NMR.data{c}.date = fileID.date; -0207 data.import.NMR.data{c}.datenum = fileID.datenum; -0208 data.import.NMR.data{c}.bytes = fileID.bytes; -0209 % the NMR data -0210 data.import.NMR.data{c}.flag = T1T2; -0211 data.import.NMR.data{c}.T1IRfac = T1IRfac; -0212 data.import.NMR.data{c}.time = data.import.NMRMOD.nmr.t(:); -0213 switch T1T2 -0214 case 'T1' -0215 data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EiT1(iL(i),:)'; -0216 case 'T2' -0217 data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EiT2(iL(i),:)'; -0218 end -0219 data.import.NMR.data{c}.phase = 0; -0220 data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; -0221 data.import.NMR.data{c}.raw.signal = data.import.NMR.data{c}.signal; -0222 -0223 data.import.NMR.para{c}.geom = data.import.NMRMOD.geom.type; -0224 data.import.NMR.para{c}.Tbulk = data.import.NMRMOD.nmr.Tb; -0225 data.import.NMR.para{c}.rho = data.import.NMRMOD.nmr.rho; -0226 data.import.NMR.para{c}.porosity = data.import.NMRMOD.nmr.porosity; -0227 -0228 table{c,1} = true; -0229 table{c,2} = data.import.NMRMOD.p(iL(i)); -0230 table{c,3} = data.import.NMRMOD.Si(iL(i)); -0231 table{c,4} = 'I'; -0232 end -0233 -0234 data.import.NMR.files = fnames; -0235 data.import.NMR.filesShort = shownames; -0236 -0237 % import pressure / saturation data -0238 data.pressure.unit = data.import.NMRMOD.gui_pressure.unit; -0239 data.pressure.unitfac = data.import.NMRMOD.gui_pressure.unitfac; -0240 data.pressure.table = table; -0241 -0242 % update the list of file names -0243 set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); -0244 set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); -0245 -0246 % create a global INVdata struct for every file in the list -0247 if isstruct(getappdata(fig,'INVdata')) -0248 setappdata(fig,'INVdata',[]); -0249 end -0250 INVdata = cell(length(data.import.NMR.filesShort),1); -0251 setappdata(fig,'INVdata',INVdata); -0252 -0253 % clear all axes -0254 clearAllAxes(gui.figh); +0176 data.import.NMR.data{c}.noise = data.import.NMRMOD.nmr.noise(dL(i),2); +0177 case 'T2' +0178 data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EdT2(dL(i),:)'; +0179 data.import.NMR.data{c}.noise = data.import.NMRMOD.nmr.noise(dL(i),4); +0180 end +0181 data.import.NMR.data{c}.phase = 0; +0182 data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; +0183 data.import.NMR.data{c}.raw.signal = data.import.NMR.data{c}.signal; +0184 +0185 data.import.NMR.para{c}.geom = data.import.NMRMOD.geom.type; +0186 data.import.NMR.para{c}.Tbulk = data.import.NMRMOD.nmr.Tb; +0187 if isfield(data.import.NMRMOD.nmr,'Td') +0188 data.import.NMR.para{c}.Tdiff = data.import.NMRMOD.nmr.Td; +0189 else +0190 data.import.NMR.para{c}.Tdiff = 1e6; +0191 end +0192 data.import.NMR.para{c}.rho = data.import.NMRMOD.nmr.rho; +0193 data.import.NMR.para{c}.porosity = data.import.NMRMOD.nmr.porosity; +0194 +0195 table{c,1} = true; +0196 table{c,2} = data.import.NMRMOD.p(dL(i)); +0197 table{c,3} = data.import.NMRMOD.Sd(dL(i)); +0198 table{c,4} = 'D'; +0199 end +0200 +0201 % now we import imbibition NMR data +0202 for i = 1:numel(iL) +0203 % the individual file names +0204 c = c + 1; +0205 fnames(c).parfile = ''; +0206 fnames(c).datafile = data.import.file; +0207 fnames(c).T2specfile = ''; +0208 +0209 shownames{c} = ['NUCLEUSmod_',T1T2,'_imb_',num2str(i)]; +0210 +0211 % the 'header' data +0212 data.import.NMR.data{c}.datfile = fileID.name; +0213 data.import.NMR.data{c}.date = fileID.date; +0214 data.import.NMR.data{c}.datenum = fileID.datenum; +0215 data.import.NMR.data{c}.bytes = fileID.bytes; +0216 % the NMR data +0217 data.import.NMR.data{c}.flag = T1T2; +0218 data.import.NMR.data{c}.T1IRfac = T1IRfac; +0219 data.import.NMR.data{c}.time = data.import.NMRMOD.nmr.t(:); +0220 switch T1T2 +0221 case 'T1' +0222 data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EiT1(iL(i),:)'; +0223 data.import.NMR.data{c}.noise = data.import.NMRMOD.nmr.noise(iL(i),1); +0224 case 'T2' +0225 data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EiT2(iL(i),:)'; +0226 data.import.NMR.data{c}.noise = data.import.NMRMOD.nmr.noise(iL(i),3); +0227 end +0228 data.import.NMR.data{c}.phase = 0; +0229 data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; +0230 data.import.NMR.data{c}.raw.signal = data.import.NMR.data{c}.signal; +0231 +0232 data.import.NMR.para{c}.geom = data.import.NMRMOD.geom.type; +0233 data.import.NMR.para{c}.Tbulk = data.import.NMRMOD.nmr.Tb; +0234 if isfield(data.import.NMRMOD.nmr,'Td') +0235 data.import.NMR.para{c}.Tdiff = data.import.NMRMOD.nmr.Td; +0236 else +0237 data.import.NMR.para{c}.Tdiff = 1e6; +0238 end +0239 data.import.NMR.para{c}.rho = data.import.NMRMOD.nmr.rho; +0240 data.import.NMR.para{c}.porosity = data.import.NMRMOD.nmr.porosity; +0241 +0242 table{c,1} = true; +0243 table{c,2} = data.import.NMRMOD.p(iL(i)); +0244 table{c,3} = data.import.NMRMOD.Si(iL(i)); +0245 table{c,4} = 'I'; +0246 end +0247 +0248 data.import.NMR.files = fnames; +0249 data.import.NMR.filesShort = shownames; +0250 +0251 % import pressure / saturation data +0252 data.pressure.unit = data.import.NMRMOD.gui_pressure.unit; +0253 data.pressure.unitfac = data.import.NMRMOD.gui_pressure.unitfac; +0254 data.pressure.table = table; 0255 -0256 % enable GUI data and interface -0257 setappdata(fig,'data',data); -0258 setappdata(fig,'gui',gui); -0259 enableGUIelements('MOD'); -0260 NUCLEUSinv_updateInterface; -0261 else -0262 helpdlg({'importNUCLEUSmod:',... -0263 'NUCLEUSmod data import unsuccessful.'},'import error'); -0264 end -0265 -0266 end -0267 -0268 %------------- END OF CODE -------------- -0269 -0270 %% License: -0271 % MIT License -0272 % -0273 % Copyright (c) 2018 Thomas Hiller -0274 % -0275 % Permission is hereby granted, free of charge, to any person obtaining a copy -0276 % of this software and associated documentation files (the "Software"), to deal -0277 % in the Software without restriction, including without limitation the rights -0278 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0279 % copies of the Software, and to permit persons to whom the Software is -0280 % furnished to do so, subject to the following conditions: -0281 % -0282 % The above copyright notice and this permission notice shall be included in all -0283 % copies or substantial portions of the Software. -0284 % -0285 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0286 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0287 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0288 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0289 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0290 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0291 % SOFTWARE. +0256 % update the list of file names +0257 set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); +0258 set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); +0259 +0260 % create a global INVdata struct for every file in the list +0261 if isstruct(getappdata(fig,'INVdata')) +0262 setappdata(fig,'INVdata',[]); +0263 end +0264 INVdata = cell(length(data.import.NMR.filesShort),1); +0265 setappdata(fig,'INVdata',INVdata); +0266 +0267 % clear all axes +0268 clearAllAxes(gui.figh); +0269 +0270 % enable GUI data and interface +0271 setappdata(fig,'data',data); +0272 setappdata(fig,'gui',gui); +0273 enableGUIelements('MOD'); +0274 NUCLEUSinv_updateInterface; +0275 else +0276 helpdlg({'importNUCLEUSmod:',... +0277 'NUCLEUSmod data import unsuccessful.'},'import error'); +0278 end +0279 +0280 end +0281 +0282 %------------- END OF CODE -------------- +0283 +0284 %% License: +0285 % MIT License +0286 % +0287 % Copyright (c) 2018 Thomas Hiller +0288 % +0289 % Permission is hereby granted, free of charge, to any person obtaining a copy +0290 % of this software and associated documentation files (the "Software"), to deal +0291 % in the Software without restriction, including without limitation the rights +0292 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0293 % copies of the Software, and to permit persons to whom the Software is +0294 % furnished to do so, subject to the following conditions: +0295 % +0296 % The above copyright notice and this permission notice shall be included in all +0297 % copies or substantial portions of the Software. +0298 % +0299 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0300 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0301 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0302 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0303 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0304 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0305 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/importMOD2MOD.html b/doc/nucleus/functions/interface/importMOD2MOD.html index ce46b92..ce034be 100644 --- a/doc/nucleus/functions/interface/importMOD2MOD.html +++ b/doc/nucleus/functions/interface/importMOD2MOD.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: NUCLEUSmod -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- @@ -123,49 +123,52 @@

    SOURCE CODE ^% update GUI data -0061 setappdata(fig,'data',data); -0062 % update the interface -0063 NUCLEUSmod_updateInterface; -0064 % update the axes -0065 updatePlotsPSD; -0066 % update the axes -0067 updatePlotsCPS; -0068 updatePlotsNMR; -0069 end -0070 -0071 end -0072 -0073 %------------- END OF CODE -------------- -0074 -0075 %% License: -0076 % MIT License -0077 % -0078 % Copyright (c) 2018 Thomas Hiller -0079 % -0080 % Permission is hereby granted, free of charge, to any person obtaining a copy -0081 % of this software and associated documentation files (the "Software"), to deal -0082 % in the Software without restriction, including without limitation the rights -0083 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0084 % copies of the Software, and to permit persons to whom the Software is -0085 % furnished to do so, subject to the following conditions: -0086 % -0087 % The above copyright notice and this permission notice shall be included in all -0088 % copies or substantial portions of the Software. +0054 if ~isfield(guidata.NMRMOD_GUI.nmr,'Td') +0055 data.nmr.Td = 1e6; +0056 end +0057 data.results.constants = guidata.constants; +0058 data.results.GEOM = guidata.GEOM; +0059 data.results.NMR = guidata.NMR; +0060 data.results.psddata = guidata.psddata; +0061 data.results.SAT = guidata.SAT; +0062 +0063 % update GUI data +0064 setappdata(fig,'data',data); +0065 % update the interface +0066 NUCLEUSmod_updateInterface; +0067 % update the axes +0068 updatePlotsPSD; +0069 % update the axes +0070 updatePlotsCPS; +0071 updatePlotsNMR; +0072 end +0073 +0074 end +0075 +0076 %------------- END OF CODE -------------- +0077 +0078 %% License: +0079 % MIT License +0080 % +0081 % Copyright (c) 2018 Thomas Hiller +0082 % +0083 % Permission is hereby granted, free of charge, to any person obtaining a copy +0084 % of this software and associated documentation files (the "Software"), to deal +0085 % in the Software without restriction, including without limitation the rights +0086 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0087 % copies of the Software, and to permit persons to whom the Software is +0088 % furnished to do so, subject to the following conditions: 0089 % -0090 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0091 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0092 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0093 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0094 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0095 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0096 % SOFTWARE. +0090 % The above copyright notice and this permission notice shall be included in all +0091 % copies or substantial portions of the Software. +0092 % +0093 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0094 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0095 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0096 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0097 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0098 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0099 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/importNMRdata.html b/doc/nucleus/functions/interface/importNMRdata.html index 02e9764..72327b9 100644 --- a/doc/nucleus/functions/interface/importNMRdata.html +++ b/doc/nucleus/functions/interface/importNMRdata.html @@ -57,6 +57,7 @@

    DESCRIPTION ^DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • NUCLEUSinv_updateInterface updates all GUI elements
  • LoadNMRData_driver loads NMR raw data from different file formats
  • fixParameterString cleans parameter file lines when the properties have a
  • rotateT2phase rotateT2phase rotates the complex NMR T2 signal so that the imaginary
  • cleanupGUIData removes unnecessary fields from the global "data" struct
  • clearAllAxes clears all axes of a given figure
  • displayStatusText shows status information either in the GUI or on the
  • enableGUIelements activates all necessary GUI elements after successful
  • makeINIfile creates or updates the ini-File
  • This function is called by: @@ -80,7 +81,7 @@

    CROSS-REFERENCE INFORMATION ^
 
 <h2><a name=SUBFUNCTIONS ^

    +
  • function [NMRpath,NMRfile] = getNMRPathFile(label,import)
  • function [data,gui] = importDataMouseCPMG(data,gui)
  • function [data,gui] = importDataBGRmat(data,gui)
  • function [data,gui] = importDataBGRliftSingle(data,gui)
  • function [data,gui] = importDataBGRliftAll(data,gui)
  • function [data,gui] = importDataHelios(data,gui)
  • function [data,gui] = importDataDart(data,gui)
  • function [data,gui] = importDataGeneral(data,gui)
  • function [data,gui] = importDataLIAG(data,gui)
  • function [data,gui] = importDataLIAGproject(data,gui)
  • function [data,gui] = importDataMouse(data,gui)
  • function [data,gui] = importDataIBAC(data,gui)
  • function data = loadGUIParameters(datapath,fname)
  • function data = loadGUIrawdata(data,NMRpath,NMRfile)
  • SOURCE CODE ^

    0001 function importNMRdata(src)
    @@ -115,1048 +116,1199 @@ 

    SOURCE CODE ^% importDataLIAG 0031 % importDataLIAGproject 0032 % importDataMouse -0033 % loadGUIParameters -0034 % loadGUIrawdata -0035 % -0036 % MAT-files required: -0037 % none -0038 % -0039 % See also: NUCLEUSinv, NUCLEUSmod -0040 % Author: Thomas Hiller -0041 % email: thomas.hiller[at]leibniz-liag.de -0042 % License: MIT License (at end) -0043 -0044 %------------- BEGIN CODE -------------- -0045 -0046 %% get GUI handle and data -0047 fig = findobj('Tag','INV'); -0048 gui = getappdata(fig,'gui'); -0049 data = getappdata(fig,'data'); -0050 -0051 % try is used to catch any import error -0052 % often the wrong input file format is the case -0053 try -0054 % check what import format is chosen -0055 label = get(src,'Label'); -0056 -0057 % set file format for later use -0058 if strcmp(label,'GGE ascii') -0059 data.import.fileformat = 'rwth'; -0060 elseif strcmp(label,'GGE field') -0061 data.import.fileformat = 'field'; -0062 elseif strcmp(label,'GGE Dart') -0063 data.import.fileformat = 'dart'; -0064 elseif strcmp(label,'CoreLab ascii') -0065 data.import.fileformat = 'corelab'; -0066 elseif strcmp(label,'MOUSE') -0067 data.import.fileformat = 'mouse'; -0068 elseif strcmp(label,'LIAG single') -0069 data.import.fileformat = 'liag'; -0070 elseif strcmp(label,'LIAG from project') -0071 data.import.fileformat = 'liag'; -0072 elseif strcmp(label,'LIAG last project') -0073 data.import.fileformat = 'liag'; -0074 elseif strcmp(label,'BGR std') -0075 data.import.fileformat = 'bgr'; -0076 elseif strcmp(label,'BGR org') -0077 data.import.fileformat = 'bgr2'; -0078 elseif strcmp(label,'BGR mat') -0079 data.import.fileformat = 'bgrmat'; -0080 elseif strcmp(label,'BAM TOM') -0081 data.import.fileformat = 'bamtom'; -0082 elseif strcmp(label,'PM5') -0083 data.import.fileformat = 'pm5'; -0084 elseif strcmp(label,'PM25') -0085 data.import.fileformat = 'pm25'; -0086 else -0087 helpdlg('Something is utterly wrong.','onMenuImport: Choose again.'); -0088 end -0089 -0090 % remove info field if any -0091 ih = findobj('Tag','inv_info'); -0092 if ~isempty(ih); delete(ih); end -0093 -0094 % depending on the import format get the corresponding path / file -0095 [NMRpath,NMRfile] = getNMRPathFile(label,data.import); +0033 % importDataHelios +0034 % loadGUIParameters +0035 % loadGUIrawdata +0036 % +0037 % MAT-files required: +0038 % none +0039 % +0040 % See also: NUCLEUSinv, NUCLEUSmod +0041 % Author: see AUTHORS.md +0042 % email: see AUTHORS.md +0043 % License: MIT License (at end) +0044 +0045 %------------- BEGIN CODE -------------- +0046 +0047 %% get GUI handle and data +0048 fig = findobj('Tag','INV'); +0049 gui = getappdata(fig,'gui'); +0050 data = getappdata(fig,'data'); +0051 +0052 % try is used to catch any import error +0053 % often the wrong input file format is the case +0054 try +0055 % check what import format is chosen +0056 label = get(src,'Label'); +0057 +0058 % set file format for later use +0059 if strcmp(label,'GGE ascii') +0060 data.import.fileformat = 'rwth'; +0061 elseif strcmp(label,'GGE field') +0062 data.import.fileformat = 'field'; +0063 elseif strcmp(label,'GGE Dart') +0064 data.import.fileformat = 'dart'; +0065 elseif strcmp(label,'CoreLab ascii') +0066 data.import.fileformat = 'corelab'; +0067 elseif strcmp(label,'MOUSE') +0068 data.import.fileformat = 'mouse'; +0069 elseif strcmp(label,'LIAG single') +0070 data.import.fileformat = 'liag'; +0071 elseif strcmp(label,'LIAG from project') +0072 data.import.fileformat = 'liag'; +0073 elseif strcmp(label,'LIAG last project') +0074 data.import.fileformat = 'liag'; +0075 elseif strcmp(label,'BGR std') +0076 data.import.fileformat = 'bgr'; +0077 elseif strcmp(label,'MouseCPMG') +0078 data.import.fileformat = 'MouseCPMG'; +0079 elseif strcmp(label,'BGR mat') +0080 data.import.fileformat = 'bgrmat'; +0081 elseif strcmp(label,'MouseLiftSingle') +0082 data.import.fileformat = 'MouseLiftSingle'; +0083 elseif strcmp(label,'MouseLiftAll') +0084 data.import.fileformat = 'MouseLiftAll'; +0085 elseif strcmp(label,'Helios') +0086 data.import.fileformat = 'helios'; +0087 elseif strcmp(label,'BAM TOM') +0088 data.import.fileformat = 'bamtom'; +0089 elseif strcmp(label,'PM5') +0090 data.import.fileformat = 'pm5'; +0091 elseif strcmp(label,'PM25') +0092 data.import.fileformat = 'pm25'; +0093 else +0094 helpdlg('Something is utterly wrong.','onMenuImport: Choose again.'); +0095 end 0096 -0097 % only continue if user didn't cancel -0098 if sum([NMRpath NMRfile]) > 0 -0099 % remove old fields and data -0100 data = cleanupGUIData(data); -0101 -0102 % check for mat-file with GUI rawdata and import data -0103 isfile = dir(fullfile(NMRpath,'NUCLEUSinv_raw.mat')); -0104 -0105 % if there is nor raw-file import from folder/file -0106 if isempty(isfile) -0107 % import data -0108 data.import.path = NMRpath; -0109 data.import.file = -1; -0110 displayStatusText(gui,'Reading NMR Data ...'); -0111 % call the corresponding subroutines -0112 switch label -0113 case {'GGE ascii','GGE field','CoreLab ascii','BGR std',... -0114 'BAM TOM'} -0115 [data,gui] = importDataGeneral(data,gui); -0116 case 'Dart' -0117 data.import.file = NMRfile; -0118 [data,gui] = importDataDart(data,gui); -0119 case 'MOUSE' -0120 [data,gui] = importDataMouse(data,gui); -0121 case 'LIAG single' -0122 [data,gui] = importDataLIAG(data,gui); -0123 case {'LIAG from project','LIAG last project'} -0124 [data,gui] = importDataLIAGproject(data,gui); -0125 % make the Petro Panel visible as default -0126 tmp_h = gui.myui.heights(2,:); -0127 tmp_h(3) = gui.myui.heights(2,3); -0128 % but the CPS panel stays minimized -0129 tmp_h(5) = gui.myui.heights(1,3); -0130 set(gui.panels.main,'Heights',tmp_h); -0131 set(gui.panels.petro.main,'Minimized',false); -0132 case 'BGR org' -0133 [data,gui] = importDataBGR(data,gui); -0134 case 'BGR mat' -0135 data.import.file = NMRfile; -0136 [data,gui] = importDataBGRmat(data,gui); -0137 case {'PM5','PM25'} -0138 data.import.file = NMRfile; -0139 [data,gui] = importDataIBAC(data,gui); -0140 end -0141 displayStatusText(gui,'Reading NMR Data ... done'); -0142 else -0143 % import from mat-file -0144 displayStatusText(gui,'Importing NMR raw data from mat-file ...'); -0145 data = loadGUIrawdata(data,NMRpath,NMRfile); -0146 displayStatusText(gui,'Importing NMR raw data from mat-file ... done'); -0147 end -0148 -0149 % update the path info field with "NMRpath" ("NMRfile") -0150 if NMRfile > 0 -0151 tmpstr = fullfile(NMRpath,NMRfile); -0152 else -0153 tmpstr = NMRpath; -0154 end -0155 if length(tmpstr)>50 -0156 set(gui.text_handles.data_path,'String',['...',tmpstr(end-50:end)],... -0157 'HorizontalAlignment','left'); -0158 else -0159 set(gui.text_handles.data_path,'String',tmpstr,... -0160 'HorizontalAlignment','left'); +0097 % remove info field if any +0098 ih = findobj('Tag','inv_info'); +0099 if ~isempty(ih); delete(ih); end +0100 +0101 % depending on the import format get the corresponding path / file +0102 [NMRpath,NMRfile] = getNMRPathFile(label,data.import); +0103 +0104 % only continue if user didn't cancel +0105 if sum([NMRpath NMRfile]) > 0 +0106 % remove old fields and data +0107 data = cleanupGUIData(data); +0108 +0109 % check for mat-file with GUI rawdata and import data +0110 isfile = dir(fullfile(NMRpath,'NUCLEUSinv_raw.mat')); +0111 +0112 % if there is no raw-file import from folder/file +0113 if isempty(isfile) +0114 % import data +0115 data.import.path = NMRpath; +0116 data.import.file = -1; +0117 displayStatusText(gui,'Reading NMR Data ...'); +0118 % call the corresponding subroutines +0119 switch label +0120 case {'GGE ascii','GGE field','CoreLab ascii','BGR std',... +0121 'BAM TOM'} +0122 [data,gui] = importDataGeneral(data,gui); +0123 case 'Dart' +0124 data.import.file = NMRfile; +0125 [data,gui] = importDataDart(data,gui); +0126 case 'MOUSE' +0127 [data,gui] = importDataMouse(data,gui); +0128 case 'LIAG single' +0129 [data,gui] = importDataLIAG(data,gui); +0130 case {'LIAG from project','LIAG last project'} +0131 [data,gui] = importDataLIAGproject(data,gui); +0132 % make the Petro Panel visible as default +0133 tmp_h = gui.myui.heights(2,:); +0134 tmp_h(3) = gui.myui.heights(2,3); +0135 % but the CPS panel stays minimized +0136 tmp_h(5) = gui.myui.heights(1,3); +0137 set(gui.panels.main,'Heights',tmp_h); +0138 set(gui.panels.petro.main,'Minimized',false); +0139 case 'BGR mat' +0140 data.import.file = NMRfile; +0141 [data,gui] = importDataBGRmat(data,gui); +0142 case 'MouseCPMG' +0143 [data,gui] = importDataMouseCPMG(data,gui); +0144 case 'MouseLiftSingle' +0145 [data,gui] = importDataBGRliftSingle(data,gui); +0146 case 'MouseLiftAll' +0147 [data,gui] = importDataBGRliftAll(data,gui); +0148 case 'Helios' +0149 data.import.file = NMRfile; +0150 [data,gui] = importDataHelios(data,gui); +0151 case {'PM5','PM25'} +0152 data.import.file = NMRfile; +0153 [data,gui] = importDataIBAC(data,gui); +0154 end +0155 displayStatusText(gui,'Reading NMR Data ... done'); +0156 else +0157 % import from mat-file +0158 displayStatusText(gui,'Importing NMR raw data from mat-file ...'); +0159 data = loadGUIrawdata(data,NMRpath,NMRfile); +0160 displayStatusText(gui,'Importing NMR raw data from mat-file ... done'); 0161 end -0162 set(gui.text_handles.data_path,'TooltipString',tmpstr); -0163 -0164 % update the ini-file -0165 gui.myui.inidata.importpath = data.import.path; -0166 gui = makeINIfile(gui,'update'); -0167 -0168 % update the list of file names -0169 set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); -0170 set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); -0171 -0172 % create a global INVdata struct for every file in the list -0173 if isstruct(getappdata(fig,'INVdata')) -0174 setappdata(fig,'INVdata',[]); +0162 +0163 % update the path info field with "NMRpath" ("NMRfile") +0164 if NMRfile > 0 +0165 tmpstr = fullfile(NMRpath,NMRfile); +0166 else +0167 tmpstr = NMRpath; +0168 end +0169 if length(tmpstr)>50 +0170 set(gui.text_handles.data_path,'String',['...',tmpstr(end-50:end)],... +0171 'HorizontalAlignment','left'); +0172 else +0173 set(gui.text_handles.data_path,'String',tmpstr,... +0174 'HorizontalAlignment','left'); 0175 end -0176 INVdata = cell(length(data.import.NMR.filesShort),1); -0177 setappdata(fig,'INVdata',INVdata); -0178 -0179 % clear all axes -0180 clearAllAxes(gui.figh); +0176 set(gui.text_handles.data_path,'TooltipString',tmpstr); +0177 +0178 % update the ini-file +0179 gui.myui.inidata.importpath = data.import.path; +0180 gui = makeINIfile(gui,'update'); 0181 -0182 % update GUI data and interface -0183 setappdata(fig,'data',data); -0184 setappdata(fig,'gui',gui); -0185 enableGUIelements('NMR'); -0186 -0187 % special treatment of LIAG projects -0188 switch label -0189 case {'LIAG from project','LIAG last project'} -0190 cpath = data.import.LIAG.calibrationpath; -0191 % check if this calibration file was already used -0192 isfile = dir(fullfile(cpath,'NUCLEUS_calibData.mat')); -0193 if ~isempty(isfile) -0194 id = 2; -0195 % if data is there reuse it -0196 calib = load(fullfile(cpath,isfile.name),'calib'); -0197 INVdata{id} = calib.calib; -0198 data.calib = INVdata{id}.calib; -0199 data.import.LIAG.Tbulk = INVdata{id}.results.invstd.T2; -0200 setappdata(fig,'INVdata',INVdata); -0201 setappdata(fig,'data',data); -0202 % color the list entry -0203 strL = get(gui.listbox_handles.signal,'String'); -0204 str1 = strL{id}; -0205 str2 = ['<HTML><BODY bgcolor="rgb(',... -0206 sprintf('%d,%d,%d',gui.myui.colors.listINV.*255),')">',... -0207 str1,'</BODY></HTML>']; -0208 strL{id} = str2; -0209 set(gui.listbox_handles.signal,'String',strL); -0210 end -0211 otherwise -0212 end -0213 % update GUI interface -0214 NUCLEUSinv_updateInterface; -0215 end -0216 -0217 catch ME -0218 % show error message in case import fails -0219 errmsg = {ME.message;[ME.stack(1).name,' Line: ',num2str(ME.stack(1).line)];... -0220 'Check File Format settings.'}; -0221 errordlg(errmsg,'importNMRdata: Error!'); -0222 -0223 end -0224 -0225 end -0226 -0227 %% -0228 function [NMRpath,NMRfile] = getNMRPathFile(label,import) -0229 -0230 NMRpath = -1; -0231 NMRfile = -1; -0232 % for almost all import cases we load a folder ... but not for all -0233 switch label -0234 case {'GGE ascii','GGE field','CoreLab ascii','MOUSE','LIAG single',... -0235 'BGR std','BGR org','BAM TOM','PM25'} -0236 % if there is already a data folder present we start from here -0237 if isfield(import,'path') -0238 NMRpath = uigetdir(import.path,'Choose Data Path'); -0239 else -0240 % otherwise we start at the current working dircetory -0241 % 'NMRpath' holds the name of the choosen data path -0242 here = mfilename('fullpath'); -0243 [pathstr,~,~] = fileparts(here); -0244 NMRpath = uigetdir(pathstr,'Choose Data Path'); -0245 end -0246 case 'LIAG from project' -0247 % if there is already a data folder present we start from here -0248 if isfield(import,'path') -0249 NMRpath = uigetdir(import.path,'Choose Project Path'); -0250 else -0251 % otherwise we start at the current working dircetory -0252 % 'NMRpath' holds the name of the choosen data path -0253 here = mfilename('fullpath'); -0254 [pathstr,~,~] = fileparts(here); -0255 NMRpath = uigetdir(pathstr,'Choose Project Path'); -0256 end -0257 case 'LIAG last project' -0258 % there is already a data folder and we use this one -0259 if isfield(import,'path') -0260 NMRpath = import.path; -0261 else -0262 % otherwise we start at the current working dircetory -0263 % 'NMRpath' holds the name of the choosen data path -0264 here = mfilename('fullpath'); -0265 [pathstr,~,~] = fileparts(here); -0266 NMRpath = uigetdir(pathstr,'Choose Project Path'); -0267 end -0268 case {'GGE Dart','BGR mat','NMR mat'} -0269 % if there is already a data folder present we start from here -0270 if isfield(import,'path') -0271 [NMRfile,NMRpath] = uigetfile(import.path,'Choose Data file'); -0272 else -0273 % otherwise we start at the current working dircetory -0274 % 'foldername' hold s the name of the choosen data path -0275 here = mfilename('fullpath'); -0276 [pathstr,~,~] = fileparts(here); -0277 [NMRfile,NMRpath] = uigetfile(pathstr,'Choose Data file'); -0278 end -0279 case 'PM5' -0280 % if there is already a data folder present we start from here -0281 if isfield(import,'path') -0282 NMRpath = uigetdir(import.path,'Choose PM5 Data Path'); -0283 else -0284 % otherwise we start at the current working dircetory -0285 % 'NMRpath' holds the name of the choosen data path -0286 here = mfilename('fullpath'); -0287 [pathstr,~,~] = fileparts(here); -0288 NMRpath = uigetdir(pathstr,'Choose PM5 Data Path'); -0289 end -0290 -0291 % check if there are multiple inf-files available -0292 % if yes -> choose one -0293 inffiles = dir(fullfile(NMRpath,'*.inf')); -0294 if numel(inffiles) > 1 -0295 [NMRfile,NMRpath] = uigetfile(fullfile(NMRpath,'*.inf'),... -0296 'Choose INF file'); -0297 elseif numel(inffiles) == 1 -0298 NMRfile = inffiles.name; -0299 end -0300 end -0301 -0302 end -0303 -0304 %% -0305 function [data,gui] = importDataBGR(data,gui) -0306 -0307 % first check the subpaths -0308 % there should be 'cpmgfastauto' and 't1test' -0309 t1path = dir(fullfile(data.import.path,'t1test')); -0310 t1path = t1path(~ismember({t1path.name},{'.','..'})); -0311 t2path = dir(fullfile(data.import.path,'cpmgfastauto')); -0312 t2path = t2path(~ismember({t2path.name},{'.','..'})); -0313 -0314 fnames = struct; -0315 % shownames is just a dummy to hold all data file names that -0316 % will be shown in the listbox -0317 shownames = cell(1,1); -0318 -0319 c = 0; -0320 if ~isempty(t1path) -0321 for i = 1:size(t1path,1) -0322 in.T1T2 = 'T1'; -0323 in.path = fullfile(data.import.path,'t1test',t1path(i).name); -0324 in.fileformat = data.import.fileformat; -0325 out = LoadNMRData_driver(in); -0326 -0327 for j = 1:size(out.nmrData,2) -0328 % the individual file names -0329 c = c + 1; -0330 fnames(c).parfile = 'acq.par'; -0331 fnames(c).datafile = out.nmrData{j}.datfile; -0332 -0333 shownames{c} = ['T1_',t1path(i).name,'_',fnames(c).datafile]; -0334 -0335 % the NMR data -0336 % here we fix the time scale from [ms] to [s] -0337 if max(out.nmrData{j}.time) > 100 -0338 out.nmrData{j}.time = out.nmrData{j}.time/1000; -0339 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; -0340 end -0341 data.import.NMR.data{c} = out.nmrData{j}; -0342 data.import.NMR.para{c} = out.parData; -0343 end -0344 end -0345 end -0346 -0347 if ~isempty(t2path) -0348 for i = 1:size(t2path,1) -0349 in.T1T2 = 'T2'; -0350 in.path = fullfile(data.import.path,'cpmgfastauto',t2path(i).name); -0351 in.fileformat = data.import.fileformat; -0352 out = LoadNMRData_driver(in); -0353 -0354 for j = 1:size(out.nmrData,2) -0355 % the individual file names -0356 c = c + 1; -0357 fnames(c).parfile = 'acq.par'; -0358 fnames(c).datafile = out.nmrData{j}.datfile; -0359 fnames(c).T2specfile = ''; -0360 -0361 shownames{c} = ['T2_',t2path(i).name,'_',fnames(c).datafile]; -0362 -0363 % the NMR data -0364 % here we fix the time scale from [ms] to [s] -0365 if max(out.nmrData{j}.time) > 100 -0366 out.nmrData{j}.time = out.nmrData{j}.time/1000; -0367 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; -0368 end -0369 data.import.NMR.data{c} = out.nmrData{j}; -0370 data.import.NMR.para{c} = out.parData; -0371 end -0372 end -0373 end -0374 -0375 if isempty(t1path) && isempty(t2path) -0376 helpdlg('No data folders in the given directory.','onMenuImport: No data.'); -0377 else -0378 % update the global data structure -0379 data.import.NMR.files = fnames; -0380 data.import.NMR.filesShort = shownames; -0381 end -0382 -0383 end -0384 -0385 %% -0386 function [data,gui] = importDataBGRmat(data,gui) -0387 -0388 in.path = fullfile(data.import.path); -0389 in.name = data.import.file; -0390 in.fileformat = data.import.fileformat; -0391 out = LoadNMRData_driver(in); -0392 -0393 fnames = struct; -0394 % shownames is just a dummy to hold all data file names that -0395 % will be shown in the listbox -0396 shownames = cell(1,1); -0397 -0398 c = 0; -0399 table = {true,0,1,'D'}; -0400 for j = 1:size(out.nmrData,2) -0401 % the individual file names -0402 c = c + 1; -0403 fnames(c).parfile = ''; -0404 fnames(c).datafile = data.import.file; -0405 fnames(c).T2specfile = ''; -0406 -0407 shownames{c} = out.parData{j}.file; -0408 -0409 data.import.NMR.data{c} = out.nmrData{j}; -0410 data.import.NMR.para{c} = out.parData{j}; -0411 -0412 if isfield(out,'pressData') -0413 % convert hPa to Pa -0414 table{c,1} = true; -0415 table{c,2} = out.pressData.p(j)*1e2; -0416 table{c,3} = out.pressData.S(j); -0417 table{c,4} = 'D'; -0418 end +0182 % update the list of file names +0183 set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); +0184 set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); +0185 +0186 % create a global INVdata struct for every file in the list +0187 if isstruct(getappdata(fig,'INVdata')) +0188 setappdata(fig,'INVdata',[]); +0189 end +0190 INVdata = cell(length(data.import.NMR.filesShort),1); +0191 setappdata(fig,'INVdata',INVdata); +0192 +0193 % clear all axes +0194 clearAllAxes(gui.figh); +0195 +0196 % update GUI data and interface +0197 setappdata(fig,'data',data); +0198 setappdata(fig,'gui',gui); +0199 enableGUIelements('NMR'); +0200 +0201 % special treatment of LIAG projects +0202 switch label +0203 case {'LIAG from project','LIAG last project'} +0204 cpath = data.import.LIAG.calibrationpath; +0205 % check if this calibration file was already used +0206 isfile = dir(fullfile(cpath,'NUCLEUS_calibData.mat')); +0207 if ~isempty(isfile) +0208 id = 2; +0209 % if data is there reuse it +0210 calib = load(fullfile(cpath,isfile.name),'calib'); +0211 INVdata{id} = calib.calib; +0212 data.calib = INVdata{id}.calib; +0213 data.import.LIAG.Tbulk = INVdata{id}.results.invstd.T2; +0214 setappdata(fig,'INVdata',INVdata); +0215 setappdata(fig,'data',data); +0216 % color the list entry +0217 strL = get(gui.listbox_handles.signal,'String'); +0218 str1 = strL{id}; +0219 str2 = ['<HTML><BODY bgcolor="rgb(',... +0220 sprintf('%d,%d,%d',gui.myui.colors.listINV.*255),')">',... +0221 str1,'</BODY></HTML>']; +0222 strL{id} = str2; +0223 set(gui.listbox_handles.signal,'String',strL); +0224 end +0225 otherwise +0226 end +0227 % update GUI interface +0228 NUCLEUSinv_updateInterface; +0229 end +0230 +0231 catch ME +0232 % show error message in case import fails +0233 errmsg = {ME.message;[ME.stack(1).name,' Line: ',num2str(ME.stack(1).line)];... +0234 'Check File Format settings.'}; +0235 errordlg(errmsg,'importNMRdata: Error!'); +0236 +0237 end +0238 +0239 end +0240 +0241 %% +0242 function [NMRpath,NMRfile] = getNMRPathFile(label,import) +0243 +0244 NMRpath = -1; +0245 NMRfile = -1; +0246 % for almost all import cases we load a folder ... but not for all +0247 switch label +0248 case {'GGE ascii','GGE field','CoreLab ascii','MOUSE','LIAG single',... +0249 'BGR std','MouseCPMG','MouseLiftSingle','MouseLiftAll','Helios','BAM TOM','PM25'} +0250 % if there is already a data folder present we start from here +0251 if isfield(import,'path') +0252 NMRpath = uigetdir(import.path,'Choose Data Path'); +0253 else +0254 % otherwise we start at the current working dircetory +0255 % 'NMRpath' holds the name of the choosen data path +0256 here = mfilename('fullpath'); +0257 [pathstr,~,~] = fileparts(here); +0258 NMRpath = uigetdir(pathstr,'Choose Data Path'); +0259 end +0260 case 'LIAG from project' +0261 % if there is already a data folder present we start from here +0262 if isfield(import,'path') +0263 NMRpath = uigetdir(import.path,'Choose Project Path'); +0264 else +0265 % otherwise we start at the current working dircetory +0266 % 'NMRpath' holds the name of the choosen data path +0267 here = mfilename('fullpath'); +0268 [pathstr,~,~] = fileparts(here); +0269 NMRpath = uigetdir(pathstr,'Choose Project Path'); +0270 end +0271 case 'LIAG last project' +0272 % there is already a data folder and we use this one +0273 if isfield(import,'path') +0274 NMRpath = import.path; +0275 else +0276 % otherwise we start at the current working dircetory +0277 % 'NMRpath' holds the name of the choosen data path +0278 here = mfilename('fullpath'); +0279 [pathstr,~,~] = fileparts(here); +0280 NMRpath = uigetdir(pathstr,'Choose Project Path'); +0281 end +0282 case {'GGE Dart','BGR mat','NMR mat'} +0283 % if there is already a data folder present we start from here +0284 if isfield(import,'path') +0285 [NMRfile,NMRpath] = uigetfile(import.path,'Choose Data file'); +0286 else +0287 % otherwise we start at the current working dircetory +0288 % 'foldername' hold s the name of the choosen data path +0289 here = mfilename('fullpath'); +0290 [pathstr,~,~] = fileparts(here); +0291 [NMRfile,NMRpath] = uigetfile(pathstr,'Choose Data file'); +0292 end +0293 case 'PM5' +0294 % if there is already a data folder present we start from here +0295 if isfield(import,'path') +0296 NMRpath = uigetdir(import.path,'Choose PM5 Data Path'); +0297 else +0298 % otherwise we start at the current working dircetory +0299 % 'NMRpath' holds the name of the choosen data path +0300 here = mfilename('fullpath'); +0301 [pathstr,~,~] = fileparts(here); +0302 NMRpath = uigetdir(pathstr,'Choose PM5 Data Path'); +0303 end +0304 +0305 % check if there are multiple inf-files available +0306 % if yes -> choose one +0307 inffiles = dir(fullfile(NMRpath,'*.inf')); +0308 if numel(inffiles) > 1 +0309 [NMRfile,NMRpath] = uigetfile(fullfile(NMRpath,'*.inf'),... +0310 'Choose INF file'); +0311 elseif numel(inffiles) == 1 +0312 NMRfile = inffiles.name; +0313 end +0314 end +0315 +0316 end +0317 +0318 %% +0319 function [data,gui] = importDataMouseCPMG(data,gui) +0320 +0321 csv_t2path = dir(fullfile(data.import.path,'CPMG')); +0322 csv_t2path = csv_t2path(~ismember({csv_t2path.name},{'.','..'})); +0323 +0324 fnames = struct; +0325 % shownames is just a dummy to hold all data file names that +0326 % will be shown in the listbox +0327 shownames = cell(1,1); +0328 +0329 c = 0; +0330 if ~isempty(csv_t2path) +0331 for i = 1:size(csv_t2path,1) +0332 in.T1T2 = 'T2'; +0333 in.path = fullfile(data.import.path,'CPMG',csv_t2path(i).name); +0334 in.fileformat = data.import.fileformat; +0335 out = LoadNMRData_driver(in); +0336 +0337 for j = 1:size(out.nmrData,2) +0338 % the individual file names +0339 c = c + 1; +0340 fnames(c).parfile = 'acqu.par'; +0341 fnames(c).datafile = out.nmrData{j}.datfile; +0342 fnames(c).T2specfile = ''; +0343 +0344 shownames{c} = ['T2_',csv_t2path(i).name,'_',fnames(c).datafile]; +0345 +0346 % the NMR data +0347 % here we fix the time scale from [ms] to [s] +0348 if max(out.nmrData{j}.time) > 100 +0349 out.nmrData{j}.time = out.nmrData{j}.time/1000; +0350 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; +0351 end +0352 data.import.NMR.data{c} = out.nmrData{j}; +0353 data.import.NMR.para{c} = out.parData; +0354 end +0355 end +0356 end +0357 +0358 if isempty(csv_t2path) +0359 helpdlg('No data folders in the given directory.','onMenuImport: No data.'); +0360 else +0361 % update the global data structure +0362 data.import.NMR.files = fnames; +0363 data.import.NMR.filesShort = shownames; +0364 end +0365 +0366 end +0367 +0368 %% +0369 function [data,gui] = importDataBGRmat(data,gui) +0370 +0371 in.path = fullfile(data.import.path); +0372 in.name = data.import.file; +0373 in.fileformat = data.import.fileformat; +0374 out = LoadNMRData_driver(in); +0375 +0376 fnames = struct; +0377 % shownames is just a dummy to hold all data file names that +0378 % will be shown in the listbox +0379 shownames = cell(1,1); +0380 +0381 c = 0; +0382 table = {true,0,1,'D'}; +0383 for j = 1:size(out.nmrData,2) +0384 % the individual file names +0385 c = c + 1; +0386 fnames(c).parfile = ''; +0387 fnames(c).datafile = data.import.file; +0388 fnames(c).T2specfile = ''; +0389 +0390 shownames{c} = out.parData{j}.file; +0391 +0392 data.import.NMR.data{c} = out.nmrData{j}; +0393 data.import.NMR.para{c} = out.parData{j}; +0394 +0395 if isfield(out,'pressData') +0396 % convert hPa to Pa +0397 table{c,1} = true; +0398 table{c,2} = out.pressData.p(j)*1e2; +0399 table{c,3} = out.pressData.S(j); +0400 table{c,4} = 'D'; +0401 end +0402 end +0403 +0404 % global Tbulk +0405 data.invstd.Tbulk = out.parData{1}.Tbulk; +0406 % global porosity +0407 data.import.BGR.porosity = out.parData{1}.porosity; +0408 +0409 data.import.NMR.files = fnames; +0410 data.import.NMR.filesShort = shownames; +0411 +0412 % import pressure / saturation data +0413 if isfield(out,'pressData') +0414 data.pressure.unit = 'kPa'; +0415 data.pressure.unitfac = 1e-3; +0416 data.pressure.table = table; +0417 end +0418 0419 end 0420 -0421 % global Tbulk -0422 data.invstd.Tbulk = out.parData{1}.Tbulk; -0423 % global porosity -0424 data.import.BGR.porosity = out.parData{1}.porosity; -0425 -0426 data.import.NMR.files = fnames; -0427 data.import.NMR.filesShort = shownames; -0428 -0429 % import pressure / saturation data -0430 if isfield(out,'pressData') -0431 data.pressure.unit = 'kPa'; -0432 data.pressure.unitfac = 1e-3; -0433 data.pressure.table = table; -0434 end -0435 +0421 %% +0422 function [data,gui] = importDataBGRliftSingle(data,gui) +0423 +0424 % first check whether T1 or T2 was measured... +0425 % by analyzing the name of data folder +0426 indiz = find(data.import.path == filesep); +0427 checkT1T2 = data.import.path(indiz(end-1)+1:indiz(end)-1); +0428 if strcmp(checkT1T2,'t1test') +0429 in.T1T2 = 'T1'; +0430 elseif strcmp(checkT1T2,'cpmgfastautotest') +0431 in.T1T2 = 'T2'; +0432 elseif strcmp(checkT1T2,'cpmgfastauto') +0433 in.T1T2 = 'T2'; +0434 else +0435 disp('Please chose an original Prospa folder for Mouse Lift data!'); 0436 end 0437 -0438 %% -0439 function [data,gui] = importDataDart(data,gui) +0438 % % there should be folders with integer values in their names +0439 % t1t2path = data.import.path; 0440 -0441 in.path = fullfile(data.import.path); -0442 in.name = data.import.file; -0443 in.fileformat = data.import.fileformat; -0444 out = LoadNMRData_driver(in); +0441 fnames = struct; +0442 % shownames is just a dummy to hold all data file names that +0443 % will be shown in the listbox +0444 shownames = cell(1,1); 0445 -0446 fnames = struct; -0447 % shownames is just a dummy to hold all data file names that -0448 % will be shown in the listbox -0449 shownames = cell(1,1); -0450 -0451 c = 0; -0452 for j = 1:size(out.nmrData,2) -0453 % the individual file names -0454 c = c + 1; -0455 fnames(c).parfile = ''; -0456 fnames(c).datafile = data.import.file; -0457 fnames(c).T2specfile = ''; -0458 -0459 shownames{c} = ['depth_',sprintf('%04.3f',out.parData{j}.depth)]; -0460 -0461 % the NMR data -0462 % here we fix the time scale from [ms] to [s] -0463 if max(out.nmrData{j}.time) > 100 -0464 out.nmrData{j}.time = out.nmrData{j}.time/1000; -0465 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; -0466 end -0467 data.import.NMR.data{c} = out.nmrData{j}; -0468 data.import.NMR.para{c} = out.parData{j}; -0469 end -0470 -0471 data.import.NMR.files = fnames; -0472 data.import.NMR.filesShort = shownames; +0446 c = 0; +0447 if ~isempty(data.import.path) +0448 % for i = 1:size(t1t2path,1) +0449 in.path = data.import.path; +0450 in.fileformat = data.import.fileformat; +0451 out = LoadNMRData_driver(in); +0452 +0453 for j = 1:size(out.nmrData,2) +0454 % the individual file names +0455 c = c + 1; +0456 fnames(c).parfile = 'acq.par'; +0457 fnames(c).datafile = out.nmrData{j}.datfile; +0458 +0459 shownames{c} = [in.T1T2,'_',fnames(c).datafile]; +0460 +0461 % the NMR data +0462 % here we fix the time scale from [ms] to [s] +0463 if max(out.nmrData{j}.time) > 100 +0464 out.nmrData{j}.time = out.nmrData{j}.time/1000; +0465 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; +0466 end +0467 data.import.NMR.data{c} = out.nmrData{j}; +0468 data.import.NMR.para{c} = out.parData; +0469 end +0470 else +0471 helpdlg('No data folders in the given directory.','onMenuImport: No data.'); +0472 end 0473 -0474 end -0475 -0476 %% -0477 function [data,gui] = importDataGeneral(data,gui) +0474 +0475 % update the global data structure +0476 data.import.NMR.files = fnames; +0477 data.import.NMR.filesShort = shownames; 0478 -0479 % look for all files ending with '.par' -0480 % should exist for T1 and T2 measurements -0481 filenames = dir(fullfile(data.import.path,'*.par')); +0479 end +0480 %% +0481 function [data,gui] = importDataBGRliftAll(data,gui) 0482 -0483 fnames = struct; -0484 % shownames is just a dummy to hold all data file names that -0485 % will be shown in the listbox -0486 shownames = cell(1,1); -0487 -0488 % loop over all found files and import the data -0489 c = 0; -0490 in.path = data.import.path; -0491 for i = 1:size(filenames,1) -0492 ind = strfind(filenames(i).name,'.'); -0493 ind = max(ind); -0494 in.name = filenames(i).name(1:ind-1); -0495 in.fileformat = data.import.fileformat; -0496 out = LoadNMRData_driver(in); -0497 -0498 for j = 1:size(out.nmrData,2) -0499 % the individual file names -0500 c = c + 1; -0501 fnames(c).parfile = filenames(i).name; -0502 fnames(c).datafile = out.nmrData{j}.datfile; -0503 if strcmp(out.nmrData{j}.flag,'T2') && isfield(out.nmrData{j},'specfile') -0504 fnames(c).T2specfile = out.nmrData{j}.specfile; -0505 else -0506 fnames(c).T2specfile = ''; -0507 end -0508 shownames{c} = fnames(c).datafile; -0509 -0510 % the NMR data -0511 % here we fix the time scale from [ms] to [s] -0512 if max(out.nmrData{j}.time) > 100 -0513 out.nmrData{j}.time = out.nmrData{j}.time/1000; -0514 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; -0515 end -0516 data.import.NMR.data{c} = out.nmrData{j}; -0517 data.import.NMR.para{c} = out.parData; -0518 end -0519 end -0520 -0521 switch data.import.fileformat -0522 case 'bamtom' -0523 nslices = out.parData.nSlices; -0524 ncsvfiles = numel(fnames); -0525 -0526 % check for background file ("Leermessung") -0527 has_bg = false; -0528 for i = 1:numel(fnames) -0529 if ~isempty(strfind(fnames(i).datafile,'000')) -0530 has_bg = true; -0531 index_bg = i; -0532 break; -0533 end -0534 end -0535 -0536 if has_bg -0537 % background data set -0538 bg = data.import.NMR.data{index_bg}; -0539 -0540 % vector of indices of the files that get corrected -0541 ind_files = 1:1:ncsvfiles; -0542 ind_files(ind_files==index_bg) = []; -0543 -0544 for i = ind_files -0545 % subtract the background signal -0546 s = data.import.NMR.data{i}.signal; -0547 s_bg = bg.signal; -0548 % if the background signal is longer than the signal cut it -0549 if numel(s_bg) > numel(s) -0550 tmp_s = s_bg(1:numel(s)); -0551 else % if not pad it with zeros -0552 tmp_s = zeros(size(s)); -0553 tmp_s(1:numel(s_bg)) = s_bg; -0554 end -0555 s = complex(real(s)-real(tmp_s),imag(s)-imag(tmp_s)); -0556 % update original data set -0557 data.import.NMR.data{i}.signal = s; -0558 end -0559 -0560 % check if the number of slices is equal to the number of files -0561 % (excluding the background file) -0562 if nslices == numel(ind_files) -0563 % create z-vector -0564 p = out.parData; -0565 zslice = linspace(p.startPos,p.endPos,p.nSlices)'; -0566 data.import.BAM.use_z = true; -0567 data.import.BAM.zslice = zslice; -0568 if numel(zslice) > 1 -0569 c = 0; -0570 for i = ind_files -0571 c = c + 1; -0572 tmp = shownames{i}; -0573 shownames{i} = [tmp,' z:',sprintf('%5.4f',zslice(c))]; -0574 end -0575 end -0576 else -0577 data.import.BAM.use_z = false; -0578 data.import.BAM.zslice = 1:1:max([numel(ind_files) 1]); +0483 % first check whether T1 or T2 was measured +0484 indiz = find(data.import.path == filesep); +0485 checkT1T2 = data.import.path(indiz(end)+1:end); +0486 if strcmp(checkT1T2,'t1test') +0487 in.T1T2 = 'T1'; +0488 elseif strcmp(checkT1T2,'cpmgfastautotest') +0489 in.T1T2 = 'T2'; +0490 elseif strcmp(checkT1T2,'cpmgfastauto') +0491 in.T1T2 = 'T2'; +0492 else +0493 helpdlg('No original data folder','onMenuImport: No data.'); +0494 end +0495 +0496 % there should be folders with integer values in their names +0497 t1t2path = dir(data.import.path); +0498 t1t2path = t1t2path(~ismember({t1t2path.name},{'.','..'})); +0499 +0500 fnames = struct; +0501 % shownames is just a dummy to hold all data file names that +0502 % will be shown in the listbox +0503 shownames = cell(1,1); +0504 +0505 c = 0; +0506 if ~isempty(t1t2path) +0507 for i = 1:size(t1t2path,1) +0508 in.path = fullfile(data.import.path,t1t2path(i).name); +0509 in.fileformat = data.import.fileformat; +0510 out = LoadNMRData_driver(in); +0511 +0512 for j = 1:size(out.nmrData,2) +0513 % the individual file names +0514 c = c + 1; +0515 fnames(c).parfile = 'acq.par'; +0516 fnames(c).datafile = out.nmrData{j}.datfile; +0517 +0518 shownames{c} = [in.T1T2,'_',t1t2path(i).name,'_',fnames(c).datafile]; +0519 +0520 % the NMR data +0521 % here we fix the time scale from [ms] to [s] +0522 if max(out.nmrData{j}.time) > 100 +0523 out.nmrData{j}.time = out.nmrData{j}.time/1000; +0524 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; +0525 end +0526 data.import.NMR.data{c} = out.nmrData{j}; +0527 data.import.NMR.para{c} = out.parData; +0528 end +0529 end +0530 else +0531 helpdlg('No data folders in the given directory.','onMenuImport: No data.'); +0532 end +0533 % update the global data structure +0534 data.import.NMR.files = fnames; +0535 data.import.NMR.filesShort = shownames; +0536 +0537 end +0538 +0539 %% +0540 function [data,gui] = importDataHelios(data,gui) +0541 +0542 % first check the subpaths +0543 % there should be some folders with names ... +0544 % ... similar to the data filenames inside them +0545 datpath = dir(data.import.path); +0546 datpath = datpath(~ismember({datpath.name},{'.','..'})); +0547 +0548 fnames = struct; +0549 % shownames is just a dummy to hold all data file names that +0550 % will be shown in the listbox +0551 shownames = cell(1,1); +0552 +0553 c = 0; +0554 if ~isempty(datpath) +0555 for i = 1:size(datpath,1) +0556 % does datpath.name points to a folder? +0557 if datpath(i).isdir +0558 % check if datpath.name includes regular Helios data files +0559 content = dir([data.import.path,filesep,datpath(i).name]); +0560 content = content(~ismember({content.name},{'.','..'})); +0561 for j = 1:size(content,1) +0562 if strcmp(content(j).name,[datpath(i).name,'_1.hrd']) +0563 in.T1T2 = 'T2'; +0564 in.name = content(j).name; +0565 in.path = fullfile(data.import.path,filesep,datpath(i).name); +0566 in.fileformat = data.import.fileformat; +0567 out = LoadNMRData_driver(in); +0568 +0569 % the individual file names +0570 c = c + 1; +0571 fnames(c).parfile = ''; +0572 fnames(c).datafile = out.nmrData.datfile; +0573 fnames(c).T2specfile = ''; +0574 shownames{c} = ['T2_',datpath(i).name]; +0575 +0576 data.import.NMR.data{c} = out.nmrData; +0577 data.import.NMR.para{c} = out.parData; +0578 end 0579 end -0580 -0581 else -0582 if nslices == ncsvfiles -0583 % create z-vector -0584 p = out.parData; -0585 zslice = linspace(p.startPos,p.endPos,p.nSlices)'; -0586 data.import.BAM.use_z = true; -0587 data.import.BAM.zslice = zslice; -0588 if numel(zslice) > 1 -0589 for i = 1:numel(zslice) -0590 tmp = shownames{i}; -0591 shownames{i} = [tmp,' z:',sprintf('%5.4f',zslice(i))]; -0592 end -0593 end -0594 else -0595 data.import.BAM.use_z = false; -0596 data.import.BAM.zslice = 1:1:ncsvfiles; -0597 end -0598 end -0599 end -0600 -0601 % update the global data structure -0602 data.import.NMR.files = fnames; -0603 data.import.NMR.filesShort = shownames; -0604 -0605 end -0606 -0607 %% -0608 function [data,gui] = importDataLIAG(data,gui) -0609 -0610 in.path = fullfile(data.import.path); -0611 in.fileformat = data.import.fileformat; -0612 out = LoadNMRData_driver(in); -0613 -0614 fnames = struct; -0615 % shownames is just a dummy to hold all data file names that -0616 % will be shown in the listbox -0617 shownames = cell(1,1); -0618 -0619 c = 0; -0620 for j = 1:size(out.nmrData,2) -0621 % the individual file names -0622 c = c + 1; -0623 fnames(c).parfile = 'acqu.par'; -0624 fnames(c).datafile = out.nmrData{j}.datfile; -0625 fnames(c).T2specfile = ''; -0626 -0627 shownames{c} = fnames(c).datafile; -0628 -0629 % the NMR data -0630 % here we fix the time scale to [s] if neccessary -0631 TE = out.parData.echoTime; % [µs] -0632 if out.nmrData{j}.time(1)== TE/1e3 -0633 % change [ms] to [s] -0634 out.nmrData{j}.time = out.nmrData{j}.time/1e3; -0635 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1e3; -0636 elseif out.nmrData{j}.time(1)== TE -0637 % change [µs] to [s] -> very unlikely -0638 out.nmrData{j}.time = out.nmrData{j}.time/1e6; -0639 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1e6; -0640 end -0641 data.import.NMR.data{c} = out.nmrData{j}; -0642 data.import.NMR.para{c} = out.parData; -0643 end -0644 -0645 % update the global data structure -0646 data.import.NMR.files = fnames; -0647 data.import.NMR.filesShort = shownames; -0648 -0649 end -0650 -0651 %% -0652 function [data,gui] = importDataLIAGproject(data,gui) -0653 -0654 % 1) show all folders and ask for sample -0655 subdirs = dir(data.import.path); -0656 % remove the dot-dirs -0657 subdirs = subdirs(~ismember({subdirs.name},{'.','..'})); -0658 -0659 fnames = {subdirs.name}; -0660 [indx,~] = listdlg('PromptString','Select Sample:',... -0661 'SelectionMode','single',... -0662 'ListString',fnames); -0663 -0664 if ~isempty(indx) -0665 % 2) check corresponding SampleParameter.par file for reference and -0666 % calibration sample and other parameters -0667 datapath = fullfile(data.import.path,fnames{indx}); -0668 % load SampleParameter file for sample -0669 [SampleParameter] = loadGUIParameters(datapath,'SampleParameters.par'); -0670 if isfield(SampleParameter,'sampleVolume') -0671 dataVol = SampleParameter.sampleVolume; -0672 else -0673 dataVol = 1; -0674 end -0675 -0676 % 2a) background file #1 -0677 backgroundFile1 = SampleParameter.backgroundFile; -0678 if isempty(backgroundFile1) -0679 bnames = {subdirs.name}; -0680 bnames(indx) = []; -0681 [indb,~] = listdlg('PromptString','Select Background File:',... -0682 'SelectionMode','single',... -0683 'ListString',bnames); -0684 if ~isempty(indb) -0685 backgroundFile1 = bnames{indb}; -0686 else -0687 backgroundFile1 = ''; -0688 end -0689 end -0690 if ~isempty(backgroundFile1) -0691 ind = strfind(backgroundFile1,filesep); -0692 if ~isempty(ind) -0693 backgroundFile1 = backgroundFile1(ind(end)+1:end); -0694 end -0695 fileInList = ismember(fnames,{backgroundFile1}); -0696 if any(fileInList) -0697 backgroundpath1 = fullfile(data.import.path,fnames{fileInList}); -0698 end -0699 else -0700 backgroundpath1 = ''; -0701 backgroundFile1 = ''; -0702 end -0703 backVol = 1; -0704 -0705 % 2b) calibration file -0706 c = 0; -0707 if isfield(SampleParameter,'calibrationFile0') -0708 c = c + 1; -0709 calibrationFiles{c} = SampleParameter.calibrationFile0; -0710 end -0711 if isfield(SampleParameter,'calibrationFile1') -0712 c = c + 1; -0713 calibrationFiles{c} = SampleParameter.calibrationFile1; -0714 end -0715 if isfield(SampleParameter,'calibrationFile2') -0716 c = c + 1; -0717 calibrationFiles{c} = SampleParameter.calibrationFile2; -0718 end -0719 if isfield(SampleParameter,'calibrationFile3') -0720 c = c + 1; -0721 calibrationFiles{c} = SampleParameter.calibrationFile3; -0722 end -0723 -0724 % find the non-empty one -0725 ind = ismember(calibrationFiles,{''}); -0726 % there are three possibilities: 0, 1 and more than 1 calib. files -0727 calibrationFiles(ind) = []; -0728 if isempty(calibrationFiles) -0729 cnames = {subdirs.name}; -0730 cnames(indx) = []; -0731 [indc,~] = listdlg('PromptString','Select Calibration File:',... -0732 'SelectionMode','single',... -0733 'ListString',cnames); -0734 if ~isempty(indc) -0735 calibrationFiles = cnames{indc}; -0736 else -0737 calibrationFiles = ''; -0738 end -0739 else -0740 % if there are more than one let the user select the correct one -0741 if numel(calibrationFiles) > 1 -0742 [ind,~] = listdlg('PromptString','Select Calibration File:',... -0743 'SelectionMode','single',... -0744 'ListString',calibrationFiles); -0745 calibrationFiles = calibrationFiles{ind}; -0746 else -0747 calibrationFiles = calibrationFiles{1}; -0748 end -0749 end -0750 if ~isempty(calibrationFiles) -0751 ind = strfind(calibrationFiles,filesep); -0752 if ~isempty(ind) -0753 calibrationFiles = calibrationFiles(ind(end)+1:end); -0754 end -0755 fileInList = ismember(fnames,{calibrationFiles}); -0756 if any(fileInList) -0757 calibrationpath = fullfile(data.import.path,fnames{fileInList}); -0758 end -0759 else -0760 calibrationpath = ''; -0761 calibrationFiles = ''; -0762 end -0763 -0764 if ~isempty(calibrationpath) -0765 [SampleParameterC] = loadGUIParameters(calibrationpath,'SampleParameters.par'); -0766 if isfield(SampleParameterC,'sampleVolume') -0767 calibVol = SampleParameterC.sampleVolume; -0768 else -0769 calibVol = 1; -0770 end -0771 -0772 % 2a) background file #2 -0773 backgroundFile2 = SampleParameterC.backgroundFile; -0774 if isempty(backgroundFile2) -0775 bnames = {subdirs.name}; -0776 bnames(indx) = []; -0777 [indb,~] = listdlg('PromptString','Select Background File for Calibration:',... -0778 'SelectionMode','single',... -0779 'ListString',bnames); -0780 if ~isempty(indb) -0781 backgroundFile2 = bnames{indb}; -0782 else -0783 backgroundFile2 = ''; -0784 end -0785 end -0786 if ~isempty(backgroundFile2) -0787 ind = strfind(backgroundFile2,filesep); -0788 if ~isempty(ind) -0789 backgroundFile2 = backgroundFile2(ind(end)+1:end); -0790 end -0791 fileInList = ismember(fnames,{backgroundFile2}); -0792 if any(fileInList) -0793 backgroundpath2 = fullfile(data.import.path,fnames{fileInList}); -0794 end -0795 else -0796 backgroundpath2 = ''; -0797 backgroundFile2 = ''; -0798 end -0799 else -0800 calibVol = 1; -0801 backgroundpath2 = ''; -0802 backgroundFile2 = ''; -0803 end -0804 -0805 % 3) now load the data -0806 workpaths = {datapath,calibrationpath,backgroundpath1,backgroundpath2}; -0807 workfiles = {fnames{indx},[calibrationFiles,' - calibration'],... -0808 [backgroundFile1,' - backgroundS'],[backgroundFile2,' - backgroundC']}; -0809 out = cell(size(workpaths)); -0810 count = 0; -0811 keep = false(size(workpaths)); -0812 for i = 1:numel(workpaths) -0813 if ~isempty(workpaths{i}) -0814 workdirs = dir(workpaths{i}); -0815 workdirs = workdirs(~ismember({workdirs.name},{'.','..'})); -0816 isT2 = ismember({workdirs.name},{'T2CPMG'}); -0817 if any(isT2) -0818 keep(i) = true; -0819 count = count + 1; -0820 T2path = fullfile(workdirs(isT2).folder,workdirs(isT2).name); -0821 in.path = T2path; -0822 in.fileformat = data.import.fileformat; -0823 out{i} = LoadNMRData_driver(in); -0824 end -0825 end -0826 end -0827 -0828 if isempty(backgroundpath1) -0829 ref1 = struct; -0830 else -0831 background1 = out{3}; -0832 % get the background data 1 -0833 ref1.t = background1.nmrData{1}.time; -0834 ref1.s = background1.nmrData{1}.signal; -0835 [ref1.s,~] = rotateT2phase(ref1.s); -0836 end -0837 -0838 if isempty(backgroundpath2) -0839 ref2 = struct; -0840 else -0841 background2 = out{4}; -0842 % get the background data 2 -0843 ref2.t = background2.nmrData{1}.time; -0844 ref2.s = background2.nmrData{1}.signal; -0845 [ref2.s,~] = rotateT2phase(ref2.s); -0846 end -0847 -0848 workpaths = workpaths(keep); -0849 workfiles = workfiles(keep); -0850 out = out(keep); -0851 -0852 ffnames = struct; -0853 % shownames is just a dummy to hold all data file names that -0854 % will be shown in the listbox -0855 shownames = cell(1,1); -0856 -0857 for i = 1:count -0858 ffnames(i).parfile = 'acqu.par'; -0859 ffnames(i).datafile = workfiles{i}; -0860 ffnames(i).T2specfile = ''; -0861 -0862 shownames{i} = ffnames(i).datafile; -0863 -0864 % the NMR data -0865 % here we fix the time scale to [s] if neccessary -0866 TE = out{i}.parData.echoTime; % [µs] -0867 if out{i}.nmrData{1}.time(1)== TE/1e3 -0868 % change [ms] to [s] -0869 out{i}.nmrData{1}.time = out{i}.nmrData{1}.time/1e3; -0870 out{i}.nmrData{1}.raw.time = out{i}.nmrData{1}.raw.time/1e3; -0871 elseif out{i}.nmrData{1}.time(1)== TE -0872 % change [µs] to [s] -> very unlikely -0873 out{i}.nmrData{1}.time = out{i}.nmrData{1}.time/1e6; -0874 out{i}.nmrData{1}.raw.time = out{i}.nmrData{1}.raw.time/1e6; -0875 end -0876 -0877 data.import.NMR.data{i} = out{i}.nmrData{1}; -0878 data.import.NMR.para{i} = out{i}.parData; -0879 data.import.NMR.para{i}.SampleParameter = SampleParameter; -0880 -0881 % subtract the background signal -0882 s = data.import.NMR.data{i}.signal; -0883 if i==1 && isfield(ref1,'s') -0884 % if the background signal is longer than the signal cut it, if -0885 % not extend it with zeros -0886 if numel(ref1.s) > numel(s) -0887 tmp_r = ref1.s(1:numel(s)); -0888 else -0889 tmp_r = zeros(size(s)); -0890 tmp_r(1:numel(ref1.s)) = ref1.s; -0891 end -0892 s = complex(real(s)-real(tmp_r),imag(s)-imag(tmp_r)); -0893 elseif i==2 && isfield(ref2,'s') -0894 % if the background signal is longer than the signal cut it, if -0895 % not extend it with zeros -0896 if numel(ref2.s) > numel(s) -0897 tmp_r = ref2.s(1:numel(s)); -0898 else -0899 tmp_r = zeros(size(s)); -0900 tmp_r(1:numel(ref2.s)) = ref2.s; -0901 end -0902 s = complex(real(s)-real(tmp_r),imag(s)-imag(tmp_r)); -0903 end -0904 data.import.NMR.data{i}.signal = s; -0905 data.import.NMR.data{i}.raw.signal = s; -0906 -0907 if ~isempty(strfind(workfiles{i},' - background')) -0908 data.import.LIAG.sampleVol(i) = backVol; -0909 elseif ~isempty(strfind(workfiles{i},' - calibration')) -0910 data.import.LIAG.sampleVol(i) = calibVol; -0911 elseif isempty(strfind(workfiles{i},' - background')) &&... -0912 isempty(strfind(workfiles{i},' - calibration')) -0913 data.import.LIAG.sampleVol(i) = dataVol; -0914 end -0915 end -0916 data.import.LIAG.Tbulk = 1e6; -0917 data.import.LIAG.workpaths = workpaths; -0918 data.import.LIAG.datapath = datapath; -0919 data.import.LIAG.calibrationpath = calibrationpath; -0920 data.import.LIAG.backgroundpath1 = backgroundpath1; -0921 data.import.LIAG.backgroundpath2 = backgroundpath2; -0922 -0923 % update the global data structure -0924 data.import.NMR.files = ffnames; -0925 data.import.NMR.filesShort = shownames; -0926 -0927 end -0928 -0929 end -0930 -0931 %% -0932 function [data,gui] = importDataMouse(data,gui) -0933 -0934 in.path = fullfile(data.import.path); -0935 in.fileformat = data.import.fileformat; -0936 out = LoadNMRData_driver(in); -0937 -0938 fnames = struct; -0939 % shownames is just a dummy to hold all data file names that -0940 % will be shown in the listbox -0941 shownames = cell(1,1); -0942 -0943 c = 0; -0944 for j = 1:size(out.nmrData,2) -0945 % the individual file names -0946 c = c + 1; -0947 fnames(c).parfile = 'acq.par'; -0948 fnames(c).datafile = out.nmrData{j}.datfile; -0949 fnames(c).T2specfile = ''; -0950 -0951 shownames{c} = ['T2_',fnames(c).datafile]; -0952 -0953 % the NMR data -0954 % here we fix the time scale from [ms] to [s] -0955 if max(out.nmrData{j}.time) > 100 -0956 out.nmrData{j}.time = out.nmrData{j}.time/1000; -0957 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; -0958 end -0959 data.import.NMR.data{c} = out.nmrData{j}; -0960 data.import.NMR.para{c} = out.parData; -0961 end -0962 -0963 % update the global data structure -0964 data.import.NMR.files = fnames; -0965 data.import.NMR.filesShort = shownames; -0966 -0967 end -0968 -0969 %% -0970 function [data,gui] = importDataIBAC(data,gui) -0971 -0972 in.path = fullfile(data.import.path); -0973 in.name = data.import.file; -0974 in.fileformat = data.import.fileformat; -0975 out = LoadNMRData_driver(in); -0976 -0977 nslices = out.parData.depths; -0978 nfiles = size(out.nmrData,2); -0979 -0980 fnames = struct; -0981 % shownames is just a dummy to hold all data file names that -0982 % will be shown in the listbox -0983 shownames = cell(1,1); -0984 -0985 c = 0; -0986 for j = 1:size(out.nmrData,2) -0987 % the individual file names -0988 c = c + 1; -0989 fnames(c).parfile = out.parData.parfile; -0990 fnames(c).datafile = out.nmrData{j}.datfile; -0991 fnames(c).T2specfile = ''; -0992 -0993 shownames{c} = [fnames(c).datafile]; -0994 -0995 data.import.NMR.data{c} = out.nmrData{j}; -0996 data.import.NMR.para{c} = out.parData; -0997 end -0998 -0999 % check if the number of depth levels is equal to the number of -1000 % measurements -1001 if nslices == nfiles -1002 % create z-vector -1003 p = out.parData; -1004 zslice = linspace(p.initialdepth,p.finaldepth,p.depths)'; -1005 data.import.IBAC.use_z = true; -1006 data.import.IBAC.zslice = zslice; -1007 if numel(zslice) > 1 -1008 c = 0; -1009 for i = 1:nfiles -1010 c = c + 1; -1011 tmp = shownames{i}; -1012 shownames{i} = [tmp,' z:',sprintf('%05d',zslice(c))]; -1013 end -1014 end -1015 else -1016 data.import.IBAC.use_z = false; -1017 data.import.IBAC.zslice = 1:1:max([nfiles 1]); -1018 end -1019 -1020 % update the global data structure -1021 data.import.NMR.files = fnames; -1022 data.import.NMR.filesShort = shownames; -1023 -1024 end -1025 -1026 %% -1027 function data = loadGUIParameters(datapath,fname) -1028 fid = fopen(fullfile(datapath,fname)); -1029 d = textscan(fid,'%s','Delimiter','\n'); -1030 fclose(fid); -1031 data = struct; -1032 for i = 1:size(d{1},1) -1033 str = char(d{1}(i)); -1034 str = fixParameterString(str); -1035 eval(['data.',str,';']); -1036 end -1037 -1038 end -1039 -1040 %% -1041 function data = loadGUIrawdata(data,NMRpath,NMRfile) -1042 -1043 load(fullfile(NMRpath,'NUCLEUSinv_raw.mat'),'savedata'); -1044 -1045 data.import.file = NMRfile; -1046 data.import.path = NMRpath; -1047 data.import.NMR = savedata; -1048 -1049 end -1050 -1051 %------------- END OF CODE -------------- -1052 -1053 %% License: -1054 % MIT License -1055 % -1056 % Copyright (c) 2018 Thomas Hiller -1057 % -1058 % Permission is hereby granted, free of charge, to any person obtaining a copy -1059 % of this software and associated documentation files (the "Software"), to deal -1060 % in the Software without restriction, including without limitation the rights -1061 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -1062 % copies of the Software, and to permit persons to whom the Software is -1063 % furnished to do so, subject to the following conditions: -1064 % -1065 % The above copyright notice and this permission notice shall be included in all -1066 % copies or substantial portions of the Software. -1067 % -1068 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -1069 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -1070 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -1071 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -1072 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -1073 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -1074 % SOFTWARE.

    +0580 end +0581 end +0582 end +0583 +0584 data.import.NMR.files = fnames; +0585 data.import.NMR.filesShort = shownames; +0586 +0587 end +0588 +0589 %% +0590 function [data,gui] = importDataDart(data,gui) +0591 +0592 in.path = fullfile(data.import.path); +0593 in.name = data.import.file; +0594 in.fileformat = data.import.fileformat; +0595 out = LoadNMRData_driver(in); +0596 +0597 fnames = struct; +0598 % shownames is just a dummy to hold all data file names that +0599 % will be shown in the listbox +0600 shownames = cell(1,1); +0601 +0602 c = 0; +0603 for j = 1:size(out.nmrData,2) +0604 % the individual file names +0605 c = c + 1; +0606 fnames(c).parfile = ''; +0607 fnames(c).datafile = data.import.file; +0608 fnames(c).T2specfile = ''; +0609 +0610 shownames{c} = ['depth_',sprintf('%04.3f',out.parData{j}.depth)]; +0611 +0612 % the NMR data +0613 % here we fix the time scale from [ms] to [s] +0614 if max(out.nmrData{j}.time) > 100 +0615 out.nmrData{j}.time = out.nmrData{j}.time/1000; +0616 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; +0617 end +0618 data.import.NMR.data{c} = out.nmrData{j}; +0619 data.import.NMR.para{c} = out.parData{j}; +0620 end +0621 +0622 data.import.NMR.files = fnames; +0623 data.import.NMR.filesShort = shownames; +0624 +0625 end +0626 +0627 %% +0628 function [data,gui] = importDataGeneral(data,gui) +0629 +0630 % look for all files ending with '.par' +0631 % should exist for T1 and T2 measurements +0632 filenames = dir(fullfile(data.import.path,'*.par')); +0633 +0634 fnames = struct; +0635 % shownames is just a dummy to hold all data file names that +0636 % will be shown in the listbox +0637 shownames = cell(1,1); +0638 +0639 % loop over all found files and import the data +0640 c = 0; +0641 in.path = data.import.path; +0642 for i = 1:size(filenames,1) +0643 ind = strfind(filenames(i).name,'.'); +0644 ind = max(ind); +0645 in.name = filenames(i).name(1:ind-1); +0646 in.fileformat = data.import.fileformat; +0647 out = LoadNMRData_driver(in); +0648 +0649 for j = 1:size(out.nmrData,2) +0650 % the individual file names +0651 c = c + 1; +0652 fnames(c).parfile = filenames(i).name; +0653 fnames(c).datafile = out.nmrData{j}.datfile; +0654 if strcmp(out.nmrData{j}.flag,'T2') && isfield(out.nmrData{j},'specfile') +0655 fnames(c).T2specfile = out.nmrData{j}.specfile; +0656 else +0657 fnames(c).T2specfile = ''; +0658 end +0659 shownames{c} = fnames(c).datafile; +0660 +0661 % the NMR data +0662 % here we fix the time scale from [ms] to [s] +0663 if max(out.nmrData{j}.time) > 100 +0664 out.nmrData{j}.time = out.nmrData{j}.time/1000; +0665 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; +0666 end +0667 data.import.NMR.data{c} = out.nmrData{j}; +0668 data.import.NMR.para{c} = out.parData; +0669 end +0670 end +0671 +0672 switch data.import.fileformat +0673 case 'bamtom' +0674 nslices = out.parData.nSlices; +0675 ncsvfiles = numel(fnames); +0676 +0677 % check for background file ("Leermessung") +0678 has_bg = false; +0679 for i = 1:numel(fnames) +0680 if ~isempty(strfind(fnames(i).datafile,'000')) +0681 has_bg = true; +0682 index_bg = i; +0683 break; +0684 end +0685 end +0686 +0687 if has_bg +0688 % background data set +0689 bg = data.import.NMR.data{index_bg}; +0690 +0691 % vector of indices of the files that get corrected +0692 ind_files = 1:1:ncsvfiles; +0693 ind_files(ind_files==index_bg) = []; +0694 +0695 for i = ind_files +0696 % subtract the background signal +0697 s = data.import.NMR.data{i}.signal; +0698 s_bg = bg.signal; +0699 % if the background signal is longer than the signal cut it +0700 if numel(s_bg) > numel(s) +0701 tmp_s = s_bg(1:numel(s)); +0702 else % if not pad it with zeros +0703 tmp_s = zeros(size(s)); +0704 tmp_s(1:numel(s_bg)) = s_bg; +0705 end +0706 s = complex(real(s)-real(tmp_s),imag(s)-imag(tmp_s)); +0707 % update original data set +0708 data.import.NMR.data{i}.signal = s; +0709 end +0710 +0711 % check if the number of slices is equal to the number of files +0712 % (excluding the background file) +0713 if nslices == numel(ind_files) +0714 % create z-vector +0715 p = out.parData; +0716 zslice = linspace(p.startPos,p.endPos,p.nSlices)'; +0717 data.import.BAM.use_z = true; +0718 data.import.BAM.zslice = zslice; +0719 if numel(zslice) > 1 +0720 c = 0; +0721 for i = ind_files +0722 c = c + 1; +0723 tmp = shownames{i}; +0724 shownames{i} = [tmp,' z:',sprintf('%5.4f',zslice(c))]; +0725 end +0726 end +0727 else +0728 data.import.BAM.use_z = false; +0729 data.import.BAM.zslice = 1:1:max([numel(ind_files) 1]); +0730 end +0731 +0732 else +0733 if nslices == ncsvfiles +0734 % create z-vector +0735 p = out.parData; +0736 zslice = linspace(p.startPos,p.endPos,p.nSlices)'; +0737 data.import.BAM.use_z = true; +0738 data.import.BAM.zslice = zslice; +0739 if numel(zslice) > 1 +0740 for i = 1:numel(zslice) +0741 tmp = shownames{i}; +0742 shownames{i} = [tmp,' z:',sprintf('%5.4f',zslice(i))]; +0743 end +0744 end +0745 else +0746 data.import.BAM.use_z = false; +0747 data.import.BAM.zslice = 1:1:ncsvfiles; +0748 end +0749 end +0750 end +0751 +0752 % update the global data structure +0753 data.import.NMR.files = fnames; +0754 data.import.NMR.filesShort = shownames; +0755 +0756 end +0757 +0758 %% +0759 function [data,gui] = importDataLIAG(data,gui) +0760 +0761 in.path = fullfile(data.import.path); +0762 in.fileformat = data.import.fileformat; +0763 out = LoadNMRData_driver(in); +0764 +0765 fnames = struct; +0766 % shownames is just a dummy to hold all data file names that +0767 % will be shown in the listbox +0768 shownames = cell(1,1); +0769 +0770 c = 0; +0771 for j = 1:size(out.nmrData,2) +0772 % the individual file names +0773 c = c + 1; +0774 fnames(c).parfile = 'acqu.par'; +0775 fnames(c).datafile = out.nmrData{j}.datfile; +0776 fnames(c).T2specfile = ''; +0777 +0778 shownames{c} = fnames(c).datafile; +0779 +0780 % the NMR data +0781 % here we fix the time scale to [s] if neccessary +0782 TE = out.parData.echoTime; % [µs] +0783 if out.nmrData{j}.time(1)== TE/1e3 +0784 % change [ms] to [s] +0785 out.nmrData{j}.time = out.nmrData{j}.time/1e3; +0786 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1e3; +0787 elseif out.nmrData{j}.time(1)== TE +0788 % change [µs] to [s] -> very unlikely +0789 out.nmrData{j}.time = out.nmrData{j}.time/1e6; +0790 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1e6; +0791 end +0792 data.import.NMR.data{c} = out.nmrData{j}; +0793 data.import.NMR.para{c} = out.parData; +0794 end +0795 +0796 % update the global data structure +0797 data.import.NMR.files = fnames; +0798 data.import.NMR.filesShort = shownames; +0799 +0800 end +0801 +0802 %% +0803 function [data,gui] = importDataLIAGproject(data,gui) +0804 +0805 % 1) show all folders and ask for sample +0806 subdirs = dir(data.import.path); +0807 % remove the dot-dirs +0808 subdirs = subdirs(~ismember({subdirs.name},{'.','..'})); +0809 +0810 fnames = {subdirs.name}; +0811 [indx,~] = listdlg('PromptString','Select Sample:',... +0812 'SelectionMode','single',... +0813 'ListString',fnames); +0814 +0815 if ~isempty(indx) +0816 % 2) check corresponding SampleParameter.par file for reference and +0817 % calibration sample and other parameters +0818 datapath = fullfile(data.import.path,fnames{indx}); +0819 % load SampleParameter file for sample +0820 [SampleParameter] = loadGUIParameters(datapath,'SampleParameters.par'); +0821 if isfield(SampleParameter,'sampleVolume') +0822 dataVol = SampleParameter.sampleVolume; +0823 else +0824 dataVol = 1; +0825 end +0826 +0827 % 2a) background file #1 +0828 backgroundFile1 = SampleParameter.backgroundFile; +0829 if isempty(backgroundFile1) +0830 bnames = {subdirs.name}; +0831 bnames(indx) = []; +0832 [indb,~] = listdlg('PromptString','Select Background File:',... +0833 'SelectionMode','single',... +0834 'ListString',bnames); +0835 if ~isempty(indb) +0836 backgroundFile1 = bnames{indb}; +0837 else +0838 backgroundFile1 = ''; +0839 end +0840 end +0841 if ~isempty(backgroundFile1) +0842 ind = strfind(backgroundFile1,filesep); +0843 if ~isempty(ind) +0844 backgroundFile1 = backgroundFile1(ind(end)+1:end); +0845 end +0846 fileInList = ismember(fnames,{backgroundFile1}); +0847 if any(fileInList) +0848 backgroundpath1 = fullfile(data.import.path,fnames{fileInList}); +0849 end +0850 else +0851 backgroundpath1 = ''; +0852 backgroundFile1 = ''; +0853 end +0854 backVol = 1; +0855 +0856 % 2b) calibration file +0857 c = 0; +0858 if isfield(SampleParameter,'calibrationFile0') +0859 c = c + 1; +0860 calibrationFiles{c} = SampleParameter.calibrationFile0; +0861 end +0862 if isfield(SampleParameter,'calibrationFile1') +0863 c = c + 1; +0864 calibrationFiles{c} = SampleParameter.calibrationFile1; +0865 end +0866 if isfield(SampleParameter,'calibrationFile2') +0867 c = c + 1; +0868 calibrationFiles{c} = SampleParameter.calibrationFile2; +0869 end +0870 if isfield(SampleParameter,'calibrationFile3') +0871 c = c + 1; +0872 calibrationFiles{c} = SampleParameter.calibrationFile3; +0873 end +0874 +0875 % find the non-empty one +0876 ind = ismember(calibrationFiles,{''}); +0877 % there are three possibilities: 0, 1 and more than 1 calib. files +0878 calibrationFiles(ind) = []; +0879 if isempty(calibrationFiles) +0880 cnames = {subdirs.name}; +0881 cnames(indx) = []; +0882 [indc,~] = listdlg('PromptString','Select Calibration File:',... +0883 'SelectionMode','single',... +0884 'ListString',cnames); +0885 if ~isempty(indc) +0886 calibrationFiles = cnames{indc}; +0887 else +0888 calibrationFiles = ''; +0889 end +0890 else +0891 % if there are more than one let the user select the correct one +0892 if numel(calibrationFiles) > 1 +0893 [ind,~] = listdlg('PromptString','Select Calibration File:',... +0894 'SelectionMode','single',... +0895 'ListString',calibrationFiles); +0896 calibrationFiles = calibrationFiles{ind}; +0897 else +0898 calibrationFiles = calibrationFiles{1}; +0899 end +0900 end +0901 if ~isempty(calibrationFiles) +0902 ind = strfind(calibrationFiles,filesep); +0903 if ~isempty(ind) +0904 calibrationFiles = calibrationFiles(ind(end)+1:end); +0905 end +0906 fileInList = ismember(fnames,{calibrationFiles}); +0907 if any(fileInList) +0908 calibrationpath = fullfile(data.import.path,fnames{fileInList}); +0909 end +0910 else +0911 calibrationpath = ''; +0912 calibrationFiles = ''; +0913 end +0914 +0915 if ~isempty(calibrationpath) +0916 [SampleParameterC] = loadGUIParameters(calibrationpath,'SampleParameters.par'); +0917 if isfield(SampleParameterC,'sampleVolume') +0918 calibVol = SampleParameterC.sampleVolume; +0919 else +0920 calibVol = 1; +0921 end +0922 +0923 % 2a) background file #2 +0924 backgroundFile2 = SampleParameterC.backgroundFile; +0925 if isempty(backgroundFile2) +0926 bnames = {subdirs.name}; +0927 bnames(indx) = []; +0928 [indb,~] = listdlg('PromptString','Select Background File for Calibration:',... +0929 'SelectionMode','single',... +0930 'ListString',bnames); +0931 if ~isempty(indb) +0932 backgroundFile2 = bnames{indb}; +0933 else +0934 backgroundFile2 = ''; +0935 end +0936 end +0937 if ~isempty(backgroundFile2) +0938 ind = strfind(backgroundFile2,filesep); +0939 if ~isempty(ind) +0940 backgroundFile2 = backgroundFile2(ind(end)+1:end); +0941 end +0942 fileInList = ismember(fnames,{backgroundFile2}); +0943 if any(fileInList) +0944 backgroundpath2 = fullfile(data.import.path,fnames{fileInList}); +0945 end +0946 else +0947 backgroundpath2 = ''; +0948 backgroundFile2 = ''; +0949 end +0950 else +0951 calibVol = 1; +0952 backgroundpath2 = ''; +0953 backgroundFile2 = ''; +0954 end +0955 +0956 % 3) now load the data +0957 workpaths = {datapath,calibrationpath,backgroundpath1,backgroundpath2}; +0958 workfiles = {fnames{indx},[calibrationFiles,' - calibration'],... +0959 [backgroundFile1,' - backgroundS'],[backgroundFile2,' - backgroundC']}; +0960 out = cell(size(workpaths)); +0961 count = 0; +0962 keep = false(size(workpaths)); +0963 for i = 1:numel(workpaths) +0964 if ~isempty(workpaths{i}) +0965 workdirs = dir(workpaths{i}); +0966 workdirs = workdirs(~ismember({workdirs.name},{'.','..'})); +0967 isT2 = ismember({workdirs.name},{'T2CPMG'}); +0968 if any(isT2) +0969 keep(i) = true; +0970 count = count + 1; +0971 T2path = fullfile(workdirs(isT2).folder,workdirs(isT2).name); +0972 in.path = T2path; +0973 in.fileformat = data.import.fileformat; +0974 out{i} = LoadNMRData_driver(in); +0975 end +0976 end +0977 end +0978 +0979 if isempty(backgroundpath1) +0980 ref1 = struct; +0981 else +0982 background1 = out{3}; +0983 % get the background data 1 +0984 ref1.t = background1.nmrData{1}.time; +0985 ref1.s = background1.nmrData{1}.signal; +0986 [ref1.s,~] = rotateT2phase(ref1.s); +0987 end +0988 +0989 if isempty(backgroundpath2) +0990 ref2 = struct; +0991 else +0992 background2 = out{4}; +0993 % get the background data 2 +0994 ref2.t = background2.nmrData{1}.time; +0995 ref2.s = background2.nmrData{1}.signal; +0996 [ref2.s,~] = rotateT2phase(ref2.s); +0997 end +0998 +0999 workpaths = workpaths(keep); +1000 workfiles = workfiles(keep); +1001 out = out(keep); +1002 +1003 ffnames = struct; +1004 % shownames is just a dummy to hold all data file names that +1005 % will be shown in the listbox +1006 shownames = cell(1,1); +1007 +1008 for i = 1:count +1009 ffnames(i).parfile = 'acqu.par'; +1010 ffnames(i).datafile = workfiles{i}; +1011 ffnames(i).T2specfile = ''; +1012 +1013 shownames{i} = ffnames(i).datafile; +1014 +1015 % the NMR data +1016 % here we fix the time scale to [s] if neccessary +1017 TE = out{i}.parData.echoTime; % [µs] +1018 if out{i}.nmrData{1}.time(1)== TE/1e3 +1019 % change [ms] to [s] +1020 out{i}.nmrData{1}.time = out{i}.nmrData{1}.time/1e3; +1021 out{i}.nmrData{1}.raw.time = out{i}.nmrData{1}.raw.time/1e3; +1022 elseif out{i}.nmrData{1}.time(1)== TE +1023 % change [µs] to [s] -> very unlikely +1024 out{i}.nmrData{1}.time = out{i}.nmrData{1}.time/1e6; +1025 out{i}.nmrData{1}.raw.time = out{i}.nmrData{1}.raw.time/1e6; +1026 end +1027 +1028 data.import.NMR.data{i} = out{i}.nmrData{1}; +1029 data.import.NMR.para{i} = out{i}.parData; +1030 data.import.NMR.para{i}.SampleParameter = SampleParameter; +1031 +1032 % subtract the background signal +1033 s = data.import.NMR.data{i}.signal; +1034 if i==1 && isfield(ref1,'s') +1035 % if the background signal is longer than the signal cut it, if +1036 % not extend it with zeros +1037 if numel(ref1.s) > numel(s) +1038 tmp_r = ref1.s(1:numel(s)); +1039 else +1040 tmp_r = zeros(size(s)); +1041 tmp_r(1:numel(ref1.s)) = ref1.s; +1042 end +1043 s = complex(real(s)-real(tmp_r),imag(s)-imag(tmp_r)); +1044 elseif i==2 && isfield(ref2,'s') +1045 % if the background signal is longer than the signal cut it, if +1046 % not extend it with zeros +1047 if numel(ref2.s) > numel(s) +1048 tmp_r = ref2.s(1:numel(s)); +1049 else +1050 tmp_r = zeros(size(s)); +1051 tmp_r(1:numel(ref2.s)) = ref2.s; +1052 end +1053 s = complex(real(s)-real(tmp_r),imag(s)-imag(tmp_r)); +1054 end +1055 data.import.NMR.data{i}.signal = s; +1056 data.import.NMR.data{i}.raw.signal = s; +1057 +1058 if ~isempty(strfind(workfiles{i},' - background')) +1059 data.import.LIAG.sampleVol(i) = backVol; +1060 elseif ~isempty(strfind(workfiles{i},' - calibration')) +1061 data.import.LIAG.sampleVol(i) = calibVol; +1062 elseif isempty(strfind(workfiles{i},' - background')) &&... +1063 isempty(strfind(workfiles{i},' - calibration')) +1064 data.import.LIAG.sampleVol(i) = dataVol; +1065 end +1066 end +1067 data.import.LIAG.Tbulk = 1e6; +1068 data.import.LIAG.workpaths = workpaths; +1069 data.import.LIAG.datapath = datapath; +1070 data.import.LIAG.calibrationpath = calibrationpath; +1071 data.import.LIAG.backgroundpath1 = backgroundpath1; +1072 data.import.LIAG.backgroundpath2 = backgroundpath2; +1073 +1074 % update the global data structure +1075 data.import.NMR.files = ffnames; +1076 data.import.NMR.filesShort = shownames; +1077 +1078 end +1079 +1080 end +1081 +1082 %% +1083 function [data,gui] = importDataMouse(data,gui) +1084 +1085 in.path = fullfile(data.import.path); +1086 in.fileformat = data.import.fileformat; +1087 out = LoadNMRData_driver(in); +1088 +1089 fnames = struct; +1090 % shownames is just a dummy to hold all data file names that +1091 % will be shown in the listbox +1092 shownames = cell(1,1); +1093 +1094 c = 0; +1095 for j = 1:size(out.nmrData,2) +1096 % the individual file names +1097 c = c + 1; +1098 fnames(c).parfile = 'acq.par'; +1099 fnames(c).datafile = out.nmrData{j}.datfile; +1100 fnames(c).T2specfile = ''; +1101 +1102 shownames{c} = ['T2_',fnames(c).datafile]; +1103 +1104 % the NMR data +1105 % here we fix the time scale from [ms] to [s] +1106 if max(out.nmrData{j}.time) > 100 +1107 out.nmrData{j}.time = out.nmrData{j}.time/1000; +1108 out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; +1109 end +1110 data.import.NMR.data{c} = out.nmrData{j}; +1111 data.import.NMR.para{c} = out.parData; +1112 end +1113 +1114 % update the global data structure +1115 data.import.NMR.files = fnames; +1116 data.import.NMR.filesShort = shownames; +1117 +1118 end +1119 +1120 %% +1121 function [data,gui] = importDataIBAC(data,gui) +1122 +1123 in.path = fullfile(data.import.path); +1124 in.name = data.import.file; +1125 in.fileformat = data.import.fileformat; +1126 out = LoadNMRData_driver(in); +1127 +1128 nslices = out.parData.depths; +1129 nfiles = size(out.nmrData,2); +1130 +1131 fnames = struct; +1132 % shownames is just a dummy to hold all data file names that +1133 % will be shown in the listbox +1134 shownames = cell(1,1); +1135 +1136 c = 0; +1137 for j = 1:size(out.nmrData,2) +1138 % the individual file names +1139 c = c + 1; +1140 fnames(c).parfile = out.parData.parfile; +1141 fnames(c).datafile = out.nmrData{j}.datfile; +1142 fnames(c).T2specfile = ''; +1143 +1144 shownames{c} = [fnames(c).datafile]; +1145 +1146 data.import.NMR.data{c} = out.nmrData{j}; +1147 data.import.NMR.para{c} = out.parData; +1148 end +1149 +1150 % check if the number of depth levels is equal to the number of +1151 % measurements +1152 if nslices == nfiles +1153 % create z-vector +1154 p = out.parData; +1155 zslice = linspace(p.initialdepth,p.finaldepth,p.depths)'; +1156 data.import.IBAC.use_z = true; +1157 data.import.IBAC.zslice = zslice; +1158 if numel(zslice) > 1 +1159 c = 0; +1160 for i = 1:nfiles +1161 c = c + 1; +1162 tmp = shownames{i}; +1163 shownames{i} = [tmp,' z:',sprintf('%05d',zslice(c))]; +1164 end +1165 end +1166 else +1167 data.import.IBAC.use_z = false; +1168 data.import.IBAC.zslice = 1:1:max([nfiles 1]); +1169 end +1170 +1171 % update the global data structure +1172 data.import.NMR.files = fnames; +1173 data.import.NMR.filesShort = shownames; +1174 +1175 end +1176 +1177 %% +1178 function data = loadGUIParameters(datapath,fname) +1179 fid = fopen(fullfile(datapath,fname)); +1180 d = textscan(fid,'%s','Delimiter','\n'); +1181 fclose(fid); +1182 data = struct; +1183 for i = 1:size(d{1},1) +1184 str = char(d{1}(i)); +1185 str = fixParameterString(str); +1186 eval(['data.',str,';']); +1187 end +1188 +1189 end +1190 +1191 %% +1192 function data = loadGUIrawdata(data,NMRpath,NMRfile) +1193 +1194 load(fullfile(NMRpath,'NUCLEUSinv_raw.mat'),'savedata'); +1195 +1196 data.import.file = NMRfile; +1197 data.import.path = NMRpath; +1198 data.import.NMR = savedata; +1199 +1200 end +1201 +1202 %------------- END OF CODE -------------- +1203 +1204 %% License: +1205 % MIT License +1206 % +1207 % Copyright (c) 2018 Thomas Hiller +1208 % +1209 % Permission is hereby granted, free of charge, to any person obtaining a copy +1210 % of this software and associated documentation files (the "Software"), to deal +1211 % in the Software without restriction, including without limitation the rights +1212 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +1213 % copies of the Software, and to permit persons to whom the Software is +1214 % furnished to do so, subject to the following conditions: +1215 % +1216 % The above copyright notice and this permission notice shall be included in all +1217 % copies or substantial portions of the Software. +1218 % +1219 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +1220 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +1221 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +1222 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +1223 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +1224 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +1225 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/makeINIfile.html b/doc/nucleus/functions/interface/makeINIfile.html index 2870772..b7de085 100644 --- a/doc/nucleus/functions/interface/makeINIfile.html +++ b/doc/nucleus/functions/interface/makeINIfile.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/menu.html b/doc/nucleus/functions/interface/menu.html index a30ed3d..dd24a64 100644 --- a/doc/nucleus/functions/interface/menu.html +++ b/doc/nucleus/functions/interface/menu.html @@ -18,7 +18,7 @@

    Index for nucleus\functions\interface

    Matlab files in this directory:

    +
  • ConductView
  • PhaseView
  • beautifyAxes
  • calculateGeometry
  • calculateGuiOnMonitorPosition
  • calculateNMR
  • calibratePorosity
  • caluclatePressureSaturation
  • changeColorTheme
  • checkIfInversionExists
  • cleanupGUIData
  • clearAllAxes
  • clearInversion
  • clearSingleAxis
  • displayStatusText
  • enableGUIelements
  • exportData
  • exportGraphics
  • exportINV
  • findParentOfType
  • fixAxes
  • getColorIndex
  • getColorTheme
  • getVersionNoFromString
  • importASCIIdata
  • importCPSdata
  • importCalibrationData
  • importEXCELdata
  • importINV2INV
  • importMOD2INV
  • importMOD2MOD
  • importNMRdata
  • makeINIfile
  • minimizePanel
  • moveEntryInList
  • onFigureSizeChange
  • processNMRData
  • processNMRDataControl
  • readINIfile
  • removeCalculationFields
  • removeInversionFields
  • removeSignalFromList
  • resortDataList
  • runInversionBatch
  • runInversionJoint
  • runInversionStd
  • showExtraGraphics
  • showFitStatistics
  • showParameterInfo
  • switchToolTips
  • uncheckImportMenus
  • updateCPSTable
  • updateCPSTableSize
  • updateInfo
  • updateNMRsignals
  • updatePlotsCPS
  • updatePlotsDistribution
  • updatePlotsDistributionInfo
  • updatePlotsGeometryType
  • updatePlotsJointInversion
  • updatePlotsLcurve
  • updatePlotsNMR
  • updatePlotsPSD
  • updatePlotsSignal
  • updateStatusInformation
  • updateToolTips
  • useSignalAsCalibration
  • Other Matlab-specific files in this directory:

    This function is called by: @@ -110,8 +110,8 @@

    SOURCE CODE ^% none 0033 % 0034 % See also: NUCLEUSinv -0035 % Author: Thomas Hiller -0036 % email: thomas.hiller[at]leibniz-liag.de +0035 % Author: see AUTHORS.md +0036 % email: see AUTHORS.md 0037 % License: MIT License (at end) 0038 0039 %------------- BEGIN CODE -------------- @@ -205,146 +205,188 @@

    SOURCE CODE ^fitDataFree(data.results.nmrproc.t,... 0128 data.results.nmrproc.s,flag,param,data.invstd.freeDT); 0129 -0130 case 'NNLS' +0130 case 'LU' 0131 param.T1T2 = data.results.nmrproc.T1T2; 0132 param.T1IRfac = data.results.nmrproc.T1IRfac; 0133 param.Tb = data.invstd.Tbulk; -0134 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; -0135 param.regMethod = data.invstd.regtype; +0134 param.Td = data.invstd.Tdiff; +0135 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; 0136 param.Lorder = data.invstd.Lorder; 0137 param.lambda = data.invstd.lambda; 0138 param.noise = data.results.nmrproc.noise; -0139 param.solver = data.info.solver; -0140 if isfield(data.results.nmrproc,'W') -0141 param.W = data.results.nmrproc.W; -0142 end -0143 -0144 invstd = fitDataLSQ(data.results.nmrproc.t,... -0145 data.results.nmrproc.s,param); -0146 -0147 case 'LU' -0148 param.T1T2 = data.results.nmrproc.T1T2; -0149 param.T1IRfac = data.results.nmrproc.T1IRfac; -0150 param.Tb = data.invstd.Tbulk; -0151 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; -0152 param.Lorder = data.invstd.Lorder; -0153 param.lambda = data.invstd.lambda; -0154 param.noise = data.results.nmrproc.noise; -0155 -0156 invstd = fitDataLUdecomp(data.results.nmrproc.t,... -0157 data.results.nmrproc.s,param); -0158 end -0159 -0160 % save inversion results -0161 data.results.invstd = invstd; -0162 if id == 1 -0163 % get possible parameter file information -0164 if isfield(data.import.NMR,'para') -0165 data.info.parameter = data.import.NMR.para{id}; -0166 else -0167 data.info.parameter = 'No parameter data available.'; -0168 end -0169 INVdata{id} = []; -0170 INVdata{id} = data; -0171 INVdata{id} = rmfield(INVdata{id},'import'); -0172 INVdata{id} = rmfield(INVdata{id},'info'); -0173 INVdata{id} = rmfield(INVdata{id},'calib'); -0174 INVdata{id} = rmfield(INVdata{id},'pressure'); -0175 % copy data to all INVdata fields to allocate memory -0176 % this speeds up the overall runtime -0177 INVdata = repmat(INVdata(id),[length(data.import.NMR.filesShort),1]); -0178 else -0179 % save individual results -0180 INVdata{id}.process = data.process; -0181 INVdata{id}.results = data.results; -0182 if isfield(data.import.NMR,'para') -0183 INVdata{id}.info.parameter = data.import.NMR.para{id}; -0184 else -0185 INVdata{id}.info.parameter = 'No parameter data available.'; -0186 end -0187 end -0188 -0189 % color the list entries that already have an inversion result -0190 strL = get(gui.listbox_handles.signal,'String'); -0191 str1 = strL{id}; -0192 str2 = ['<HTML><BODY bgcolor="rgb(',... -0193 sprintf('%d,%d,%d',gui.myui.colors.listINV.*255),')">',str1,'</BODY></HTML>']; -0194 strL{id} = str2; -0195 set(gui.listbox_handles.signal,'String',strL); -0196 -0197 % update wait-bar -0198 if wbopts.show -0199 % for a small number of signals always update the wait-bar -0200 if size(INVdata,1) <= 50 -0201 waitbar(id / steps,hwb,['processing ...',num2str(id),... -0202 ' / ',num2str(steps),' NMR signals']); -0203 else -0204 % otherwise only update every 25 signals -0205 % NOTE: Matlab's wait-bar SLOWS DOWN the calculation -0206 % MASSIVELY -0207 if id == 1 || mod(id,25) == 0 -0208 waitbar(id / steps,hwb,['processing ...',num2str(id),... -0209 ' / ',num2str(steps),' NMR signals']); -0210 end -0211 end -0212 end -0213 else -0214 displayStatusText(gui,[infostring,' was canceled']); -0215 % remove temporary data fields -0216 data = removeInversionFields(data); -0217 % remove data from fields not processed -0218 INVdata{id} = []; -0219 end -0220 end -0221 % delete wait-bar -0222 if wbopts.show -0223 delete(hwb); -0224 end -0225 if get(gui.push_handles.invstd_run,'UserData') == 1 % STOP was not pressed -0226 displayStatusText(gui,[infostring,'done']); -0227 end -0228 -0229 % update INVdata to GUI -0230 setappdata(fig,'INVdata',INVdata); -0231 % make the STOP button a RUN again -0232 set(gui.push_handles.invstd_run,'String','<HTML><u>R</u>UN',... -0233 'BackgroundColor','g','Callback',@onPushRun); -0234 % update GUI data -0235 setappdata(fig,'gui',gui); -0236 % set focus on the first entry in the list -0237 set(gui.listbox_handles.signal,'Value',1); -0238 onListboxData(gui.listbox_handles.signal); -0239 else -0240 helpdlg('Nothing to do because there is no data loaded!',... -0241 'runInversioBatch: Load NMR data first.'); -0242 end -0243 -0244 end -0245 -0246 %------------- END OF CODE -------------- -0247 -0248 %% License: -0249 % MIT License -0250 % -0251 % Copyright (c) 2018 Thomas Hiller -0252 % -0253 % Permission is hereby granted, free of charge, to any person obtaining a copy -0254 % of this software and associated documentation files (the "Software"), to deal -0255 % in the Software without restriction, including without limitation the rights -0256 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0257 % copies of the Software, and to permit persons to whom the Software is -0258 % furnished to do so, subject to the following conditions: -0259 % -0260 % The above copyright notice and this permission notice shall be included in all -0261 % copies or substantial portions of the Software. -0262 % -0263 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0264 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0265 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0266 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0267 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0268 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0269 % SOFTWARE. +0139 +0140 invstd = fitDataLUdecomp(data.results.nmrproc.t,... +0141 data.results.nmrproc.s,param); +0142 +0143 case 'NNLS' +0144 param.T1T2 = data.results.nmrproc.T1T2; +0145 param.T1IRfac = data.results.nmrproc.T1IRfac; +0146 param.Tb = data.invstd.Tbulk; +0147 param.Td = data.invstd.Tdiff; +0148 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; +0149 param.regMethod = data.invstd.regtype; +0150 param.Lorder = data.invstd.Lorder; +0151 param.lambda = data.invstd.lambda; +0152 param.noise = data.results.nmrproc.noise; +0153 param.solver = data.info.solver; +0154 if isfield(data.results.nmrproc,'W') +0155 param.W = data.results.nmrproc.W; +0156 end +0157 +0158 invstd = fitDataLSQ(data.results.nmrproc.t,... +0159 data.results.nmrproc.s,param); +0160 +0161 case 'MUMO' % N free distribution inversion +0162 param.T1T2 = data.results.nmrproc.T1T2; +0163 param.T1IRfac = data.results.nmrproc.T1IRfac; +0164 param.Tb = data.invstd.Tbulk; +0165 param.Td = data.invstd.Tdiff; +0166 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; +0167 param.regMethod = data.invstd.regtype; +0168 param.noise = data.results.nmrproc.noise; +0169 param.solver = data.info.solver; +0170 param.optim = data.info.has_optim; +0171 if isfield(data.results.nmrproc,'W') +0172 param.W = data.results.nmrproc.W; +0173 end +0174 +0175 % status bar information +0176 switch data.info.solver +0177 case 'lsqlin' +0178 infostring = 'Inversion using ''Optimization Toolbox'' ... '; +0179 case 'lsqnonneg' +0180 infostring = 'Inversion using ''fminsearchbnd'' ... '; +0181 end +0182 displayStatusText(gui,infostring); +0183 invstd = fitDataMultiModal(data.results.nmrproc.t,... +0184 data.results.nmrproc.s,param,data.invstd.freeDT); +0185 +0186 % estimate uncertainty +0187 if data.invstd.useUncert +0188 % original fit parameter +0189 iparam = param; +0190 % uncertainty parameter +0191 uparam.time = data.results.nmrproc.t; +0192 uparam.signal = data.results.nmrproc.s; +0193 uparam.uncertMethod = data.invstd.uncertMethod; +0194 uparam.uncertThresh = data.invstd.uncertThresh; +0195 uparam.uncertChi2 = data.invstd.uncertChi2; +0196 uparam.uncertN = data.invstd.uncertN; +0197 uparam.uncertMax = data.invstd.uncertMax; +0198 invstd = estimateUncertainty(data.invstd.invtype,invstd,iparam,uparam); +0199 end +0200 end +0201 +0202 % save inversion results +0203 data.results.invstd = invstd; +0204 if id == 1 +0205 % get possible parameter file information +0206 if isfield(data.import.NMR,'para') +0207 data.info.parameter = data.import.NMR.para{id}; +0208 else +0209 data.info.parameter = 'No parameter data available.'; +0210 end +0211 INVdata{id} = []; +0212 INVdata{id} = data; +0213 INVdata{id} = rmfield(INVdata{id},'import'); +0214 INVdata{id} = rmfield(INVdata{id},'info'); +0215 INVdata{id} = rmfield(INVdata{id},'calib'); +0216 INVdata{id} = rmfield(INVdata{id},'pressure'); +0217 % copy data to all INVdata fields to allocate memory +0218 % this speeds up the overall runtime +0219 INVdata = repmat(INVdata(id),[length(data.import.NMR.filesShort),1]); +0220 else +0221 % save individual results +0222 INVdata{id}.process = data.process; +0223 INVdata{id}.results = data.results; +0224 if isfield(data.import.NMR,'para') +0225 INVdata{id}.info.parameter = data.import.NMR.para{id}; +0226 else +0227 INVdata{id}.info.parameter = 'No parameter data available.'; +0228 end +0229 end +0230 +0231 % color the list entries that already have an inversion result +0232 strL = get(gui.listbox_handles.signal,'String'); +0233 str1 = strL{id}; +0234 str2 = ['<HTML><BODY bgcolor="rgb(',... +0235 sprintf('%d,%d,%d',gui.myui.colors.listINV.*255),')">',str1,'</BODY></HTML>']; +0236 strL{id} = str2; +0237 set(gui.listbox_handles.signal,'String',strL); +0238 +0239 % update wait-bar +0240 if wbopts.show +0241 % for a small number of signals always update the wait-bar +0242 if size(INVdata,1) <= 50 +0243 waitbar(id / steps,hwb,['processing ...',num2str(id),... +0244 ' / ',num2str(steps),' NMR signals']); +0245 else +0246 % otherwise only update every 25 signals +0247 % NOTE: Matlab's wait-bar SLOWS DOWN the calculation +0248 % MASSIVELY +0249 if id == 1 || mod(id,25) == 0 +0250 waitbar(id / steps,hwb,['processing ...',num2str(id),... +0251 ' / ',num2str(steps),' NMR signals']); +0252 end +0253 end +0254 end +0255 else +0256 displayStatusText(gui,[infostring,' was canceled']); +0257 % remove temporary data fields +0258 data = removeInversionFields(data); +0259 % remove data from fields not processed +0260 INVdata{id} = []; +0261 end +0262 end +0263 % delete wait-bar +0264 if wbopts.show +0265 delete(hwb); +0266 end +0267 if get(gui.push_handles.invstd_run,'UserData') == 1 % STOP was not pressed +0268 displayStatusText(gui,[infostring,'done']); +0269 end +0270 +0271 % update INVdata to GUI +0272 setappdata(fig,'INVdata',INVdata); +0273 % make the STOP button a RUN again +0274 set(gui.push_handles.invstd_run,'String','<HTML><u>R</u>UN',... +0275 'BackgroundColor','g','Callback',@onPushRun); +0276 % update GUI data +0277 setappdata(fig,'gui',gui); +0278 % set focus on the first entry in the list +0279 set(gui.listbox_handles.signal,'Value',1); +0280 onListboxData(gui.listbox_handles.signal); +0281 else +0282 helpdlg('Nothing to do because there is no data loaded!',... +0283 'runInversioBatch: Load NMR data first.'); +0284 end +0285 +0286 end +0287 +0288 %------------- END OF CODE -------------- +0289 +0290 %% License: +0291 % MIT License +0292 % +0293 % Copyright (c) 2018 Thomas Hiller +0294 % +0295 % Permission is hereby granted, free of charge, to any person obtaining a copy +0296 % of this software and associated documentation files (the "Software"), to deal +0297 % in the Software without restriction, including without limitation the rights +0298 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0299 % copies of the Software, and to permit persons to whom the Software is +0300 % furnished to do so, subject to the following conditions: +0301 % +0302 % The above copyright notice and this permission notice shall be included in all +0303 % copies or substantial portions of the Software. +0304 % +0305 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0306 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0307 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0308 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0309 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0310 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0311 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/runInversionJoint.html b/doc/nucleus/functions/interface/runInversionJoint.html index ba72430..51cfd2f 100644 --- a/doc/nucleus/functions/interface/runInversionJoint.html +++ b/doc/nucleus/functions/interface/runInversionJoint.html @@ -67,7 +67,7 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
  • onPushShowHide shows/hides the INFO column on the right side of NUCLEUSinv
  • onPushStop recognizes that a STOP push button was pressed and resets the
  • checkIfInversionExists checks if any inversion result is stored inside
  • clearSingleAxis clears an individual axis
  • displayStatusText shows status information either in the GUI or on the
  • removeInversionFields deletes all inversion result fields from NUCLEUSinv
  • updateInfo updates the information shown in all information list boxes
  • updatePlotsJointInversion plots the joint-inversion results in NUCLEUSinv
  • updatePlotsLcurve plots the results of the L-curve calculation
  • fcn_JointInvfixed performs the "fixed" joint inversion using the RTD of
  • fcn_JointInvfree jointly estimates the pore size distribution and surface
  • fcn_JointInvshape performs the "shape" joint inversion using the RTD of
  • getChi2 the chi2 of a NMR fit (noise weighted error quality)
  • getLambdaFromLCurve estimates the regularization parameter lambda according
  • getConstants provides some physical constants to the forward calculation
  • getCornerNMRparameter calculates corner parameters (amplitude surface to
  • getGeometryParameter calculates geometric parameters for the three possible
  • getPartialSaturationMatrix calculates the partial saturation matrix to be
  • getSaturationFromPressureBatch
  • This function is called by:
    • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
    @@ -122,8 +122,8 @@

    SOURCE CODE ^% none 0045 % 0046 % See also: NUCLEUSinv -0047 % Author: Thomas Hiller -0048 % email: thomas.hiller[at]leibniz-liag.de +0047 % Author: see AUTHORS.md +0048 % email: see AUTHORS.md 0049 % License: MIT License (at end) 0050 0051 %------------- BEGIN CODE -------------- @@ -354,540 +354,545 @@

    SOURCE CODE ^end 0278 iparam.Tb = data.invstd.Tbulk; -0279 iparam.T1T2 = T1T2flag; -0280 iparam.T1IRfac = T1IRfac; -0281 iparam.L = L; -0282 iparam.lambda = lambda_range(i); -0283 iparam.igeom = igeom; -0284 iparam.IPS = IPS; -0285 iparam.SVdata = SVdata; -0286 iparam.SatImbDrain = SatImbDrain; -0287 -0288 % start values and bounds -0289 rhostart = log10(data.invjoint.rhostart/1e6); -0290 rhobounds = log10(data.invjoint.rhobounds/1e6); -0291 x0 = [zeros(size(igeom.radius))' rhostart]; -0292 lb = [zeros(size(igeom.radius))' rhobounds(1)]; -0293 ub = [ones(size(igeom.radius))' rhobounds(2)]; -0294 -0295 options = optimset('Display',info,'TolFun',1e-12,'TolX',1e-12,... -0296 'Jacobian','on','DerivativeCheck','off','FinDiffType','central',... -0297 'Algorithm','levenberg-marquardt',... -0298 'MaxIter',1000); -0299 -0300 [X,~,~,~] = lsqnonlin(@(X)fcn_JointInvfree(X,iparam),x0,lb,ub,options); -0301 [~,~,ig,~] = fcn_JointInvfree(X,iparam); -0302 -0303 if useW -0304 % normalize the fit because the signal was error -0305 % weighted for the inversion -0306 e = diag(iparam.W); -0307 einv = 1./e; -0308 Winv = diag(einv); -0309 ig = Winv * ig; -0310 end -0311 -0312 residual = ig - g'; -0313 iF = X(1:length(X)-1); -0314 -0315 % output data -0316 % get RMS and X^2 -0317 if useW -0318 % weighted RMS error -0319 % residual is weighted with the amount of echoes N per time gate -0320 % NOTE: if "N per gate" is too large, the RMS estimation breaks down -0321 RMS(i) = sqrt (sum(N'.*(residual).^2) / length(residual)); -0322 % X2 estimate -0323 CHI2(i) = getChi2(g',ig,e); -0324 else -0325 % RMS error -0326 RMS(i) = sqrt( sum(residual.^2) / length(residual) ); -0327 % X2 estimate -0328 CHI2(i) = getChi2(g',ig,idata.nmr{levels(1)}.noise); -0329 end -0330 % error norm and model norm -0331 RN(i) = norm(residual,2); -0332 XN(i) = norm(L*iF',2); -0333 % wait-bar update -0334 if wbopts.show -0335 waitbar(i / steps,hwb,['processing ...',num2str(i),' / ',num2str(steps),' lambda steps']); -0336 end -0337 end -0338 end -0339 % delete the wait-bar -0340 if wbopts.show -0341 delete(hwb); -0342 end -0343 -0344 % check if the STOP button was pressed -0345 % if "UserData" is 1 STOP was not pressed -> save data -0346 if get(gui.push_handles.invjoint_run,'UserData') == 1 -0347 lc.lambda = lambda_range; -0348 lc.RMS = RMS; -0349 lc.RN = RN; -0350 lc.XN = XN; -0351 % get optimal lambda -0352 % lc.index = getLambdaFromRMS(lc.lambda,lc.RMS,0); -0353 lc.index = getLambdaFromLCurve(RN,XN,0); -0354 data.results.lcurve = lc; -0355 % update GUI data -0356 setappdata(fig,'data',data); -0357 % update L-curve plots -0358 updatePlotsLcurve; -0359 % status bar information -0360 displayStatusText(gui,[infostring,' done']); -0361 % set focus on results -0362 set(gui.plots.DistPanel,'Selection',1); -0363 else -0364 % status bar information -0365 displayStatusText(gui,[infostring,' was canceled']); -0366 % remove temporary data fields -0367 data = removeInversionFields(data); -0368 end -0369 -0370 case 'manual' -0371 % disable the RUN button to indicate a running inversion -0372 set(gui.push_handles.invjoint_run,'String','RUNNING ...',... -0373 'Enable','inactive'); -0374 -0375 % inversion parameter -0376 iparam.t = t; -0377 iparam.g = g; -0378 if useW -0379 iparam.W = W; -0380 end -0381 iparam.Tb = data.invstd.Tbulk; -0382 iparam.T1T2 = T1T2flag; -0383 iparam.T1IRfac = T1IRfac; -0384 iparam.L = L; -0385 iparam.lambda = data.invjoint.lambda; -0386 iparam.igeom = igeom; -0387 iparam.IPS = IPS; -0388 iparam.SVdata = SVdata; -0389 iparam.SatImbDrain = SatImbDrain; -0390 -0391 % start values and bounds -0392 rhostart = log10(data.invjoint.rhostart/1e6); -0393 rhobounds = log10(data.invjoint.rhobounds/1e6); -0394 x0 = [zeros(size(igeom.radius))' rhostart]; -0395 lb = [zeros(size(igeom.radius))' rhobounds(1)]; -0396 ub = [ones(size(igeom.radius))' rhobounds(2)]; -0397 -0398 % status bar information -0399 infostring = 'Joint Inversion (free) using ''lsqnonlin'' ... '; -0400 displayStatusText(gui,infostring); -0401 -0402 % optimization settings -0403 options = optimset('Display',info,'TolFun',1e-12,'TolX',1e-12,... -0404 'Jacobian','on','DerivativeCheck','off','FinDiffType','central',... -0405 'Algorithm','levenberg-marquardt',... -0406 'MaxIter',1000); -0407 [X,~,~,exitflag] = lsqnonlin(@(X)fcn_JointInvfree(X,iparam),x0,lb,ub,options); -0408 % status bar information -0409 displayStatusText(gui,[infostring,'done']); -0410 % get the final fit -0411 [~,~,ig,KK] = fcn_JointInvfree(X,iparam); -0412 -0413 if useW -0414 % normalize the fit because the signal was error -0415 % weighted for the inversion -0416 e = diag(iparam.W); -0417 einv = 1./e; -0418 Winv = diag(einv); -0419 ig = Winv * ig; -0420 end -0421 -0422 % the inverted surface relaxivity and PSD -0423 iF = X(1:length(X)-1); -0424 irho = 10^X(length(X)); -0425 % inversion output -0426 data.results.invjoint.p0 = p0; -0427 data.results.invjoint.S0 = S0; -0428 data.results.invjoint.levels = levels; -0429 data.results.invjoint.T1T2 = T1T2flag; -0430 data.results.invjoint.T1IRfac = T1IRfac; -0431 data.results.invjoint.x0 = x0; -0432 data.results.invjoint.lb = lb; -0433 data.results.invjoint.ub = ub; -0434 data.results.invjoint.iparam = iparam; -0435 data.results.invjoint.iGEOM = igeom; -0436 data.results.invjoint.iSAT = iSAT; -0437 data.results.invjoint.iF = iF'; -0438 data.results.invjoint.irho = irho; -0439 data.results.invjoint.ig = ig; -0440 data.results.invjoint.XX = KK; -0441 data.results.invjoint.errnorm = norm((ig - g')).^2; -0442 data.results.invjoint.residual = ig - g'; -0443 data.results.invjoint.exitflag = exitflag; -0444 -0445 % get RMS and X^2 -0446 residual = data.results.invjoint.residual; -0447 if useW -0448 % weighted RMS error -0449 % residual is weighted with the amount of echoes N per time gate -0450 % NOTE: if "N per gate" is too large, the RMS estimation breaks down -0451 data.results.invjoint.rms = sqrt (sum(N'.*(residual).^2) / length(residual)); -0452 % X2 estimate -0453 data.results.invjoint.chi2 = getChi2(g',ig,e); -0454 else -0455 % RMS error -0456 data.results.invjoint.rms = sqrt( sum(residual.^2) / length(residual) ); -0457 % X2 estimate -0458 data.results.invjoint.chi2 = getChi2(g',ig,idata.nmr{levels(1)}.noise); -0459 end -0460 -0461 % predict CPS curves for the final model -0462 infostring = 'calculate CPS curve ... '; -0463 displayStatusText(gui,infostring); -0464 ppsddata.r = igeom.radius'; -0465 ppsddata.psd = data.results.invjoint.iF'./sum(data.results.invjoint.iF); -0466 if min(p) == 0 -0467 p_tmp = logspace(floor(log10(min(p(p>0)))-2),ceil(log10(max(p)))+2,150); -0468 else -0469 p_tmp = logspace(floor(log10(min(p)/2)),ceil(log10(max(p)))+2,150); -0470 end -0471 % waitbar option -0472 wbopts.show = true; -0473 wbopts.tag = 'INV'; -0474 pSAT = getSaturationFromPressureBatch(igeom,p_tmp,ppsddata,getConstants,wbopts); -0475 % save -0476 data.results.invjoint.pSAT = pSAT; -0477 displayStatusText(gui,[infostring,'done']); -0478 end -0479 -0480 case 'fixed' % only invert for rho -0481 % disable the RUN button to indicate a running inversion -0482 set(gui.push_handles.invjoint_run,'String','RUNNING ...',... -0483 'Enable','inactive'); -0484 -0485 % inversion geometry -0486 igeom.type = data.invjoint.geometry_type; -0487 igeom.angles = [data.invjoint.alpha data.invjoint.beta data.invjoint.gamma]; -0488 igeom.polyN = data.invjoint.polyN; -0489 igeom.radius = data.param.rho.*data.param.a.*fullsat.T; % first guess -0490 igeom = getGeometryParameter(igeom); -0491 -0492 iparam.t = t; -0493 iparam.g = g; -0494 if useW -0495 iparam.W = W; -0496 end -0497 iparam.indt = indt; -0498 iparam.Tb = data.invstd.Tbulk; -0499 iparam.T1T2 = T1T2flag; -0500 iparam.T1IRfac = T1IRfac; -0501 iparam.SatImbDrain = SatImbDrain; -0502 iparam.p = p; -0503 iparam.igeom = igeom; -0504 iparam.x = fullsat.T'; -0505 iparam.f = fullsat.F'; -0506 -0507 % start values and bounds -0508 x0 = log10(data.invjoint.rhostart/1e6); -0509 rhobounds = log10(data.invjoint.rhobounds/1e6); -0510 lb = rhobounds(1); -0511 ub = rhobounds(2); -0512 -0513 infostring = 'Joint Inversion (fixed) using ''fminsearchbnd'' ... '; -0514 displayStatusText(gui,infostring); -0515 -0516 options = optimset('Display',info,'TolFun',1e-12,'TolX',1e-12,... -0517 'MaxFunEvals',300,'MaxIter',300); -0518 X = fminsearchbnd(@(X) fcn_JointInvfixed(X,iparam),x0,lb,ub,options); +0279 iparam.Td = data.invstd.Tdiff; +0280 iparam.T1T2 = T1T2flag; +0281 iparam.T1IRfac = T1IRfac; +0282 iparam.L = L; +0283 iparam.lambda = lambda_range(i); +0284 iparam.igeom = igeom; +0285 iparam.IPS = IPS; +0286 iparam.SVdata = SVdata; +0287 iparam.SatImbDrain = SatImbDrain; +0288 +0289 % start values and bounds +0290 rhostart = log10(data.invjoint.rhostart/1e6); +0291 rhobounds = log10(data.invjoint.rhobounds/1e6); +0292 x0 = [zeros(size(igeom.radius))' rhostart]; +0293 lb = [zeros(size(igeom.radius))' rhobounds(1)]; +0294 ub = [ones(size(igeom.radius))' rhobounds(2)]; +0295 +0296 options = optimset('Display',info,'TolFun',1e-12,'TolX',1e-12,... +0297 'Jacobian','on','DerivativeCheck','off','FinDiffType','central',... +0298 'Algorithm','levenberg-marquardt',... +0299 'MaxIter',1000); +0300 +0301 [X,~,~,~] = lsqnonlin(@(X)fcn_JointInvfree(X,iparam),x0,lb,ub,options); +0302 [~,~,ig,~] = fcn_JointInvfree(X,iparam); +0303 +0304 if useW +0305 % normalize the fit because the signal was error +0306 % weighted for the inversion +0307 e = diag(iparam.W); +0308 einv = 1./e; +0309 Winv = diag(einv); +0310 ig = Winv * ig; +0311 end +0312 +0313 residual = ig - g'; +0314 iF = X(1:length(X)-1); +0315 +0316 % output data +0317 % get RMS and X^2 +0318 if useW +0319 % weighted RMS error +0320 % residual is weighted with the amount of echoes N per time gate +0321 % NOTE: if "N per gate" is too large, the RMS estimation breaks down +0322 RMS(i) = sqrt (sum(N'.*(residual).^2) / length(residual)); +0323 % X2 estimate +0324 CHI2(i) = getChi2(g',ig,e); +0325 else +0326 % RMS error +0327 RMS(i) = sqrt( sum(residual.^2) / length(residual) ); +0328 % X2 estimate +0329 CHI2(i) = getChi2(g',ig,idata.nmr{levels(1)}.noise); +0330 end +0331 % error norm and model norm +0332 RN(i) = norm(residual,2); +0333 XN(i) = norm(L*iF',2); +0334 % wait-bar update +0335 if wbopts.show +0336 waitbar(i / steps,hwb,['processing ...',num2str(i),' / ',num2str(steps),' lambda steps']); +0337 end +0338 end +0339 end +0340 % delete the wait-bar +0341 if wbopts.show +0342 delete(hwb); +0343 end +0344 +0345 % check if the STOP button was pressed +0346 % if "UserData" is 1 STOP was not pressed -> save data +0347 if get(gui.push_handles.invjoint_run,'UserData') == 1 +0348 lc.lambda = lambda_range; +0349 lc.RMS = RMS; +0350 lc.RN = RN; +0351 lc.XN = XN; +0352 % get optimal lambda +0353 % lc.index = getLambdaFromRMS(lc.lambda,lc.RMS,0); +0354 lc.index = getLambdaFromLCurve(RN,XN,0); +0355 data.results.lcurve = lc; +0356 % update GUI data +0357 setappdata(fig,'data',data); +0358 % update L-curve plots +0359 updatePlotsLcurve; +0360 % status bar information +0361 displayStatusText(gui,[infostring,' done']); +0362 % set focus on results +0363 set(gui.plots.DistPanel,'Selection',1); +0364 else +0365 % status bar information +0366 displayStatusText(gui,[infostring,' was canceled']); +0367 % remove temporary data fields +0368 data = removeInversionFields(data); +0369 end +0370 +0371 case 'manual' +0372 % disable the RUN button to indicate a running inversion +0373 set(gui.push_handles.invjoint_run,'String','RUNNING ...',... +0374 'Enable','inactive'); +0375 +0376 % inversion parameter +0377 iparam.t = t; +0378 iparam.g = g; +0379 if useW +0380 iparam.W = W; +0381 end +0382 iparam.Tb = data.invstd.Tbulk; +0383 iparam.Td = data.invstd.Tdiff; +0384 iparam.T1T2 = T1T2flag; +0385 iparam.T1IRfac = T1IRfac; +0386 iparam.L = L; +0387 iparam.lambda = data.invjoint.lambda; +0388 iparam.igeom = igeom; +0389 iparam.IPS = IPS; +0390 iparam.SVdata = SVdata; +0391 iparam.SatImbDrain = SatImbDrain; +0392 +0393 % start values and bounds +0394 rhostart = log10(data.invjoint.rhostart/1e6); +0395 rhobounds = log10(data.invjoint.rhobounds/1e6); +0396 x0 = [zeros(size(igeom.radius))' rhostart]; +0397 lb = [zeros(size(igeom.radius))' rhobounds(1)]; +0398 ub = [ones(size(igeom.radius))' rhobounds(2)]; +0399 +0400 % status bar information +0401 infostring = 'Joint Inversion (free) using ''lsqnonlin'' ... '; +0402 displayStatusText(gui,infostring); +0403 +0404 % optimization settings +0405 options = optimset('Display',info,'TolFun',1e-12,'TolX',1e-12,... +0406 'Jacobian','on','DerivativeCheck','off','FinDiffType','central',... +0407 'Algorithm','levenberg-marquardt',... +0408 'MaxIter',1000); +0409 [X,~,~,exitflag] = lsqnonlin(@(X)fcn_JointInvfree(X,iparam),x0,lb,ub,options); +0410 +0411 % status bar information +0412 displayStatusText(gui,[infostring,'done']); +0413 % get the final fit +0414 [~,~,ig,KK] = fcn_JointInvfree(X,iparam); +0415 +0416 if useW +0417 % normalize the fit because the signal was error +0418 % weighted for the inversion +0419 e = diag(iparam.W); +0420 einv = 1./e; +0421 Winv = diag(einv); +0422 ig = Winv * ig; +0423 end +0424 +0425 % the inverted surface relaxivity and PSD +0426 iF = X(1:length(X)-1); +0427 irho = 10^X(length(X)); +0428 % inversion output +0429 data.results.invjoint.p0 = p0; +0430 data.results.invjoint.S0 = S0; +0431 data.results.invjoint.levels = levels; +0432 data.results.invjoint.T1T2 = T1T2flag; +0433 data.results.invjoint.T1IRfac = T1IRfac; +0434 data.results.invjoint.x0 = x0; +0435 data.results.invjoint.lb = lb; +0436 data.results.invjoint.ub = ub; +0437 data.results.invjoint.iparam = iparam; +0438 data.results.invjoint.iGEOM = igeom; +0439 data.results.invjoint.iSAT = iSAT; +0440 data.results.invjoint.iF = iF'; +0441 data.results.invjoint.irho = irho; +0442 data.results.invjoint.ig = ig; +0443 data.results.invjoint.XX = KK; +0444 data.results.invjoint.errnorm = norm((ig - g')).^2; +0445 data.results.invjoint.residual = ig - g'; +0446 data.results.invjoint.exitflag = exitflag; +0447 +0448 % get RMS and X^2 +0449 residual = data.results.invjoint.residual; +0450 if useW +0451 % weighted RMS error +0452 % residual is weighted with the amount of echoes N per time gate +0453 % NOTE: if "N per gate" is too large, the RMS estimation breaks down +0454 data.results.invjoint.rms = sqrt (sum(N'.*(residual).^2) / length(residual)); +0455 % X2 estimate +0456 data.results.invjoint.chi2 = getChi2(g',ig,e); +0457 else +0458 % RMS error +0459 data.results.invjoint.rms = sqrt( sum(residual.^2) / length(residual) ); +0460 % X2 estimate +0461 data.results.invjoint.chi2 = getChi2(g',ig,idata.nmr{levels(1)}.noise); +0462 end +0463 +0464 % predict CPS curves for the final model +0465 infostring = 'calculate CPS curve ... '; +0466 displayStatusText(gui,infostring); +0467 ppsddata.r = igeom.radius'; +0468 ppsddata.psd = data.results.invjoint.iF'./sum(data.results.invjoint.iF); +0469 if min(p) == 0 +0470 p_tmp = logspace(floor(log10(min(p(p>0)))-2),ceil(log10(max(p)))+2,150); +0471 else +0472 p_tmp = logspace(floor(log10(min(p)/2)),ceil(log10(max(p)))+2,150); +0473 end +0474 % waitbar option +0475 wbopts.show = true; +0476 wbopts.tag = 'INV'; +0477 pSAT = getSaturationFromPressureBatch(igeom,p_tmp,ppsddata,getConstants,wbopts); +0478 % save +0479 data.results.invjoint.pSAT = pSAT; +0480 displayStatusText(gui,[infostring,'done']); +0481 end +0482 +0483 case 'fixed' % only invert for rho +0484 % disable the RUN button to indicate a running inversion +0485 set(gui.push_handles.invjoint_run,'String','RUNNING ...',... +0486 'Enable','inactive'); +0487 +0488 % inversion geometry +0489 igeom.type = data.invjoint.geometry_type; +0490 igeom.angles = [data.invjoint.alpha data.invjoint.beta data.invjoint.gamma]; +0491 igeom.polyN = data.invjoint.polyN; +0492 igeom.radius = data.param.rho.*data.param.a.*fullsat.T; % first guess +0493 igeom = getGeometryParameter(igeom); +0494 +0495 iparam.t = t; +0496 iparam.g = g; +0497 if useW +0498 iparam.W = W; +0499 end +0500 iparam.indt = indt; +0501 iparam.Tb = data.invstd.Tbulk; +0502 iparam.Td = data.invstd.Tdiff; +0503 iparam.T1T2 = T1T2flag; +0504 iparam.T1IRfac = T1IRfac; +0505 iparam.SatImbDrain = SatImbDrain; +0506 iparam.p = p; +0507 iparam.igeom = igeom; +0508 iparam.x = fullsat.T'; +0509 iparam.f = fullsat.F'; +0510 +0511 % start values and bounds +0512 x0 = log10(data.invjoint.rhostart/1e6); +0513 rhobounds = log10(data.invjoint.rhobounds/1e6); +0514 lb = rhobounds(1); +0515 ub = rhobounds(2); +0516 +0517 infostring = 'Joint Inversion (fixed) using ''fminsearchbnd'' ... '; +0518 displayStatusText(gui,infostring); 0519 -0520 [errnorm,ig,XX,iGEOM,iSAT] = fcn_JointInvfixed(X,iparam); -0521 -0522 displayStatusText(gui,[infostring,'done']); +0520 options = optimset('Display',info,'TolFun',1e-12,'TolX',1e-12,... +0521 'MaxFunEvals',300,'MaxIter',300); +0522 X = fminsearchbnd(@(X) fcn_JointInvfixed(X,iparam),x0,lb,ub,options); 0523 -0524 if useW -0525 % normalize the fit because the signal was error -0526 % weighted for the inversion -0527 e = diag(iparam.W); -0528 einv = 1./e; -0529 Winv = diag(einv); -0530 ig = Winv * ig; -0531 end -0532 -0533 % inverted surface relaxivity -0534 irho = 10^X(1); -0535 % output data -0536 data.results.invjoint.p0 = p0; -0537 data.results.invjoint.S0 = S0; -0538 data.results.invjoint.levels = levels; -0539 data.results.invjoint.T1T2 = T1T2flag; -0540 data.results.invjoint.T1IRfac = T1IRfac; -0541 data.results.invjoint.x0 = x0; -0542 data.results.invjoint.lb = lb; -0543 data.results.invjoint.ub = ub; -0544 data.results.invjoint.iparam = iparam; -0545 data.results.invjoint.iGEOM = iGEOM; -0546 data.results.invjoint.iSAT = iSAT; -0547 data.results.invjoint.iF = fullsat.F; -0548 data.results.invjoint.irho = irho; -0549 data.results.invjoint.ig = ig; -0550 data.results.invjoint.XX = XX; -0551 data.results.invjoint.errnorm = errnorm; -0552 data.results.invjoint.residual = ig-g'; -0553 -0554 % get RMS and X^2 -0555 residual = data.results.invjoint.residual; -0556 if useW -0557 % weighted RMS error -0558 % residual is weighted with the amount of echoes N per time gate -0559 % NOTE: if "N per gate" is too large, the RMS estimation breaks down -0560 data.results.invjoint.rms = sqrt (sum(N'.*(residual).^2) / length(residual)); -0561 % X2 estimate -0562 data.results.invjoint.chi2 = getChi2(g',ig,e); -0563 else -0564 % RMS error -0565 data.results.invjoint.rms = sqrt( sum(residual.^2) / length(residual) ); -0566 % X2 estimate -0567 data.results.invjoint.chi2 = getChi2(g',ig,idata.nmr{levels(1)}.noise); -0568 end -0569 -0570 % predict CPS curves from final model -0571 infostring = 'calculate CPS curve ... '; -0572 displayStatusText(gui,infostring); -0573 ppsddata.r = iGEOM.radius'; -0574 ppsddata.psd = data.results.invjoint.iF'./sum(data.results.invjoint.iF); -0575 if min(p) == 0 -0576 p_tmp = logspace(floor(log10(min(p(p>0)))-2),ceil(log10(max(p)))+2,200); -0577 else -0578 p_tmp = logspace(floor(log10(min(p)/2)),ceil(log10(max(p)))+2,200); -0579 end -0580 % waitbar option -0581 wbopts.show = true; -0582 wbopts.tag = 'INV'; -0583 pSAT = getSaturationFromPressureBatch(iGEOM,p_tmp,ppsddata,getConstants,wbopts); -0584 -0585 data.results.invjoint.pSAT = pSAT; -0586 displayStatusText(gui,[infostring,'done']); -0587 -0588 case 'shape' % invert for rho and right angular shape -0589 % disable the RUN button to indicate a running inversion -0590 set(gui.push_handles.invjoint_run,'String','RUNNING ...',... -0591 'Enable','inactive'); -0592 -0593 % inversion geometry -0594 igeom.type = data.invjoint.geometry_type; -0595 igeom.angles = [data.invjoint.alpha data.invjoint.beta data.invjoint.gamma]; -0596 igeom.polyN = data.invjoint.polyN; -0597 igeom.radius = data.param.rho.*data.param.a.*fullsat.T; % first guess -0598 igeom = getGeometryParameter(igeom); -0599 -0600 iparam.t = t; -0601 iparam.g = g; -0602 if useW -0603 iparam.W = W; -0604 end -0605 iparam.indt = indt; -0606 iparam.Tb = data.invstd.Tbulk; -0607 iparam.T1T2 = T1T2flag; -0608 iparam.T1IRfac = T1IRfac; -0609 iparam.SatImbDrain = SatImbDrain; -0610 iparam.p = p; -0611 iparam.igeom = igeom; -0612 iparam.x = fullsat.T'; -0613 iparam.f = fullsat.F'; -0614 -0615 % scale fit parameter between [0 1] -0616 % x0 = [(log10(1e-6)+7)/3 data.invjoint.beta/45]; -0617 % lb = [(log10(1e-7)+7)/3 0.1/45]; -0618 % ub = [(log10(1e-4)+7)/3 45/45]; -0619 % old way -0620 x0 = [log10(data.invjoint.rhostart/1e6) data.invjoint.anglestart]; -0621 rhobounds = log10(data.invjoint.rhobounds/1e6); -0622 lb = [rhobounds(1) 0.1]; -0623 ub = [rhobounds(2) 45]; -0624 -0625 infostring = 'Joint Inversion (shape) using ''fminsearchbnd'' ... '; -0626 displayStatusText(gui,infostring); -0627 options = optimset('Display','iter','TolFun',1e-12,'TolX',1e-12,'MaxIter',500); -0628 options.Algorithm = 'levenberg-marquardt'; -0629 options.MaxFunEvals = 500; -0630 options.DiffMinChange = 1; -0631 -0632 options = optimset('Display',info,'TolFun',1e-9,'TolX',1e-9,... -0633 'MaxFunEvals',300,'MaxIter',300); -0634 X = fminsearchbnd(@(X) fcn_JointInvshape(X,iparam),x0,lb,ub,options); -0635 -0636 [errnorm,ig,XX,iGEOM,iSAT] = fcn_JointInvshape(X,iparam); -0637 -0638 displayStatusText(gui,[infostring,'done']); -0639 -0640 if useW -0641 % normalize the fit because the signal was error -0642 % weighted for the inversion -0643 e = diag(iparam.W); -0644 einv = 1./e; -0645 Winv = diag(einv); -0646 ig = Winv * ig; -0647 end -0648 -0649 irho = 10^X(1); -0650 ibeta = X(2); -0651 -0652 data.results.invjoint.p0 = p0; -0653 data.results.invjoint.S0 = S0; -0654 data.results.invjoint.levels = levels; -0655 data.results.invjoint.T1T2 = T1T2flag; -0656 data.results.invjoint.T1IRfac = T1IRfac; -0657 data.results.invjoint.x0 = x0; -0658 data.results.invjoint.lb = lb; -0659 data.results.invjoint.ub = ub; -0660 data.results.invjoint.iparam = iparam; -0661 data.results.invjoint.iGEOM = iGEOM; -0662 data.results.invjoint.iSAT = iSAT; -0663 data.results.invjoint.iF = fullsat.F; -0664 data.results.invjoint.irho = irho; -0665 data.results.invjoint.ibeta = ibeta; -0666 data.results.invjoint.ig = ig; -0667 data.results.invjoint.XX = XX; -0668 data.results.invjoint.errnorm = errnorm; -0669 data.results.invjoint.residual = ig-g'; -0670 -0671 % get RMS and X^2 -0672 residual = data.results.invjoint.residual; -0673 if useW -0674 % weighted RMS error -0675 % residual is weighted with the amount of echoes N per time gate -0676 % NOTE: if "N per gate" is too large, the RMS estimation breaks down -0677 data.results.invjoint.rms = sqrt (sum(N'.*(residual).^2) / length(residual)); -0678 % X2 estimate -0679 data.results.invjoint.chi2 = getChi2(g',ig,e); -0680 else -0681 % RMS error -0682 data.results.invjoint.rms = sqrt( sum(residual.^2) / length(residual) ); +0524 [errnorm,ig,XX,iGEOM,iSAT] = fcn_JointInvfixed(X,iparam); +0525 +0526 displayStatusText(gui,[infostring,'done']); +0527 +0528 if useW +0529 % normalize the fit because the signal was error +0530 % weighted for the inversion +0531 e = diag(iparam.W); +0532 einv = 1./e; +0533 Winv = diag(einv); +0534 ig = Winv * ig; +0535 end +0536 +0537 % inverted surface relaxivity +0538 irho = 10^X(1); +0539 % output data +0540 data.results.invjoint.p0 = p0; +0541 data.results.invjoint.S0 = S0; +0542 data.results.invjoint.levels = levels; +0543 data.results.invjoint.T1T2 = T1T2flag; +0544 data.results.invjoint.T1IRfac = T1IRfac; +0545 data.results.invjoint.x0 = x0; +0546 data.results.invjoint.lb = lb; +0547 data.results.invjoint.ub = ub; +0548 data.results.invjoint.iparam = iparam; +0549 data.results.invjoint.iGEOM = iGEOM; +0550 data.results.invjoint.iSAT = iSAT; +0551 data.results.invjoint.iF = fullsat.F; +0552 data.results.invjoint.irho = irho; +0553 data.results.invjoint.ig = ig; +0554 data.results.invjoint.XX = XX; +0555 data.results.invjoint.errnorm = errnorm; +0556 data.results.invjoint.residual = ig-g'; +0557 +0558 % get RMS and X^2 +0559 residual = data.results.invjoint.residual; +0560 if useW +0561 % weighted RMS error +0562 % residual is weighted with the amount of echoes N per time gate +0563 % NOTE: if "N per gate" is too large, the RMS estimation breaks down +0564 data.results.invjoint.rms = sqrt (sum(N'.*(residual).^2) / length(residual)); +0565 % X2 estimate +0566 data.results.invjoint.chi2 = getChi2(g',ig,e); +0567 else +0568 % RMS error +0569 data.results.invjoint.rms = sqrt( sum(residual.^2) / length(residual) ); +0570 % X2 estimate +0571 data.results.invjoint.chi2 = getChi2(g',ig,idata.nmr{levels(1)}.noise); +0572 end +0573 +0574 % predict CPS curves from final model +0575 infostring = 'calculate CPS curve ... '; +0576 displayStatusText(gui,infostring); +0577 ppsddata.r = iGEOM.radius'; +0578 ppsddata.psd = data.results.invjoint.iF'./sum(data.results.invjoint.iF); +0579 if min(p) == 0 +0580 p_tmp = logspace(floor(log10(min(p(p>0)))-2),ceil(log10(max(p)))+2,200); +0581 else +0582 p_tmp = logspace(floor(log10(min(p)/2)),ceil(log10(max(p)))+2,200); +0583 end +0584 % waitbar option +0585 wbopts.show = true; +0586 wbopts.tag = 'INV'; +0587 pSAT = getSaturationFromPressureBatch(iGEOM,p_tmp,ppsddata,getConstants,wbopts); +0588 +0589 data.results.invjoint.pSAT = pSAT; +0590 displayStatusText(gui,[infostring,'done']); +0591 +0592 case 'shape' % invert for rho and right angular shape +0593 % disable the RUN button to indicate a running inversion +0594 set(gui.push_handles.invjoint_run,'String','RUNNING ...',... +0595 'Enable','inactive'); +0596 +0597 % inversion geometry +0598 igeom.type = data.invjoint.geometry_type; +0599 igeom.angles = [data.invjoint.alpha data.invjoint.beta data.invjoint.gamma]; +0600 igeom.polyN = data.invjoint.polyN; +0601 igeom.radius = data.param.rho.*data.param.a.*fullsat.T; % first guess +0602 igeom = getGeometryParameter(igeom); +0603 +0604 iparam.t = t; +0605 iparam.g = g; +0606 if useW +0607 iparam.W = W; +0608 end +0609 iparam.indt = indt; +0610 iparam.Tb = data.invstd.Tbulk; +0611 iparam.Td = data.invstd.Tdiff; +0612 iparam.T1T2 = T1T2flag; +0613 iparam.T1IRfac = T1IRfac; +0614 iparam.SatImbDrain = SatImbDrain; +0615 iparam.p = p; +0616 iparam.igeom = igeom; +0617 iparam.x = fullsat.T'; +0618 iparam.f = fullsat.F'; +0619 +0620 % scale fit parameter between [0 1] +0621 % x0 = [(log10(1e-6)+7)/3 data.invjoint.beta/45]; +0622 % lb = [(log10(1e-7)+7)/3 0.1/45]; +0623 % ub = [(log10(1e-4)+7)/3 45/45]; +0624 % old way +0625 x0 = [log10(data.invjoint.rhostart/1e6) data.invjoint.anglestart]; +0626 rhobounds = log10(data.invjoint.rhobounds/1e6); +0627 lb = [rhobounds(1) 0.1]; +0628 ub = [rhobounds(2) 45]; +0629 +0630 infostring = 'Joint Inversion (shape) using ''fminsearchbnd'' ... '; +0631 displayStatusText(gui,infostring); +0632 options = optimset('Display','iter','TolFun',1e-12,'TolX',1e-12,'MaxIter',500); +0633 options.Algorithm = 'levenberg-marquardt'; +0634 options.MaxFunEvals = 500; +0635 options.DiffMinChange = 1; +0636 +0637 options = optimset('Display',info,'TolFun',1e-9,'TolX',1e-9,... +0638 'MaxFunEvals',300,'MaxIter',300); +0639 X = fminsearchbnd(@(X) fcn_JointInvshape(X,iparam),x0,lb,ub,options); +0640 +0641 [errnorm,ig,XX,iGEOM,iSAT] = fcn_JointInvshape(X,iparam); +0642 +0643 displayStatusText(gui,[infostring,'done']); +0644 +0645 if useW +0646 % normalize the fit because the signal was error +0647 % weighted for the inversion +0648 e = diag(iparam.W); +0649 einv = 1./e; +0650 Winv = diag(einv); +0651 ig = Winv * ig; +0652 end +0653 +0654 irho = 10^X(1); +0655 ibeta = X(2); +0656 +0657 data.results.invjoint.p0 = p0; +0658 data.results.invjoint.S0 = S0; +0659 data.results.invjoint.levels = levels; +0660 data.results.invjoint.T1T2 = T1T2flag; +0661 data.results.invjoint.T1IRfac = T1IRfac; +0662 data.results.invjoint.x0 = x0; +0663 data.results.invjoint.lb = lb; +0664 data.results.invjoint.ub = ub; +0665 data.results.invjoint.iparam = iparam; +0666 data.results.invjoint.iGEOM = iGEOM; +0667 data.results.invjoint.iSAT = iSAT; +0668 data.results.invjoint.iF = fullsat.F; +0669 data.results.invjoint.irho = irho; +0670 data.results.invjoint.ibeta = ibeta; +0671 data.results.invjoint.ig = ig; +0672 data.results.invjoint.XX = XX; +0673 data.results.invjoint.errnorm = errnorm; +0674 data.results.invjoint.residual = ig-g'; +0675 +0676 % get RMS and X^2 +0677 residual = data.results.invjoint.residual; +0678 if useW +0679 % weighted RMS error +0680 % residual is weighted with the amount of echoes N per time gate +0681 % NOTE: if "N per gate" is too large, the RMS estimation breaks down +0682 data.results.invjoint.rms = sqrt (sum(N'.*(residual).^2) / length(residual)); 0683 % X2 estimate -0684 data.results.invjoint.chi2 = getChi2(g',ig,idata.nmr{levels(1)}.noise); -0685 end -0686 -0687 % predict CPS curves from final model -0688 infostring = 'calculate CPS curve ... '; -0689 displayStatusText(gui,infostring); -0690 ppsddata.r = iGEOM.radius'; -0691 ppsddata.psd = data.results.invjoint.iF'./sum(data.results.invjoint.iF); -0692 if min(p) == 0 -0693 p_tmp = logspace(floor(log10(min(p(p>0)))-2),ceil(log10(max(p)))+2,150); -0694 else -0695 p_tmp = logspace(floor(log10(min(p)/2)),ceil(log10(max(p)))+2,150); -0696 end -0697 % wait-bar option -0698 wbopts.show = true; -0699 wbopts.tag = 'INV'; -0700 pSAT = getSaturationFromPressureBatch(iGEOM,p_tmp,ppsddata,getConstants,wbopts); -0701 -0702 data.results.invjoint.pSAT = pSAT; -0703 displayStatusText(gui,[infostring,'done']); -0704 end -0705 -0706 % if the regularization method was not L-curve then post process the -0707 % NMR data fits -0708 if ~strcmp(data.invjoint.regtype,'lcurve') -0709 % get the individual NMR fits -0710 for i = 1:1:numel(levels) -0711 idata.nmr{levels(i)}.fit_t = idata.nmr{levels(i)}.t; -0712 if i == 1 -0713 idata.nmr{levels(i)}.fit_g = ig(1:indt(1)); -0714 else -0715 idata.nmr{levels(i)}.fit_g = ig(sum(indt(1:i-1))+1:sum(indt(1:i-1))+indt(i)); -0716 end -0717 residual = idata.nmr{levels(i)}.fit_g - idata.nmr{levels(i)}.g; -0718 -0719 % get RMS and X^2 -0720 if useW -0721 % weighted RMS error -0722 % residual is weighted with the amount of echoes N per time gate -0723 % NOTE: if "N per gate" is too large, the RMS estimation breaks down -0724 N = idata.nmr{levels(i)}.N; -0725 rms = sqrt (sum(N.*(residual).^2) / length(residual)); -0726 % X2 estimate -0727 chi2 = getChi2(idata.nmr{levels(i)}.g,... -0728 idata.nmr{levels(i)}.fit_g,... -0729 idata.nmr{levels(i)}.e); -0730 else -0731 % RMS error -0732 rms = sqrt( sum(residual.^2) / length(residual) ); -0733 % X2 estimate -0734 chi2 = getChi2(idata.nmr{levels(i)}.g,... -0735 idata.nmr{levels(i)}.fit_g,... -0736 idata.nmr{levels(i)}.noise); -0737 end -0738 -0739 idata.nmr{levels(i)}.residual = residual; -0740 idata.nmr{levels(i)}.rms = rms; -0741 idata.nmr{levels(i)}.chi2 = chi2; -0742 end -0743 % save the GUI data -0744 data.results.invjoint.idata = idata; -0745 setappdata(fig,'data',data); -0746 -0747 % save the "INVdata" -0748 for i = 1:1:numel(levels) -0749 INVdata{levels(i)}.invjoint = data.invjoint; -0750 INVdata{levels(i)}.pressure = data.pressure; -0751 INVdata{levels(i)}.results.invjoint = data.results.invjoint; -0752 end -0753 setappdata(fig,'INVdata',INVdata); -0754 % update the plots -0755 updatePlotsJointInversion; -0756 % update the INFO fields -0757 updateInfo(gui.plots.SignalPanel); -0758 % set focus on results -0759 set(gui.plots.SignalPanel,'Selection',3); -0760 set(gui.plots.DistPanel,'Selection',3); -0761 % open INFO field -0762 set(gui.push_handles.info,'String','<'); -0763 onPushShowHide(gui.push_handles.info); -0764 % activate the ConductView GUI -0765 set(gui.menu.extra_conduct,'Enable','on'); -0766 end -0767 else -0768 if ~InvtypeIsOK -0769 helpdlg({'function: runInversionJoint','Perform standard multi-exponential inversion first.',... -0770 'For ''fixed'' and ''shape'' you need a RTD!'},'No RTD'); -0771 end -0772 if ~GatetypeIsOK -0773 helpdlg({'function: runInversionJoint','Check your ''signal gating'' settings.',... -0774 'All signals need to have the same gating.'},'Wrong gating'); -0775 end -0776 end -0777 else -0778 helpdlg({'function: runInversionJoint','Perform standard inversion first.',... -0779 'For ''fixed'' and ''shape'' you need a RTD!'},'No Data'); -0780 end -0781 -0782 %% at the end, no matter what reset the RUN button -0783 set(gui.push_handles.invjoint_run,'String','<HTML><u>R</u>UN',... -0784 'BackgroundColor','g','Enable','on','Callback',@onPushRun); -0785 setappdata(fig,'gui',gui); +0684 data.results.invjoint.chi2 = getChi2(g',ig,e); +0685 else +0686 % RMS error +0687 data.results.invjoint.rms = sqrt( sum(residual.^2) / length(residual) ); +0688 % X2 estimate +0689 data.results.invjoint.chi2 = getChi2(g',ig,idata.nmr{levels(1)}.noise); +0690 end +0691 +0692 % predict CPS curves from final model +0693 infostring = 'calculate CPS curve ... '; +0694 displayStatusText(gui,infostring); +0695 ppsddata.r = iGEOM.radius'; +0696 ppsddata.psd = data.results.invjoint.iF'./sum(data.results.invjoint.iF); +0697 if min(p) == 0 +0698 p_tmp = logspace(floor(log10(min(p(p>0)))-2),ceil(log10(max(p)))+2,150); +0699 else +0700 p_tmp = logspace(floor(log10(min(p)/2)),ceil(log10(max(p)))+2,150); +0701 end +0702 % wait-bar option +0703 wbopts.show = true; +0704 wbopts.tag = 'INV'; +0705 pSAT = getSaturationFromPressureBatch(iGEOM,p_tmp,ppsddata,getConstants,wbopts); +0706 +0707 data.results.invjoint.pSAT = pSAT; +0708 displayStatusText(gui,[infostring,'done']); +0709 end +0710 +0711 % if the regularization method was not L-curve then post process the +0712 % NMR data fits +0713 if ~strcmp(data.invjoint.regtype,'lcurve') +0714 % get the individual NMR fits +0715 for i = 1:1:numel(levels) +0716 idata.nmr{levels(i)}.fit_t = idata.nmr{levels(i)}.t; +0717 if i == 1 +0718 idata.nmr{levels(i)}.fit_g = ig(1:indt(1)); +0719 else +0720 idata.nmr{levels(i)}.fit_g = ig(sum(indt(1:i-1))+1:sum(indt(1:i-1))+indt(i)); +0721 end +0722 residual = idata.nmr{levels(i)}.fit_g - idata.nmr{levels(i)}.g; +0723 +0724 % get RMS and X^2 +0725 if useW +0726 % weighted RMS error +0727 % residual is weighted with the amount of echoes N per time gate +0728 % NOTE: if "N per gate" is too large, the RMS estimation breaks down +0729 N = idata.nmr{levels(i)}.N; +0730 rms = sqrt (sum(N.*(residual).^2) / length(residual)); +0731 % X2 estimate +0732 chi2 = getChi2(idata.nmr{levels(i)}.g,... +0733 idata.nmr{levels(i)}.fit_g,... +0734 idata.nmr{levels(i)}.e); +0735 else +0736 % RMS error +0737 rms = sqrt( sum(residual.^2) / length(residual) ); +0738 % X2 estimate +0739 chi2 = getChi2(idata.nmr{levels(i)}.g,... +0740 idata.nmr{levels(i)}.fit_g,... +0741 idata.nmr{levels(i)}.noise); +0742 end +0743 +0744 idata.nmr{levels(i)}.residual = residual; +0745 idata.nmr{levels(i)}.rms = rms; +0746 idata.nmr{levels(i)}.chi2 = chi2; +0747 end +0748 % save the GUI data +0749 data.results.invjoint.idata = idata; +0750 setappdata(fig,'data',data); +0751 +0752 % save the "INVdata" +0753 for i = 1:1:numel(levels) +0754 INVdata{levels(i)}.invjoint = data.invjoint; +0755 INVdata{levels(i)}.pressure = data.pressure; +0756 INVdata{levels(i)}.results.invjoint = data.results.invjoint; +0757 end +0758 setappdata(fig,'INVdata',INVdata); +0759 % update the plots +0760 updatePlotsJointInversion; +0761 % update the INFO fields +0762 updateInfo(gui.plots.SignalPanel); +0763 % set focus on results +0764 set(gui.plots.SignalPanel,'Selection',3); +0765 set(gui.plots.DistPanel,'Selection',3); +0766 % open INFO field +0767 set(gui.push_handles.info,'String','<'); +0768 onPushShowHide(gui.push_handles.info); +0769 % activate the ConductView GUI +0770 set(gui.menu.extra_conduct,'Enable','on'); +0771 end +0772 else +0773 if ~InvtypeIsOK +0774 helpdlg({'function: runInversionJoint','Perform standard multi-exponential inversion first.',... +0775 'For ''fixed'' and ''shape'' you need a RTD!'},'No RTD'); +0776 end +0777 if ~GatetypeIsOK +0778 helpdlg({'function: runInversionJoint','Check your ''signal gating'' settings.',... +0779 'All signals need to have the same gating.'},'Wrong gating'); +0780 end +0781 end +0782 else +0783 helpdlg({'function: runInversionJoint','Perform standard inversion first.',... +0784 'For ''fixed'' and ''shape'' you need a RTD!'},'No Data'); +0785 end 0786 -0787 end -0788 -0789 %------------- END OF CODE -------------- -0790 -0791 %% License: -0792 % MIT License -0793 % -0794 % Copyright (c) 2018 Thomas Hiller -0795 % -0796 % Permission is hereby granted, free of charge, to any person obtaining a copy -0797 % of this software and associated documentation files (the "Software"), to deal -0798 % in the Software without restriction, including without limitation the rights -0799 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0800 % copies of the Software, and to permit persons to whom the Software is -0801 % furnished to do so, subject to the following conditions: -0802 % -0803 % The above copyright notice and this permission notice shall be included in all -0804 % copies or substantial portions of the Software. -0805 % -0806 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0807 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0808 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0809 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0810 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0811 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0812 % SOFTWARE. +0787 %% at the end, no matter what reset the RUN button +0788 set(gui.push_handles.invjoint_run,'String','<HTML><u>R</u>UN',... +0789 'BackgroundColor','g','Enable','on','Callback',@onPushRun); +0790 setappdata(fig,'gui',gui); +0791 +0792 end +0793 +0794 %------------- END OF CODE -------------- +0795 +0796 %% License: +0797 % MIT License +0798 % +0799 % Copyright (c) 2018 Thomas Hiller +0800 % +0801 % Permission is hereby granted, free of charge, to any person obtaining a copy +0802 % of this software and associated documentation files (the "Software"), to deal +0803 % in the Software without restriction, including without limitation the rights +0804 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0805 % copies of the Software, and to permit persons to whom the Software is +0806 % furnished to do so, subject to the following conditions: +0807 % +0808 % The above copyright notice and this permission notice shall be included in all +0809 % copies or substantial portions of the Software. +0810 % +0811 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0812 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0813 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0814 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0815 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0816 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0817 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/runInversionStd.html b/doc/nucleus/functions/interface/runInversionStd.html index 9617be0..0e7a5f2 100644 --- a/doc/nucleus/functions/interface/runInversionStd.html +++ b/doc/nucleus/functions/interface/runInversionStd.html @@ -69,15 +69,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • NUCLEUSinv_updateInterface updates all GUI elements
  • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
  • onPushShowHide shows/hides the INFO column on the right side of NUCLEUSinv
  • onPushStop recognizes that a STOP push button was pressed and resets the
  • calibratePorosity determines a sample's porosity from a calibration
  • clearAllAxes clears all axes of a given figure
  • clearSingleAxis clears an individual axis
  • displayStatusText shows status information either in the GUI or on the
  • removeInversionFields deletes all inversion result fields from NUCLEUSinv
  • showFitStatistics shows an extra fit statistics figure (for T2 data)
  • updateInfo updates the information shown in all information list boxes
  • updatePlotsDistribution plots the RTD and PSD curves into NUCLEUSinv
  • updatePlotsLcurve plots the results of the L-curve calculation
  • updatePlotsSignal plots the raw and processed NMR signals in NUCLEUSinv
  • useSignalAsCalibration uses E0 as porosity calibration factor.
  • estimateUncertainty calculates pseudo uncertainty estimates for multi
  • fitDataFree is a control routine that uses 'lsqcurvefit' to fit NMR data
  • fitDataLSQ is a control routine that fits NMR data multi-exponentially;
  • fitDataLUdecomp is a control routine that uses a LU decomposition and the
  • fitDataMultiModal is a control routine that uses either 'lsqnonlin' or
  • getLambdaFromLCurve estimates the regularization parameter lambda according
  • This function is called by:
    • onPushRun handles the callbacks to all RUN push buttons in both GUIs and
    @@ -130,8 +130,8 @@

    SOURCE CODE ^% none 0043 % 0044 % See also: NUCLEUSinv -0045 % Author: Thomas Hiller -0046 % email: thomas.hiller[at]leibniz-liag.de +0045 % Author: see AUTHORS.md +0046 % email: see AUTHORS.md 0047 % License: MIT License (at end) 0048 0049 %------------- BEGIN CODE -------------- @@ -189,310 +189,353 @@

    SOURCE CODE ^'manual'; -0106 param.Lorder = data.invstd.Lorder; -0107 param.noise = data.results.nmrproc.noise; -0108 param.TE = data.results.nmrraw.t(2)-data.results.nmrraw.t(1); -0109 if isfield(data.results.nmrproc,'W') -0110 param.W = data.results.nmrproc.W; -0111 end -0112 param.solver = data.info.solver; -0113 -0114 % status bar information -0115 infostring = 'L-curve calculation ... '; -0116 displayStatusText(gui,infostring); -0117 -0118 % wait-bar option -0119 wbopts.show = true; -0120 wbopts.tag = 'INV'; -0121 if wbopts.show -0122 hwb = waitbar(0,'processing ...','Name','L-curve calculation','Visible','off'); -0123 steps = length(lambda_range); -0124 fig = findobj('Tag',wbopts.tag); -0125 if ~isempty(fig) -0126 posf = get(fig,'Position'); -0127 set(hwb,'Units','Pixel') -0128 posw = get(hwb,'Position'); -0129 set(hwb,'Position',[posf(1)+posf(3)/2-posw(3)/2 posf(2)+posf(4)/2-posw(4)/2 posw(3:4)]); -0130 end -0131 set(hwb,'Visible','on'); -0132 end -0133 -0134 % the L-curve calculation -0135 for i = 1:length(lambda_range) -0136 % check if the STOP button was pressed -0137 % if "UserData" is 1 STOP was not pressed -> continue -0138 if get(gui.push_handles.invstd_run,'UserData') == 1 -0139 param.lambda = lambda_range(i); -0140 invdata = fitDataLSQ(data.results.nmrproc.t,data.results.nmrproc.s,param); -0141 % output data -0142 RMS(i) = invdata.rms; -0143 RN(i) = invdata.rn; -0144 XN(i) = invdata.xn; -0145 % wait-bar update -0146 if wbopts.show -0147 waitbar(i / steps,hwb,['processing ...',num2str(i),' / ',num2str(steps),' lambda steps']); -0148 end -0149 end -0150 end -0151 % delete the wait-bar -0152 if wbopts.show -0153 delete(hwb); -0154 end -0155 -0156 % check if the STOP button was pressed -0157 % if "UserData" is 1 STOP was not pressed -> save data -0158 if get(gui.push_handles.invstd_run,'UserData') == 1 -0159 lc.lambda = lambda_range; -0160 lc.RMS = RMS; -0161 lc.RN = RN; -0162 lc.XN = XN; -0163 % get optimal lambda -0164 lc.index = getLambdaFromLCurve(RN,XN,0); -0165 data.results.lcurve = lc; -0166 % update GUI data -0167 setappdata(fig,'data',data); -0168 % update L-curve plots -0169 updatePlotsLcurve; -0170 % status bar information -0171 displayStatusText(gui,[infostring,' done']); -0172 else -0173 % status bar information -0174 displayStatusText(gui,[infostring,' was canceled']); -0175 % remove temporary data fields -0176 data = removeInversionFields(data); -0177 end -0178 -0179 otherwise % normal inversion -0180 % time the whole inversion -0181 tic; -0182 % Do we want inversion output on the command line -0183 switch data.info.InvInfo -0184 case 'on' -0185 param.info = 'final'; -0186 case 'off' -0187 param.info = 'off'; -0188 end -0189 -0190 % disable the RUN button to indicate a running inversion -0191 set(gui.push_handles.invstd_run,'String','RUNNING ...',... -0192 'Enable','inactive'); -0193 % switch depending on inversion method -0194 switch data.invstd.invtype -0195 case 'mono' % mono-exponential inversion -0196 flag = data.results.nmrproc.T1T2; -0197 param.T1IRfac = data.results.nmrproc.T1IRfac; -0198 param.noise = data.results.nmrproc.noise; -0199 param.optim = data.info.has_optim; -0200 if isfield(data.results.nmrproc,'W') -0201 param.W = data.results.nmrproc.W; -0202 end -0203 % status bar information -0204 switch data.info.has_optim -0205 case 'on' -0206 infostring = 'Inversion using ''Optimization Toolbox'' ... '; -0207 case 'off' -0208 infostring = 'Inversion using ''fminsearchbnd'' ... '; -0209 end -0210 displayStatusText(gui,infostring); -0211 invstd = fitDataFree(data.results.nmrproc.t,... -0212 data.results.nmrproc.s,flag,param,1); -0213 -0214 case 'free' % bi-exponential inversion -0215 flag = data.results.nmrproc.T1T2; -0216 param.T1IRfac = data.results.nmrproc.T1IRfac; -0217 param.noise = data.results.nmrproc.noise; -0218 param.optim = data.info.has_optim; -0219 if isfield(data.results.nmrproc,'W') -0220 param.W = data.results.nmrproc.W; -0221 end -0222 % status bar information -0223 switch data.info.has_optim -0224 case 'on' -0225 infostring = 'Inversion using ''Optimization Toolbox'' ... '; -0226 case 'off' -0227 infostring = 'Inversion using ''fminsearchbnd'' ... '; -0228 end -0229 displayStatusText(gui,infostring); -0230 invstd = fitDataFree(data.results.nmrproc.t,... -0231 data.results.nmrproc.s,flag,param,data.invstd.freeDT); -0232 -0233 case 'LU' % multi-exponential inversion -0234 % general parameter -0235 param.T1T2 = data.results.nmrproc.T1T2; -0236 param.T1IRfac = data.results.nmrproc.T1IRfac; -0237 param.Tb = data.invstd.Tbulk; -0238 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; -0239 param.Lorder = data.invstd.Lorder; -0240 param.lambda = data.invstd.lambda; -0241 param.noise = data.results.nmrproc.noise; -0242 if isfield(data.results.nmrproc,'W') -0243 param.W = data.results.nmrproc.W; -0244 end -0245 % status bar information -0246 infostring = 'Inversion using LU decomposition ... '; -0247 displayStatusText(gui,infostring); -0248 invstd = fitDataLUdecomp(data.results.nmrproc.t,... -0249 data.results.nmrproc.s,param); -0250 -0251 case 'NNLS' % multi-exponential inversion with manual regularization -0252 % general parameter -0253 param.T1T2 = data.results.nmrproc.T1T2; -0254 param.T1IRfac = data.results.nmrproc.T1IRfac; -0255 param.Tb = data.invstd.Tbulk; -0256 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; -0257 param.regMethod = data.invstd.regtype; -0258 param.Lorder = data.invstd.Lorder; -0259 param.lambda = data.invstd.lambda; -0260 param.noise = data.results.nmrproc.noise; -0261 param.solver = data.info.solver; -0262 if isfield(data.results.nmrproc,'W') -0263 param.W = data.results.nmrproc.W; -0264 end -0265 -0266 % status bar information -0267 switch data.info.solver -0268 case 'lsqlin' -0269 infostring = 'Inversion using ''Optimization Toolbox'' ... '; -0270 case 'lsqnonneg' -0271 infostring = 'Inversion using ''lsqnonneg'' ... '; -0272 end -0273 displayStatusText(gui,infostring); -0274 invstd = fitDataLSQ(data.results.nmrproc.t,... -0275 data.results.nmrproc.s,param); -0276 end -0277 % normalize to 1 -0278 if data.process.norm == 1 -0279 switch data.invstd.invtype -0280 case {'LU','NNLS'} -0281 % normalization with sum(f*dt) -> area~=1 -0282 % dt = log10(invstd.T1T2me(2))-log10(invstd.T1T2me(1)); -0283 % invstd.T1T2f = invstd.T1T2f/sum(invstd.T1T2f*dt); -0284 % normalization with sum() -> sum(f)=1 -0285 invstd.T1T2f = invstd.T1T2f./sum(invstd.T1T2f); -0286 % normalization with trapz() -> area=1 but sum(f)>1 -0287 % invstd.T1T2f = invstd.T1T2f./trapz(invstd.T1T2me,invstd.T1T2f); -0288 otherwise -0289 % nothing to do -0290 end -0291 end -0292 runtime = toc; -0293 displayStatusText(gui,[infostring,'done | inversion took ',... -0294 sprintf('%5.2f',runtime),' s']); -0295 % save inversion results -0296 data.results.invstd = invstd; -0297 setappdata(fig,'data',data); -0298 end -0299 % as long as the "UserData" is 1 the STOP button was not pressed and -0300 % the inversion result gets saved in "INVdata" -0301 if get(gui.push_handles.invstd_run,'UserData') == 1 && ... -0302 ( isfield(data.results,'invstd') || ... -0303 isfield(data.results,'lcurve') ) -0304 INVdata{id} = []; -0305 INVdata{id} = data; -0306 INVdata{id} = rmfield(INVdata{id},'import'); -0307 INVdata{id} = rmfield(INVdata{id},'info'); -0308 INVdata{id} = rmfield(INVdata{id},'calib'); -0309 INVdata{id} = rmfield(INVdata{id},'pressure'); -0310 -0311 % color the list entries that already have an inversion result -0312 strL = get(gui.listbox_handles.signal,'String'); -0313 str1 = strL{id}; -0314 str2 = ['<HTML><BODY bgcolor="rgb(',... -0315 sprintf('%d,%d,%d',gui.myui.colors.listINV.*255),')">',str1,'</BODY></HTML>']; -0316 strL{id} = str2; -0317 set(gui.listbox_handles.signal,'String',strL); -0318 -0319 % update GUI INVdata -0320 setappdata(fig,'INVdata',INVdata); -0321 -0322 % --- -0323 % special treatment for LIAG processing -0324 if isfield(data.import,'LIAG') && ~strcmp(data.invstd.regtype,'lcurve') -0325 if ~isempty(strfind(str1,' - calibration')) -0326 % save Tbulk from the calibration sample -0327 btn1 = 'Yes keep it'; -0328 btn2 = 'No, reset to 1e6 [s]'; -0329 if data.results.invstd.T2 < 0.2 -0330 answer = questdlg(['Tbulk seems very short with ',... -0331 sprintf('%4.3f',data.results.invstd.T2),' [s] ',... -0332 'Do you want to keep it?'], ... -0333 'Keep relaxation time as Tbulk', ... -0334 btn1,btn2,btn2); -0335 % Handle response -0336 switch answer -0337 case btn1 -0338 data.import.LIAG.Tbulk = data.results.invstd.T2; -0339 case btn2 -0340 data.import.LIAG.Tbulk = 1e6; -0341 end -0342 else -0343 data.import.LIAG.Tbulk = data.results.invstd.T2; -0344 end -0345 % update GUI data -0346 setappdata(fig,'data',data); -0347 % save calibration data -0348 useSignalAsCalibration(id); -0349 else -0350 calibratePorosity; -0351 end -0352 end -0353 % --- -0354 else % STOP was pressed (because "UserData" is 0) -0355 % reset "UserData" -0356 set(gui.push_handles.invstd_run,'UserData',1); -0357 end -0358 % update plots and INFO fields -0359 updatePlotsSignal; -0360 updatePlotsDistribution; -0361 updateInfo(gui.plots.SignalPanel); -0362 % set focus on results -0363 set(gui.plots.SignalPanel,'Selection',1); -0364 set(gui.plots.DistPanel,'Selection',1); -0365 % open INFO field -0366 set(gui.push_handles.info,'String','<'); -0367 onPushShowHide(gui.push_handles.info); -0368 if ~isempty(findobj('Tag','FITSTATS')) -0369 showFitStatistics; -0370 end -0371 NUCLEUSinv_updateInterface; -0372 else -0373 helpdlg('Cannot start inversion because no data set is selected!',... -0374 'Select NMR data first.'); -0375 end -0376 -0377 %% at the end, no matter what reset the RUN button -0378 set(gui.push_handles.invstd_run,'String','<HTML><u>R</u>UN',... -0379 'BackgroundColor','g','Enable','on','Callback',@onPushRun); -0380 setappdata(fig,'gui',gui); -0381 -0382 end -0383 -0384 %------------- END OF CODE -------------- -0385 -0386 %% License: -0387 % MIT License -0388 % -0389 % Copyright (c) 2018 Thomas Hiller -0390 % -0391 % Permission is hereby granted, free of charge, to any person obtaining a copy -0392 % of this software and associated documentation files (the "Software"), to deal -0393 % in the Software without restriction, including without limitation the rights -0394 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0395 % copies of the Software, and to permit persons to whom the Software is -0396 % furnished to do so, subject to the following conditions: -0397 % -0398 % The above copyright notice and this permission notice shall be included in all -0399 % copies or substantial portions of the Software. -0400 % -0401 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0402 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0403 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0404 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0405 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0406 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0407 % SOFTWARE. +0104 param.Td = data.invstd.Tdiff; +0105 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; +0106 param.regMethod = 'manual'; +0107 param.Lorder = data.invstd.Lorder; +0108 param.noise = data.results.nmrproc.noise; +0109 param.TE = data.results.nmrraw.t(2)-data.results.nmrraw.t(1); +0110 if isfield(data.results.nmrproc,'W') +0111 param.W = data.results.nmrproc.W; +0112 end +0113 param.solver = data.info.solver; +0114 +0115 % status bar information +0116 infostring = 'L-curve calculation ... '; +0117 displayStatusText(gui,infostring); +0118 +0119 % wait-bar option +0120 wbopts.show = true; +0121 wbopts.tag = 'INV'; +0122 if wbopts.show +0123 hwb = waitbar(0,'processing ...','Name','L-curve calculation','Visible','off'); +0124 steps = length(lambda_range); +0125 fig = findobj('Tag',wbopts.tag); +0126 if ~isempty(fig) +0127 posf = get(fig,'Position'); +0128 set(hwb,'Units','Pixel') +0129 posw = get(hwb,'Position'); +0130 set(hwb,'Position',[posf(1)+posf(3)/2-posw(3)/2 posf(2)+posf(4)/2-posw(4)/2 posw(3:4)]); +0131 end +0132 set(hwb,'Visible','on'); +0133 end +0134 +0135 % the L-curve calculation +0136 for i = 1:length(lambda_range) +0137 % check if the STOP button was pressed +0138 % if "UserData" is 1 STOP was not pressed -> continue +0139 if get(gui.push_handles.invstd_run,'UserData') == 1 +0140 param.lambda = lambda_range(i); +0141 invdata = fitDataLSQ(data.results.nmrproc.t,data.results.nmrproc.s,param); +0142 % output data +0143 RMS(i) = invdata.rms; +0144 RN(i) = invdata.rn; +0145 XN(i) = invdata.xn; +0146 % wait-bar update +0147 if wbopts.show +0148 waitbar(i / steps,hwb,['processing ...',num2str(i),' / ',num2str(steps),' lambda steps']); +0149 end +0150 end +0151 end +0152 % delete the wait-bar +0153 if wbopts.show +0154 delete(hwb); +0155 end +0156 +0157 % check if the STOP button was pressed +0158 % if "UserData" is 1 STOP was not pressed -> save data +0159 if get(gui.push_handles.invstd_run,'UserData') == 1 +0160 lc.lambda = lambda_range; +0161 lc.RMS = RMS; +0162 lc.RN = RN; +0163 lc.XN = XN; +0164 % get optimal lambda +0165 lc.index = getLambdaFromLCurve(RN,XN,0); +0166 data.results.lcurve = lc; +0167 % update GUI data +0168 setappdata(fig,'data',data); +0169 % update L-curve plots +0170 updatePlotsLcurve; +0171 % status bar information +0172 displayStatusText(gui,[infostring,' done']); +0173 else +0174 % status bar information +0175 displayStatusText(gui,[infostring,' was canceled']); +0176 % remove temporary data fields +0177 data = removeInversionFields(data); +0178 end +0179 +0180 otherwise % normal inversion +0181 % time the whole inversion +0182 tic; +0183 % Do we want inversion output on the command line +0184 switch data.info.InvInfo +0185 case 'on' +0186 param.info = 'final'; +0187 case 'off' +0188 param.info = 'off'; +0189 end +0190 +0191 % disable the RUN button to indicate a running inversion +0192 set(gui.push_handles.invstd_run,'String','RUNNING ...',... +0193 'Enable','inactive'); +0194 % switch depending on inversion method +0195 switch data.invstd.invtype +0196 case 'mono' % mono-exponential inversion +0197 flag = data.results.nmrproc.T1T2; +0198 param.T1IRfac = data.results.nmrproc.T1IRfac; +0199 param.noise = data.results.nmrproc.noise; +0200 param.optim = data.info.has_optim; +0201 if isfield(data.results.nmrproc,'W') +0202 param.W = data.results.nmrproc.W; +0203 end +0204 % status bar information +0205 switch data.info.has_optim +0206 case 'on' +0207 infostring = 'Inversion using ''Optimization Toolbox'' ... '; +0208 case 'off' +0209 infostring = 'Inversion using ''fminsearchbnd'' ... '; +0210 end +0211 displayStatusText(gui,infostring); +0212 invstd = fitDataFree(data.results.nmrproc.t,... +0213 data.results.nmrproc.s,flag,param,1); +0214 +0215 case 'free' % N free single-exponential inversion +0216 flag = data.results.nmrproc.T1T2; +0217 param.T1IRfac = data.results.nmrproc.T1IRfac; +0218 param.noise = data.results.nmrproc.noise; +0219 param.optim = data.info.has_optim; +0220 if isfield(data.results.nmrproc,'W') +0221 param.W = data.results.nmrproc.W; +0222 end +0223 % status bar information +0224 switch data.info.has_optim +0225 case 'on' +0226 infostring = 'Inversion using ''Optimization Toolbox'' ... '; +0227 case 'off' +0228 infostring = 'Inversion using ''fminsearchbnd'' ... '; +0229 end +0230 displayStatusText(gui,infostring); +0231 invstd = fitDataFree(data.results.nmrproc.t,... +0232 data.results.nmrproc.s,flag,param,data.invstd.freeDT); +0233 +0234 case 'LU' % multi-exponential inversion +0235 % general parameter +0236 param.T1T2 = data.results.nmrproc.T1T2; +0237 param.T1IRfac = data.results.nmrproc.T1IRfac; +0238 param.Tb = data.invstd.Tbulk; +0239 param.Td = data.invstd.Tdiff; +0240 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; +0241 param.Lorder = data.invstd.Lorder; +0242 param.lambda = data.invstd.lambda; +0243 param.noise = data.results.nmrproc.noise; +0244 if isfield(data.results.nmrproc,'W') +0245 param.W = data.results.nmrproc.W; +0246 end +0247 % status bar information +0248 infostring = 'Inversion using LU decomposition ... '; +0249 displayStatusText(gui,infostring); +0250 invstd = fitDataLUdecomp(data.results.nmrproc.t,... +0251 data.results.nmrproc.s,param); +0252 +0253 case 'NNLS' % multi-exponential inversion with manual regularization +0254 % general parameter +0255 param.T1T2 = data.results.nmrproc.T1T2; +0256 param.T1IRfac = data.results.nmrproc.T1IRfac; +0257 param.Tb = data.invstd.Tbulk; +0258 param.Td = data.invstd.Tdiff; +0259 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; +0260 param.regMethod = data.invstd.regtype; +0261 param.Lorder = data.invstd.Lorder; +0262 param.lambda = data.invstd.lambda; +0263 param.noise = data.results.nmrproc.noise; +0264 param.solver = data.info.solver; +0265 if isfield(data.results.nmrproc,'W') +0266 param.W = data.results.nmrproc.W; +0267 end +0268 +0269 % status bar information +0270 switch data.info.solver +0271 case 'lsqlin' +0272 infostring = 'Inversion using ''Optimization Toolbox'' ... '; +0273 case 'lsqnonneg' +0274 infostring = 'Inversion using ''lsqnonneg'' ... '; +0275 end +0276 displayStatusText(gui,infostring); +0277 invstd = fitDataLSQ(data.results.nmrproc.t,... +0278 data.results.nmrproc.s,param); +0279 +0280 case 'MUMO' % N free distribution inversion +0281 param.T1T2 = data.results.nmrproc.T1T2; +0282 param.T1IRfac = data.results.nmrproc.T1IRfac; +0283 param.Tb = data.invstd.Tbulk; +0284 param.Td = data.invstd.Tdiff; +0285 param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; +0286 param.noise = data.results.nmrproc.noise; +0287 param.optim = data.info.has_optim; +0288 if isfield(data.results.nmrproc,'W') +0289 param.W = data.results.nmrproc.W; +0290 end +0291 +0292 % status bar information +0293 switch data.info.solver +0294 case 'lsqlin' +0295 infostring = 'Inversion using ''Optimization Toolbox'' ... '; +0296 case 'lsqnonneg' +0297 infostring = 'Inversion using ''fminsearchbnd'' ... '; +0298 end +0299 displayStatusText(gui,infostring); +0300 invstd = fitDataMultiModal(data.results.nmrproc.t,... +0301 data.results.nmrproc.s,param,data.invstd.freeDT); +0302 +0303 % estimate uncertainty +0304 if data.invstd.useUncert +0305 % original fit parameter +0306 iparam = param; +0307 % uncertainty parameter +0308 uparam.time = data.results.nmrproc.t; +0309 uparam.signal = data.results.nmrproc.s; +0310 uparam.uncertMethod = data.invstd.uncertMethod; +0311 uparam.uncertThresh = data.invstd.uncertThresh; +0312 uparam.uncertChi2 = data.invstd.uncertChi2; +0313 uparam.uncertN = data.invstd.uncertN; +0314 uparam.uncertMax = data.invstd.uncertMax; +0315 invstd = estimateUncertainty(data.invstd.invtype,invstd,iparam,uparam); +0316 end +0317 end +0318 % normalize to 1 +0319 if data.process.norm == 1 +0320 switch data.invstd.invtype +0321 case {'LU','NNLS','MUMO'} +0322 % normalization with sum() -> sum(f)=1 +0323 % this is the standard way of doing it +0324 invstd.T1T2f = invstd.T1T2f./sum(invstd.T1T2f); +0325 % alternatives depending on the objective: +0326 % 1.) normalization with sum(f*dt) -> area~=1 +0327 % dt = log10(invstd.T1T2me(2))-log10(invstd.T1T2me(1)); +0328 % invstd.T1T2f = invstd.T1T2f/sum(invstd.T1T2f*dt); +0329 % 2.) normalization with trapz() -> area=1 but sum(f)>1 +0330 % invstd.T1T2f = invstd.T1T2f./trapz(invstd.T1T2me,invstd.T1T2f); +0331 otherwise +0332 % nothing to do +0333 end +0334 end +0335 runtime = toc; +0336 displayStatusText(gui,[infostring,'done | inversion took ',... +0337 sprintf('%5.2f',runtime),' s']); +0338 % save inversion results +0339 data.results.invstd = invstd; +0340 setappdata(fig,'data',data); +0341 end +0342 % as long as the "UserData" is 1 the STOP button was not pressed and +0343 % the inversion result gets saved in "INVdata" +0344 if get(gui.push_handles.invstd_run,'UserData') == 1 && ... +0345 ( isfield(data.results,'invstd') || ... +0346 isfield(data.results,'lcurve') ) +0347 INVdata{id} = []; +0348 INVdata{id} = data; +0349 INVdata{id} = rmfield(INVdata{id},'import'); +0350 INVdata{id} = rmfield(INVdata{id},'info'); +0351 INVdata{id} = rmfield(INVdata{id},'calib'); +0352 INVdata{id} = rmfield(INVdata{id},'pressure'); +0353 +0354 % color the list entries that already have an inversion result +0355 strL = get(gui.listbox_handles.signal,'String'); +0356 str1 = strL{id}; +0357 str2 = ['<HTML><BODY bgcolor="rgb(',... +0358 sprintf('%d,%d,%d',gui.myui.colors.listINV.*255),')">',str1,'</BODY></HTML>']; +0359 strL{id} = str2; +0360 set(gui.listbox_handles.signal,'String',strL); +0361 +0362 % update GUI INVdata +0363 setappdata(fig,'INVdata',INVdata); +0364 +0365 % --- +0366 % special treatment for LIAG processing +0367 if isfield(data.import,'LIAG') && ~strcmp(data.invstd.regtype,'lcurve') +0368 if ~isempty(strfind(str1,' - calibration')) +0369 % save Tbulk from the calibration sample +0370 btn1 = 'Yes keep it'; +0371 btn2 = 'No, reset to 1e6 [s]'; +0372 if data.results.invstd.T2 < 0.2 +0373 answer = questdlg(['Tbulk seems very short with ',... +0374 sprintf('%4.3f',data.results.invstd.T2),' [s] ',... +0375 'Do you want to keep it?'], ... +0376 'Keep relaxation time as Tbulk', ... +0377 btn1,btn2,btn2); +0378 % Handle response +0379 switch answer +0380 case btn1 +0381 data.import.LIAG.Tbulk = data.results.invstd.T2; +0382 case btn2 +0383 data.import.LIAG.Tbulk = 1e6; +0384 end +0385 else +0386 data.import.LIAG.Tbulk = data.results.invstd.T2; +0387 end +0388 % update GUI data +0389 setappdata(fig,'data',data); +0390 % save calibration data +0391 useSignalAsCalibration(id); +0392 else +0393 calibratePorosity; +0394 end +0395 end +0396 % --- +0397 else % STOP was pressed (because "UserData" is 0) +0398 % reset "UserData" +0399 set(gui.push_handles.invstd_run,'UserData',1); +0400 end +0401 % update plots and INFO fields +0402 updatePlotsSignal; +0403 updatePlotsDistribution; +0404 updateInfo(gui.plots.SignalPanel); +0405 % set focus on results +0406 set(gui.plots.SignalPanel,'Selection',1); +0407 set(gui.plots.DistPanel,'Selection',1); +0408 % open INFO field +0409 set(gui.push_handles.info,'String','<'); +0410 onPushShowHide(gui.push_handles.info); +0411 if ~isempty(findobj('Tag','FITSTATS')) +0412 showFitStatistics; +0413 end +0414 NUCLEUSinv_updateInterface; +0415 else +0416 helpdlg('Cannot start inversion because no data set is selected!',... +0417 'Select NMR data first.'); +0418 end +0419 +0420 %% at the end, no matter what reset the RUN button +0421 set(gui.push_handles.invstd_run,'String','<HTML><u>R</u>UN',... +0422 'BackgroundColor','g','Enable','on','Callback',@onPushRun); +0423 setappdata(fig,'gui',gui); +0424 +0425 end +0426 +0427 %------------- END OF CODE -------------- +0428 +0429 %% License: +0430 % MIT License +0431 % +0432 % Copyright (c) 2018 Thomas Hiller +0433 % +0434 % Permission is hereby granted, free of charge, to any person obtaining a copy +0435 % of this software and associated documentation files (the "Software"), to deal +0436 % in the Software without restriction, including without limitation the rights +0437 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0438 % copies of the Software, and to permit persons to whom the Software is +0439 % furnished to do so, subject to the following conditions: +0440 % +0441 % The above copyright notice and this permission notice shall be included in all +0442 % copies or substantial portions of the Software. +0443 % +0444 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0445 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0446 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0447 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0448 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0449 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0450 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/showExtraGraphics.html b/doc/nucleus/functions/interface/showExtraGraphics.html index b8132cc..32acf1f 100644 --- a/doc/nucleus/functions/interface/showExtraGraphics.html +++ b/doc/nucleus/functions/interface/showExtraGraphics.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/showFitStatistics.html b/doc/nucleus/functions/interface/showFitStatistics.html index 17ae4bd..58d5581 100644 --- a/doc/nucleus/functions/interface/showFitStatistics.html +++ b/doc/nucleus/functions/interface/showFitStatistics.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/showParameterInfo.html b/doc/nucleus/functions/interface/showParameterInfo.html index ff04b03..12d4cf5 100644 --- a/doc/nucleus/functions/interface/showParameterInfo.html +++ b/doc/nucleus/functions/interface/showParameterInfo.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/switchToolTips.html b/doc/nucleus/functions/interface/switchToolTips.html index b4ebbc9..1254a45 100644 --- a/doc/nucleus/functions/interface/switchToolTips.html +++ b/doc/nucleus/functions/interface/switchToolTips.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv, NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/uncheckImportMenus.html b/doc/nucleus/functions/interface/uncheckImportMenus.html index a239d5f..fba64b6 100644 --- a/doc/nucleus/functions/interface/uncheckImportMenus.html +++ b/doc/nucleus/functions/interface/uncheckImportMenus.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- @@ -114,46 +114,49 @@

    SOURCE CODE ^'Checked','off'); 0046 set(gui.menu.file_import_lab_liag_project,'Checked','off'); 0047 set(gui.menu.file_import_lab_bgr_std,'Checked','off'); -0048 set(gui.menu.file_import_lab_bgr_org,'Checked','off'); -0049 set(gui.menu.file_import_lab_bgr_mat,'Checked','off'); -0050 set(gui.menu.file_import_lab_bam_tom,'Checked','off'); -0051 set(gui.menu.file_import_lab_ascii_T1,'Checked','off'); -0052 set(gui.menu.file_import_lab_ascii_T2,'Checked','off'); -0053 set(gui.menu.file_import_lab_excel_T1,'Checked','off'); -0054 set(gui.menu.file_import_lab_excel_T2,'Checked','off'); -0055 set(gui.menu.file_import_nmrinv_file,'Checked','off'); -0056 set(gui.menu.file_import_nmrmod_file,'Checked','off'); -0057 set(gui.menu.file_import_nmrmod_gui,'Checked','off'); -0058 -0059 % update GUI data -0060 setappdata(fig,'gui',gui); +0048 set(gui.menu.file_import_lab_bgr_mat,'Checked','off'); +0049 set(gui.menu.file_import_lab_bgr_mouse_cpmg,'Checked','off'); +0050 set(gui.menu.file_import_lab_bgr_mouse_liftsingle,'Checked','off'); +0051 set(gui.menu.file_import_lab_bgr_mouse_liftall,'Checked','off'); +0052 set(gui.menu.file_import_lab_bgr_helios,'Checked','off'); +0053 set(gui.menu.file_import_lab_bam_tom,'Checked','off'); +0054 set(gui.menu.file_import_lab_ascii_T1,'Checked','off'); +0055 set(gui.menu.file_import_lab_ascii_T2,'Checked','off'); +0056 set(gui.menu.file_import_lab_excel_T1,'Checked','off'); +0057 set(gui.menu.file_import_lab_excel_T2,'Checked','off'); +0058 set(gui.menu.file_import_nmrinv_file,'Checked','off'); +0059 set(gui.menu.file_import_nmrmod_file,'Checked','off'); +0060 set(gui.menu.file_import_nmrmod_gui,'Checked','off'); 0061 -0062 end -0063 -0064 %------------- END OF CODE -------------- -0065 -0066 %% License: -0067 % MIT License -0068 % -0069 % Copyright (c) 2018 Thomas Hiller -0070 % -0071 % Permission is hereby granted, free of charge, to any person obtaining a copy -0072 % of this software and associated documentation files (the "Software"), to deal -0073 % in the Software without restriction, including without limitation the rights -0074 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0075 % copies of the Software, and to permit persons to whom the Software is -0076 % furnished to do so, subject to the following conditions: -0077 % -0078 % The above copyright notice and this permission notice shall be included in all -0079 % copies or substantial portions of the Software. +0062 % update GUI data +0063 setappdata(fig,'gui',gui); +0064 +0065 end +0066 +0067 %------------- END OF CODE -------------- +0068 +0069 %% License: +0070 % MIT License +0071 % +0072 % Copyright (c) 2018 Thomas Hiller +0073 % +0074 % Permission is hereby granted, free of charge, to any person obtaining a copy +0075 % of this software and associated documentation files (the "Software"), to deal +0076 % in the Software without restriction, including without limitation the rights +0077 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0078 % copies of the Software, and to permit persons to whom the Software is +0079 % furnished to do so, subject to the following conditions: 0080 % -0081 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0082 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0083 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0084 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0085 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0086 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0087 % SOFTWARE. +0081 % The above copyright notice and this permission notice shall be included in all +0082 % copies or substantial portions of the Software. +0083 % +0084 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0085 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0086 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0087 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0088 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0089 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0090 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/updateCPSTable.html b/doc/nucleus/functions/interface/updateCPSTable.html index a0f8588..e47603f 100644 --- a/doc/nucleus/functions/interface/updateCPSTable.html +++ b/doc/nucleus/functions/interface/updateCPSTable.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updateCPSTableSize.html b/doc/nucleus/functions/interface/updateCPSTableSize.html index 3d0ac0f..3984bfd 100644 --- a/doc/nucleus/functions/interface/updateCPSTableSize.html +++ b/doc/nucleus/functions/interface/updateCPSTableSize.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updateInfo.html b/doc/nucleus/functions/interface/updateInfo.html index 5c518a2..ee3eb50 100644 --- a/doc/nucleus/functions/interface/updateInfo.html +++ b/doc/nucleus/functions/interface/updateInfo.html @@ -50,8 +50,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 </ul>
 This function is called by:
 <ul style= -
  • NUCLEUSinv_createPanelPlots creates graphics panel
  • onEditValue updates all edit field values, checks for wrong inputs and
  • onListboxData handles the calls from the context menu of the data
  • onMenuJointInversion handles the call from the menu that activates / deactivates
  • onRadioGates selects the re-sampling / gating method ("log", "lin" or "none")
  • onRadioNormalize selects whether to normalize a NMR signal to 1
  • importINV2INV imports a previously saved NUCLEUSinv session
  • runInversionJoint controls the joint inversion process to infer a pore size
  • runInversionStd controls the standard inversion process to invert a
  • +
  • NUCLEUSinv_createPanelPlots creates graphics panel
  • onEditValue updates all edit field values, checks for wrong inputs and
  • onListboxData handles the calls from the context menu of the data
  • onMenuJointInversion handles the call from the menu that activates / deactivates
  • onRadioGates selects the re-sampling / gating method ("log", "lin" or "none")
  • onRadioNormalize selects whether to normalize a NMR signal to 1
  • runInversionJoint controls the joint inversion process to infer a pore size
  • runInversionStd controls the standard inversion process to invert a
  • @@ -92,8 +92,8 @@

    SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- @@ -134,11 +134,11 @@

    SOURCE CODE ^case 'T2' 0066 switch data.process.gatetype 0067 case 'raw' -0068 info{end+1,1} = ['<HTML><BODY>Echos &nbsp= ',... +0068 info{end+1,1} = ['<HTML><BODY>Echos&nbsp= ',... 0069 sprintf('%d',length(nmrproc.t)),... 0070 ' (',data.process.gatetype,')','</BODY></HTML>']; 0071 otherwise -0072 info{end+1,1} = ['<HTML><BODY>Gates &nbsp= ',... +0072 info{end+1,1} = ['<HTML><BODY>Gates&nbsp= ',... 0073 sprintf('%d',length(nmrproc.t)),... 0074 ' (',data.process.gatetype,')','</BODY></HTML>']; 0075 end @@ -147,12 +147,12 @@

    SOURCE CODE ^switch data.process.norm 0079 case 0 0080 if max(nmrproc.s) < 1e-3 -0081 info{end+1,1} = ['<HTML><BODY>A_max &nbsp= ',... -0082 sprintf('%5.4e',max(nmrproc.s)),... +0081 info{end+1,1} = ['<HTML><BODY>A_max&nbsp= ',... +0082 sprintf('%5.3e',max(nmrproc.s)),... 0083 '</BODY></HTML>']; 0084 else -0085 info{end+1,1} = ['<HTML><BODY>A_max &nbsp= ',... -0086 sprintf('%5.4f',max(nmrproc.s)),... +0085 info{end+1,1} = ['<HTML><BODY>A_max&nbsp= ',... +0086 sprintf('%5.3f',max(nmrproc.s)),... 0087 '</BODY></HTML>']; 0088 end 0089 case 1 @@ -162,12 +162,12 @@

    SOURCE CODE ^'</BODY></HTML>']; 0094 else 0095 info{end+1,1} = ['<HTML><BODY>Normfac = ',... -0096 sprintf('%5.4f',max(data.process.normfac)),... +0096 sprintf('%5.3f',max(data.process.normfac)),... 0097 '</BODY></HTML>']; 0098 end 0099 0100 end -0101 info{end+1,1} = ['<HTML><BODY>noise &nbsp= ',sprintf('%4.3e',nmrproc.noise),'</BODY></HTML>']; +0101 info{end+1,1} = ['<HTML><BODY>noise&nbsp= ',sprintf('%4.2e',nmrproc.noise),'</BODY></HTML>']; 0102 info{end+1,1} = ' '; 0103 0104 % possible inversion results/statistics @@ -181,12 +181,12 @@

    SOURCE CODE ^switch nmrproc.T1T2 0113 case 'T1' 0114 info{end+1,1} = ['<HTML><BODY>E<sub>&infin</sub> = ',... -0115 sprintf('%4.3e',sum(invstd.E0)),... -0116 ' &#8723 (',sprintf('%4.3e',ciE0),')','</BODY></HTML>']; +0115 sprintf('%4.2e',sum(invstd.E0)),... +0116 ' &#8723 (',sprintf('%4.2e',ciE0),')','</BODY></HTML>']; 0117 case 'T2' 0118 info{end+1,1} = ['<HTML><BODY>E<sub><font size="',num2str(subfs),'">0</sub> = ',... -0119 sprintf('%4.3e',sum(invstd.E0)),... -0120 ' &#8723 (',sprintf('%4.3e',ciE0),')','</BODY></HTML>']; +0119 sprintf('%4.2e',sum(invstd.E0)),... +0120 ' &#8723 (',sprintf('%4.2e',ciE0),')','</BODY></HTML>']; 0121 end 0122 info{end+1,1} = ' '; 0123 if isfield(invstd,'chi2') @@ -195,339 +195,422 @@

    SOURCE CODE ^'<HTML><BODY>',str,'</BODY></HTML>']; 0127 end 0128 end -0129 str = ['RMS = ',sprintf('%4.3e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; +0129 str = ['RMS = ',sprintf('%4.2e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; 0130 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; -0131 if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 -0132 info{end+1,1} = ['<HTML><BODY>S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'</BODY></HTML>']; -0133 end -0134 -0135 case 'free' -0136 ciE0s = sum(full(invstd.ci(1:2:end))); -0137 E0 = invstd.E0; -0138 switch nmrproc.T1T2 -0139 case 'T1' -0140 info{end+1,1} = ['<HTML><BODY>E<sub>&infin</sub> = ',... -0141 sprintf('%4.3e',sum(E0)),... -0142 ' &#8723 (',sprintf('%4.3e',ciE0s),')','</BODY></HTML>']; -0143 case 'T2' -0144 info{end+1,1} = ['<HTML><BODY>E<sub><font size="',num2str(subfs),'">0</sub> = ',... -0145 sprintf('%4.3e',sum(E0)),... -0146 ' &#8723 (',sprintf('%4.3e',ciE0s),')','</BODY></HTML>']; -0147 end -0148 info{end+1,1} = ' '; -0149 if isfield(invstd,'chi2') -0150 if ~isnan(invstd.chi2) -0151 str = ['&Chi<sup><font size="',num2str(subfs),'">2</sup> = ',sprintf('%4.2f',invstd.chi2)]; -0152 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; -0153 end -0154 end -0155 str = ['RMS = ',sprintf('%4.3e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; -0156 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; -0157 -0158 if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 -0159 info{end+1,1} = ['<HTML><BODY>S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'</BODY></HTML>']; -0160 end -0161 -0162 case {'LU','NNLS'} -0163 switch nmrproc.T1T2 -0164 case 'T1' -0165 info{end+1,1} = ['<HTML><BODY>E<sub>&infin</sub> = ',... -0166 sprintf('%4.3e',sum(invstd.E0)),'</BODY></HTML>']; -0167 case 'T2' -0168 info{end+1,1} = ['<HTML><BODY>E<sub><font size="',num2str(subfs),'">0</sub> = ',... -0169 sprintf('%4.3e',sum(invstd.E0)),'</BODY></HTML>']; -0170 end -0171 info{end+1,1} = ' '; -0172 if isfield(invstd,'chi2') -0173 if ~isnan(invstd.chi2) -0174 str = ['&Chi<sup><font size="',num2str(subfs),'">2</sup> = ',sprintf('%4.2f',invstd.chi2)]; -0175 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; -0176 end -0177 end -0178 str = ['RMS = ',sprintf('%4.3e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; -0179 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; -0180 -0181 if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 -0182 info{end+1,1} = ['<HTML><BODY>S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'</BODY></HTML>']; -0183 end -0184 -0185 info{end+1,1} = ['<HTML><BODY>&lambda = ',sprintf('%6.5f',invstd.lambda_out),'</BODY></HTML>']; -0186 info{end+1,1} = ' '; -0187 end -0188 end -0189 end -0190 -0191 case 2 % RAW -0192 if isfield(data,'results') -0193 % add filename & date information -0194 id = get(gui.listbox_handles.signal,'Value'); -0195 info{end+1,1} = data.import.NMR.filesShort{id}; -0196 info{end+1,1} = data.import.NMR.data{id}.date; -0197 info{end+1,1} = ' '; -0198 info{end+1,1} = ['<HTML><BODY>t_min &nbsp= ',... -0199 sprintf('%4.3e',data.results.nmrraw.t(1)),'</BODY></HTML>']; -0200 info{end+1,1} = ['<HTML><BODY>t_max &nbsp= ',... -0201 sprintf('%4.3e',data.results.nmrraw.t(end)),'</BODY></HTML>']; -0202 switch data.results.nmrproc.T1T2 -0203 case 'T1' -0204 info{end+1,1} = ' '; -0205 info{end+1,1} = ['<HTML><BODY>Sampl. = ',... -0206 sprintf('%d',length(data.results.nmrproc.t)),... -0207 '</BODY></HTML>']; -0208 case 'T2' -0209 info{end+1,1} = ['<HTML><BODY>t_echo = ',... -0210 sprintf('%4.3e',data.results.nmrproc.echotime),'</BODY></HTML>']; -0211 info{end+1,1} = ['<HTML><BODY>t_dead = ',... -0212 sprintf('%4.3e',data.results.nmrproc.dead),'</BODY></HTML>']; -0213 info{end+1,1} = ' '; -0214 info{end+1,1} = ['<HTML><BODY>Echos &nbsp= ',... -0215 sprintf('%d',length(data.results.nmrraw.t)),... -0216 '</BODY></HTML>']; -0217 end -0218 if max(data.results.nmrproc.s) < 1e-3 -0219 info{end+1,1} = ['<HTML><BODY>A_max &nbsp= ',... -0220 sprintf('%4.3e',max(data.results.nmrproc.s)),... -0221 '</BODY></HTML>']; -0222 else -0223 info{end+1,1} = ['<HTML><BODY>A_max &nbsp= ',... -0224 sprintf('%5.4f',max(data.results.nmrproc.s)),... -0225 '</BODY></HTML>']; -0226 end +0131 % if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 +0132 if nmrproc.noise ~= 0 +0133 info{end+1,1} = ['<HTML><BODY>S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'</BODY></HTML>']; +0134 end +0135 +0136 case 'free' +0137 ciE0s = sum(full(invstd.ci(1:2:end))); +0138 E0 = invstd.E0; +0139 switch nmrproc.T1T2 +0140 case 'T1' +0141 info{end+1,1} = ['<HTML><BODY>E<sub>&infin</sub> = ',... +0142 sprintf('%4.2e',sum(E0)),... +0143 ' &#8723 (',sprintf('%4.2e',ciE0s),')','</BODY></HTML>']; +0144 case 'T2' +0145 info{end+1,1} = ['<HTML><BODY>E<sub><font size="',num2str(subfs),'">0</sub> = ',... +0146 sprintf('%4.2e',sum(E0)),... +0147 ' &#8723 (',sprintf('%4.2e',ciE0s),')','</BODY></HTML>']; +0148 end +0149 info{end+1,1} = ' '; +0150 if isfield(invstd,'chi2') +0151 if ~isnan(invstd.chi2) +0152 str = ['&Chi<sup><font size="',num2str(subfs),'">2</sup> = ',sprintf('%4.2f',invstd.chi2)]; +0153 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; +0154 end +0155 end +0156 str = ['RMS = ',sprintf('%4.2e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; +0157 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; +0158 +0159 % if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 +0160 if nmrproc.noise ~= 0 +0161 info{end+1,1} = ['<HTML><BODY>S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'</BODY></HTML>']; +0162 end +0163 +0164 case {'LU','NNLS'} +0165 switch nmrproc.T1T2 +0166 case 'T1' +0167 info{end+1,1} = ['<HTML><BODY>E<sub>&infin</sub> = ',... +0168 sprintf('%4.2e',sum(invstd.E0)),'</BODY></HTML>']; +0169 case 'T2' +0170 info{end+1,1} = ['<HTML><BODY>E<sub><font size="',num2str(subfs),'">0</sub> = ',... +0171 sprintf('%4.2e',sum(invstd.E0)),'</BODY></HTML>']; +0172 end +0173 info{end+1,1} = ' '; +0174 if isfield(invstd,'chi2') +0175 if ~isnan(invstd.chi2) +0176 str = ['&Chi<sup><font size="',num2str(subfs),'">2</sup> = ',sprintf('%4.2f',invstd.chi2)]; +0177 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; +0178 end +0179 end +0180 str = ['RMS = ',sprintf('%4.2e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; +0181 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; +0182 +0183 % if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 +0184 if nmrproc.noise ~= 0 +0185 info{end+1,1} = ['<HTML><BODY>S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'</BODY></HTML>']; +0186 end +0187 +0188 info{end+1,1} = ['<HTML><BODY>&lambda = ',sprintf('%6.5f',invstd.lambda_out),'</BODY></HTML>']; +0189 info{end+1,1} = ' '; +0190 case {'MUMO'} +0191 switch nmrproc.T1T2 +0192 case 'T1' +0193 info{end+1,1} = ['<HTML><BODY>E<sub>&infin</sub> = ',... +0194 sprintf('%4.2e',sum(invstd.E0)),... +0195 ' &#8723 (',sprintf('%4.2e',invstd.ciE0),')','</BODY></HTML>']; +0196 case 'T2' +0197 info{end+1,1} = ['<HTML><BODY>E<sub><font size="',num2str(subfs),'">0</sub> = ',... +0198 sprintf('%4.2e',sum(invstd.E0)),... +0199 ' &#8723 (',sprintf('%4.2e',invstd.ciE0),')','</BODY></HTML>']; +0200 end +0201 info{end+1,1} = ' '; +0202 +0203 if isfield(invstd,'chi2') +0204 if ~isnan(invstd.chi2) +0205 str = ['&Chi<sup><font size="',num2str(subfs),'">2</sup> = ',sprintf('%4.2f',invstd.chi2)]; +0206 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; +0207 end +0208 end +0209 str = ['RMS = ',sprintf('%4.2e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; +0210 info{end+1,1} = ['<HTML><BODY>',str,'</BODY></HTML>']; +0211 +0212 % if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 +0213 if nmrproc.noise ~= 0 +0214 info{end+1,1} = ['<HTML><BODY>S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'</BODY></HTML>']; +0215 end +0216 info{end+1,1} = ' '; +0217 end +0218 end +0219 end +0220 +0221 case 2 % RAW +0222 if isfield(data,'results') +0223 % add filename & date information +0224 id = get(gui.listbox_handles.signal,'Value'); +0225 info{end+1,1} = data.import.NMR.filesShort{id}; +0226 info{end+1,1} = data.import.NMR.data{id}.date; 0227 info{end+1,1} = ' '; -0228 -0229 if isfield(data.import,'BAM') -0230 a = data.import.NMR.data{id}.phase_bam; -0231 info{end+1,1} = ['<HTML><BODY>phase TOM&nbsp= ',... -0232 sprintf('%5.2f',rad2deg(a)),... -0233 '°</BODY></HTML>']; -0234 end -0235 info{end+1,1} = ['<HTML><BODY>phase fit&nbsp= ',... -0236 sprintf('%5.2f',rad2deg(data.results.nmrraw.phase)),... -0237 '°</BODY></HTML>']; -0238 info{end+1,1} = ' '; -0239 end -0240 -0241 case 3 % ALL -0242 if isfield(data,'results') -0243 if isfield(data.results,'invjoint') -0244 invjoint = data.results.invjoint; -0245 nmr = invjoint.idata.nmr; -0246 levels = invjoint.levels; -0247 -0248 % global fit error -0249 info{end+1,1} = ['ErrNorm: ',sprintf('%4.3e',invjoint.errnorm)]; -0250 info{end+1,1} = ['RMS: ',sprintf('%4.3e',invjoint.rms)]; -0251 info{end+1,1} = ['<HTML><BODY>&Chi<sup><font size="',num2str(subfs),'">2</sup>: ',... -0252 sprintf('%5.4f',invjoint.chi2),'</BODY></HTML>']; -0253 info{end+1,1} = ' '; -0254 info{end+1,1} = '-----'; -0255 info{end+1,1} = ' '; -0256 -0257 for i = 1:numel(levels) -0258 info{end+1,1} = nmr{levels(i)}.name; -0259 info{end+1,1} = ['RMS: ',sprintf('%4.3e',nmr{levels(i)}.rms)]; -0260 info{end+1,1} = ['<HTML><BODY>&Chi<sup><font size="',num2str(subfs),'">2</sup>: ',... -0261 sprintf('%5.4f',nmr{levels(i)}.chi2),'</BODY></HTML>']; -0262 info{end+1,1} = ' '; -0263 end +0228 info{end+1,1} = ['<HTML><BODY>t_min &nbsp= ',... +0229 sprintf('%4.3e',data.results.nmrraw.t(1)),'</BODY></HTML>']; +0230 info{end+1,1} = ['<HTML><BODY>t_max &nbsp= ',... +0231 sprintf('%4.3e',data.results.nmrraw.t(end)),'</BODY></HTML>']; +0232 switch data.results.nmrproc.T1T2 +0233 case 'T1' +0234 info{end+1,1} = ' '; +0235 info{end+1,1} = ['<HTML><BODY>Sampl. = ',... +0236 sprintf('%d',length(data.results.nmrproc.t)),... +0237 '</BODY></HTML>']; +0238 case 'T2' +0239 info{end+1,1} = ['<HTML><BODY>t_echo = ',... +0240 sprintf('%4.3e',data.results.nmrproc.echotime),'</BODY></HTML>']; +0241 info{end+1,1} = ['<HTML><BODY>t_dead = ',... +0242 sprintf('%4.3e',data.results.nmrproc.dead),'</BODY></HTML>']; +0243 info{end+1,1} = ' '; +0244 info{end+1,1} = ['<HTML><BODY>Echos &nbsp= ',... +0245 sprintf('%d',length(data.results.nmrraw.t)),... +0246 '</BODY></HTML>']; +0247 end +0248 if max(data.results.nmrproc.s) < 1e-3 +0249 info{end+1,1} = ['<HTML><BODY>A_max &nbsp= ',... +0250 sprintf('%4.3e',max(data.results.nmrproc.s)),... +0251 '</BODY></HTML>']; +0252 else +0253 info{end+1,1} = ['<HTML><BODY>A_max &nbsp= ',... +0254 sprintf('%5.4f',max(data.results.nmrproc.s)),... +0255 '</BODY></HTML>']; +0256 end +0257 info{end+1,1} = ' '; +0258 +0259 if isfield(data.import,'BAM') +0260 a = data.import.NMR.data{id}.phase_bam; +0261 info{end+1,1} = ['<HTML><BODY>phase TOM&nbsp= ',... +0262 sprintf('%5.2f',rad2deg(a)),... +0263 '°</BODY></HTML>']; 0264 end -0265 end -0266 end -0267 % and update the text box -0268 set(gui.listbox_handles.info_signal,'String',info,'Value',[],'Max',2,'Min',0); -0269 -0270 %% RTD panel info -0271 clear info; -0272 info{1,1} = ' '; -0273 switch whichdist -0274 case 1 % RTD -0275 if isfield(data,'results') -0276 if isfield(data.results,'invstd') -0277 nmrproc = data.results.nmrproc; -0278 invstd = data.results.invstd; -0279 invtype = data.invstd.invtype; -0280 -0281 switch invtype -0282 case 'mono' -0283 info{end+1,1} = invtype; -0284 info{end+1,1} = ' '; -0285 ciT = sum(full(invstd.ci(2:2:end))); -0286 -0287 switch nmrproc.T1T2 -0288 case 'T1' -0289 info{end+1,1} = ['<HTML><BODY>T<sub><font size="',num2str(subfs),'">1</sub> = ',... -0290 sprintf('%5.4f',invstd.T1),... -0291 ' &#8723 (',sprintf('%5.4f',ciT),')','</BODY></HTML>']; -0292 case 'T2' -0293 info{end+1,1} = ['<HTML><BODY>T<sub><font size="',num2str(subfs),'">2</sub> = ',... -0294 sprintf('%5.4f',invstd.T2),... -0295 ' &#8723 (',sprintf('%5.4f',ciT),')','</BODY></HTML>']; -0296 end -0297 info{end+1,1} = ' '; -0298 -0299 case 'free' -0300 str = [invtype,' ',num2str(data.invstd.freeDT)]; -0301 info{end+1,1} = str; -0302 info{end+1,1} = ' '; -0303 -0304 E0 = invstd.E0; -0305 ciE0 = full(invstd.ci(1:2:end)); -0306 ciT = full(invstd.ci(2:2:end)); -0307 -0308 switch nmrproc.T1T2 -0309 case 'T1' -0310 T = invstd.T1; -0311 case 'T2' -0312 T = invstd.T2; -0313 end -0314 -0315 for i = 1:length(T) -0316 info{end+1,1} = ['<HTML><BODY>T(',num2str(i),') = ',sprintf('%5.4f',T(i)),... -0317 ' &#8723 (',sprintf('%5.4f',ciT(i)),')','</BODY></HTML>']; %#ok<*AGROW> -0318 info{end+1,1} = ['<HTML><BODY>E(',num2str(i),') = ',sprintf('%5.4f',E0(i)),... -0319 ' &#8723 (',sprintf('%5.4f',ciE0(i)),')','</BODY></HTML>']; -0320 end -0321 info{end+1,1} = ' '; -0322 -0323 case {'LU','NNLS'} -0324 % info is a cell array -0325 str = [invtype,' ',data.invstd.regtype,' ',num2str(data.invstd.Lorder)]; -0326 info{end+1,1} = str; -0327 info{end+1,1} = ' '; -0328 -0329 % TLGM -0330 info{end+1,1} = ['<HTML><BODY>TLGM</sub> = ',sprintf('%5.4f',invstd.Tlgm),'</BODY></HTML>']; -0331 info{end+1,1} = ' '; -0332 -0333 % clay-bound water CBW < tcut ms -0334 % irreducible water / capillary water BVI ccut - tcut ms -0335 % movable water BVM > tcut ms -0336 switch data.process.timescale -0337 case 's' -0338 ccut = data.param.CBWcutoff/1000; -0339 tcut = data.param.BVIcutoff/1000; -0340 case 'ms' -0341 ccut = data.param.CBWcutoff; -0342 tcut = data.param.BVIcutoff; -0343 end -0344 por = data.invstd.porosity; -0345 CBW = abs(sum(invstd.T1T2f(invstd.T1T2me<=ccut))/sum(invstd.T1T2f)); -0346 BVI = abs(sum(invstd.T1T2f(invstd.T1T2me>ccut & invstd.T1T2me<=tcut))/sum(invstd.T1T2f)); -0347 BVM = abs(sum(invstd.T1T2f(invstd.T1T2me>tcut))/sum(invstd.T1T2f)); -0348 info{end+1,1} = ['CBW(',sprintf('%2d',data.param.CBWcutoff),... -0349 ') = ',sprintf('%5.2f',por*CBW*100),' [vol. %]']; -0350 -0351 info{end+1,1} = ['BVI(',sprintf('%2d',data.param.BVIcutoff),... -0352 ') = ',sprintf('%5.2f',por*BVI*100),' [vol. %]']; -0353 info{end+1,1} = ['BVM = ',sprintf('%5.2f',por*BVM*100),' [vol. %]']; +0265 if isfield(data.results.nmrraw,'phase') +0266 info{end+1,1} = ['<HTML><BODY>phase fit&nbsp= ',... +0267 sprintf('%5.2f',rad2deg(data.results.nmrraw.phase)),... +0268 '°</BODY></HTML>']; +0269 end +0270 info{end+1,1} = ' '; +0271 end +0272 +0273 case 3 % ALL +0274 if isfield(data,'results') +0275 if isfield(data.results,'invjoint') +0276 invjoint = data.results.invjoint; +0277 nmr = invjoint.idata.nmr; +0278 levels = invjoint.levels; +0279 +0280 % global fit error +0281 info{end+1,1} = ['ErrNorm: ',sprintf('%4.3e',invjoint.errnorm)]; +0282 info{end+1,1} = ['RMS: ',sprintf('%4.3e',invjoint.rms)]; +0283 info{end+1,1} = ['<HTML><BODY>&Chi<sup><font size="',num2str(subfs),'">2</sup>: ',... +0284 sprintf('%5.4f',invjoint.chi2),'</BODY></HTML>']; +0285 info{end+1,1} = ' '; +0286 info{end+1,1} = '-----'; +0287 info{end+1,1} = ' '; +0288 +0289 for i = 1:numel(levels) +0290 info{end+1,1} = nmr{levels(i)}.name; +0291 info{end+1,1} = ['RMS: ',sprintf('%4.3e',nmr{levels(i)}.rms)]; +0292 info{end+1,1} = ['<HTML><BODY>&Chi<sup><font size="',num2str(subfs),'">2</sup>: ',... +0293 sprintf('%5.4f',nmr{levels(i)}.chi2),'</BODY></HTML>']; +0294 info{end+1,1} = ' '; +0295 end +0296 end +0297 end +0298 end +0299 % and update the text box +0300 set(gui.listbox_handles.info_signal,'String',info,'Value',[],'Max',2,'Min',0); +0301 +0302 %% RTD panel info +0303 clear info; +0304 info{1,1} = ' '; +0305 switch whichdist +0306 case 1 % RTD +0307 if isfield(data,'results') +0308 if isfield(data.results,'invstd') +0309 nmrproc = data.results.nmrproc; +0310 invstd = data.results.invstd; +0311 invtype = data.invstd.invtype; +0312 +0313 switch invtype +0314 case 'mono' +0315 info{end+1,1} = invtype; +0316 info{end+1,1} = ' '; +0317 ciT = sum(full(invstd.ci(2:2:end))); +0318 +0319 switch nmrproc.T1T2 +0320 case 'T1' +0321 info{end+1,1} = ['<HTML><BODY>T<sub><font size="',num2str(subfs),'">1</sub> = ',... +0322 sprintf('%5.4f',invstd.T1),... +0323 ' &#8723 (',sprintf('%5.4f',ciT),')','</BODY></HTML>']; +0324 case 'T2' +0325 info{end+1,1} = ['<HTML><BODY>T<sub><font size="',num2str(subfs),'">2</sub> = ',... +0326 sprintf('%5.4f',invstd.T2),... +0327 ' &#8723 (',sprintf('%5.4f',ciT),')','</BODY></HTML>']; +0328 end +0329 info{end+1,1} = ' '; +0330 +0331 case 'free' +0332 str = [invtype,' ',num2str(data.invstd.freeDT)]; +0333 info{end+1,1} = str; +0334 info{end+1,1} = ' '; +0335 +0336 E0 = invstd.E0; +0337 ciE0 = full(invstd.ci(1:2:end)); +0338 ciT = full(invstd.ci(2:2:end)); +0339 +0340 switch nmrproc.T1T2 +0341 case 'T1' +0342 T = invstd.T1; +0343 case 'T2' +0344 T = invstd.T2; +0345 end +0346 +0347 for i = 1:length(T) +0348 info{end+1,1} = ['<HTML><BODY>T(',num2str(i),') = ',sprintf('%5.4f',T(i)),... +0349 ' &#8723 (',sprintf('%5.4f',ciT(i)),')','</BODY></HTML>']; %#ok<*AGROW> +0350 info{end+1,1} = ['<HTML><BODY>E(',num2str(i),') = ',sprintf('%5.4f',E0(i)),... +0351 ' &#8723 (',sprintf('%5.4f',ciE0(i)),')','</BODY></HTML>']; +0352 info{end+1,1} = ' '; +0353 end 0354 -0355 end -0356 end -0357 end -0358 -0359 case 2 % PSD -0360 info{end+1,1} = 'PSD'; -0361 info{end+1,1} = ' '; -0362 -0363 case 3 % PSDJ -0364 if isfield(data,'results') -0365 if isfield(data.results,'invjoint') -0366 invjoint = data.results.invjoint; -0367 -0368 info{end+1,1} = ['Inversion type: ',data.invjoint.invtype]; -0369 info{end+1,1} = ' '; -0370 switch data.invjoint.geometry_type -0371 case 'cyl' -0372 info{end+1,1} = ['Shape: ',data.invjoint.geometry_type]; -0373 info{end+1,1} = ['Geom.: ',sprintf('%4.2f',invjoint.iGEOM.a)]; -0374 case 'ang' -0375 info{end+1,1} = ['Shape: ',data.invjoint.geometry_type,' ',... -0376 num2str(invjoint.iGEOM.angles(1)),' ',... -0377 num2str(invjoint.iGEOM.angles(2)),' ',... -0378 num2str(invjoint.iGEOM.angles(3))]; -0379 info{end+1,1} = ['Geom.: ',sprintf('%4.2f',invjoint.iGEOM.a)]; -0380 case 'poly' -0381 info{end+1,1} = ['Shape: ',data.invjoint.geometry_type,... -0382 ' ',num2str(data.invjoint.polyN),' sides']; -0383 info{end+1,1} = ['Geom.: ',sprintf('%4.2f',invjoint.iGEOM.a)]; -0384 end -0385 info{end+1,1} = ' '; -0386 info{end+1,1} = ['rho (INV): ',sprintf('%5.3f',invjoint.irho*1e6),' [µm/s]']; -0387 if isfield(data.import,'NMRMOD') -0388 info{end+1,1} = ['rho (MOD): ',... -0389 sprintf('%5.3f',data.import.NMRMOD.nmr.rho*1e6),' [µm/s]']; -0390 end -0391 end -0392 end -0393 end -0394 % and update the text box -0395 set(gui.listbox_handles.info_dist,'String',info,'Value',[],'Max',2,'Min',0); -0396 -0397 %% CPS panel info -0398 % check if the CPS panel is maximized -0399 isminimized = get(gui.plots.CPSPanel,'Minimized'); -0400 if ~isminimized -0401 clear info; -0402 info{1,1} = ' '; -0403 if isfield(data,'results') -0404 if isfield(data.results,'invjoint') -0405 invjoint = data.results.invjoint; -0406 nmr = invjoint.idata.nmr; -0407 levels = invjoint.levels; -0408 -0409 for i = 1:numel(levels) -0410 info{end+1,1} = nmr{levels(i)}.name; -0411 info{end+1,1} = ['press. : ',... -0412 sprintf('%5.4f',invjoint.p0(levels(i))*data.pressure.unitfac),... -0413 ' [',data.pressure.unit,']']; -0414 switch invjoint.T1T2 -0415 case 'T1' -0416 info{end+1,1} = ['sat. (INV) : ',... -0417 sprintf('%4.2f',invjoint.idata.nmr{levels(i)}.fit_g(end))]; -0418 case 'T2' -0419 info{end+1,1} = ['sat. (INV) : ',... -0420 sprintf('%4.2f',invjoint.idata.nmr{levels(i)}.fit_g(1))]; -0421 end -0422 info{end+1,1} = ['sat. (MOD) : ',... -0423 sprintf('%4.2f',invjoint.S0(levels(i)))]; -0424 info{end+1,1} = ' '; -0425 end -0426 end -0427 end -0428 set(gui.listbox_handles.info_cps,'String',info,'Value',[],'Max',2,'Min',0); -0429 end -0430 -0431 % update GUI data -0432 setappdata(fig,'data',data); -0433 setappdata(fig,'gui',gui); -0434 end -0435 -0436 end -0437 -0438 %------------- END OF CODE -------------- -0439 -0440 %% License: -0441 % MIT License -0442 % -0443 % Copyright (c) 2018 Thomas Hiller -0444 % -0445 % Permission is hereby granted, free of charge, to any person obtaining a copy -0446 % of this software and associated documentation files (the "Software"), to deal -0447 % in the Software without restriction, including without limitation the rights -0448 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0449 % copies of the Software, and to permit persons to whom the Software is -0450 % furnished to do so, subject to the following conditions: -0451 % -0452 % The above copyright notice and this permission notice shall be included in all -0453 % copies or substantial portions of the Software. -0454 % -0455 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0456 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0457 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0458 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0459 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0460 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0461 % SOFTWARE. +0355 case {'LU','NNLS'} +0356 % info is a cell array +0357 str = [invtype,' ',data.invstd.regtype,' ',num2str(data.invstd.Lorder)]; +0358 info{end+1,1} = str; +0359 info{end+1,1} = ' '; +0360 +0361 % TLGM +0362 info{end+1,1} = ['<HTML><BODY>TLGM</sub> = ',sprintf('%5.4f',invstd.Tlgm),'</BODY></HTML>']; +0363 info{end+1,1} = ' '; +0364 +0365 % clay-bound water CBW < tcut ms +0366 % irreducible water / capillary water BVI ccut - tcut ms +0367 % movable water BVM > tcut ms +0368 switch data.process.timescale +0369 case 's' +0370 ccut = data.param.CBWcutoff/1000; +0371 tcut = data.param.BVIcutoff/1000; +0372 case 'ms' +0373 ccut = data.param.CBWcutoff; +0374 tcut = data.param.BVIcutoff; +0375 end +0376 por = data.invstd.porosity; +0377 CBW = abs(sum(invstd.T1T2f(invstd.T1T2me<=ccut))/sum(invstd.T1T2f)); +0378 BVI = abs(sum(invstd.T1T2f(invstd.T1T2me>ccut & invstd.T1T2me<=tcut))/sum(invstd.T1T2f)); +0379 BVM = abs(sum(invstd.T1T2f(invstd.T1T2me>tcut))/sum(invstd.T1T2f)); +0380 info{end+1,1} = ['CBW(',sprintf('%2d',data.param.CBWcutoff),... +0381 ') = ',sprintf('%5.2f',por*CBW*100),' [vol. %]']; +0382 +0383 info{end+1,1} = ['BVI(',sprintf('%2d',data.param.BVIcutoff),... +0384 ') = ',sprintf('%5.2f',por*BVI*100),' [vol. %]']; +0385 info{end+1,1} = ['BVM = ',sprintf('%5.2f',por*BVM*100),' [vol. %]']; +0386 +0387 case {'MUMO'} +0388 +0389 % info is a cell array +0390 str = [invtype,' ',num2str(data.invstd.freeDT)]; +0391 info{end+1,1} = str; +0392 info{end+1,1} = ' '; +0393 +0394 % TLGM +0395 info{end+1,1} = ['<HTML><BODY>TLGM</sub> = ',sprintf('%5.4f',invstd.Tlgm),'</BODY></HTML>']; +0396 info{end+1,1} = ' '; +0397 +0398 % clay-bound water CBW < tcut ms +0399 % irreducible water / capillary water BVI ccut - tcut ms +0400 % movable water BVM > tcut ms +0401 switch data.process.timescale +0402 case 's' +0403 ccut = data.param.CBWcutoff/1000; +0404 tcut = data.param.BVIcutoff/1000; +0405 case 'ms' +0406 ccut = data.param.CBWcutoff; +0407 tcut = data.param.BVIcutoff; +0408 end +0409 por = data.invstd.porosity; +0410 CBW = abs(sum(invstd.T1T2f(invstd.T1T2me<=ccut))/sum(invstd.T1T2f)); +0411 BVI = abs(sum(invstd.T1T2f(invstd.T1T2me>ccut & invstd.T1T2me<=tcut))/sum(invstd.T1T2f)); +0412 BVM = abs(sum(invstd.T1T2f(invstd.T1T2me>tcut))/sum(invstd.T1T2f)); +0413 info{end+1,1} = ['CBW(',sprintf('%2d',data.param.CBWcutoff),... +0414 ') = ',sprintf('%5.2f',por*CBW*100),' [vol. %]']; +0415 +0416 info{end+1,1} = ['BVI(',sprintf('%2d',data.param.BVIcutoff),... +0417 ') = ',sprintf('%5.2f',por*BVI*100),' [vol. %]']; +0418 info{end+1,1} = ['BVM = ',sprintf('%5.2f',por*BVM*100),' [vol. %]']; +0419 info{end+1,1} = ' '; +0420 +0421 % values for T, sigma and amplitude +0422 T = invstd.T; ciT = invstd.ci(1:3:end); +0423 S = invstd.S; ciS = invstd.ci(2:3:end); +0424 E = invstd.E; ciE = invstd.ci(3:3:end); +0425 % transform ciT because it is in log scale +0426 tmpT = log(T)-ciT'; +0427 ciT = T - exp(tmpT); +0428 +0429 for i = 1:length(T) +0430 info{end+1,1} = ['<HTML><BODY>T(',num2str(i),') = ',sprintf('%5.4f',T(i)),... +0431 ' &#8723 (',sprintf('%5.4f',ciT(i)),')','</BODY></HTML>']; %#ok<*AGROW> +0432 info{end+1,1} = ['<HTML><BODY>S(',num2str(i),') = ',sprintf('%5.4f',S(i)),... +0433 ' &#8723 (',sprintf('%5.4f',ciS(i)),')','</BODY></HTML>']; +0434 info{end+1,1} = ['<HTML><BODY>E(',num2str(i),') = ',sprintf('%5.4f',E(i)),... +0435 ' &#8723 (',sprintf('%5.4f',ciE(i)),')','</BODY></HTML>']; +0436 info{end+1,1} = ' '; +0437 end +0438 end +0439 end +0440 end +0441 +0442 case 2 % PSD +0443 info{end+1,1} = 'PSD'; +0444 info{end+1,1} = ' '; +0445 +0446 case 3 % PSDJ +0447 if isfield(data,'results') +0448 if isfield(data.results,'invjoint') +0449 invjoint = data.results.invjoint; +0450 +0451 info{end+1,1} = ['Inversion type: ',data.invjoint.invtype]; +0452 info{end+1,1} = ' '; +0453 switch data.invjoint.geometry_type +0454 case 'cyl' +0455 info{end+1,1} = ['Shape: ',data.invjoint.geometry_type]; +0456 info{end+1,1} = ['Geom.: ',sprintf('%4.2f',invjoint.iGEOM.a)]; +0457 case 'ang' +0458 info{end+1,1} = ['Shape: ',data.invjoint.geometry_type,' ',... +0459 num2str(invjoint.iGEOM.angles(1)),' ',... +0460 num2str(invjoint.iGEOM.angles(2)),' ',... +0461 num2str(invjoint.iGEOM.angles(3))]; +0462 info{end+1,1} = ['Geom.: ',sprintf('%4.2f',invjoint.iGEOM.a)]; +0463 case 'poly' +0464 info{end+1,1} = ['Shape: ',data.invjoint.geometry_type,... +0465 ' ',num2str(data.invjoint.polyN),' sides']; +0466 info{end+1,1} = ['Geom.: ',sprintf('%4.2f',invjoint.iGEOM.a)]; +0467 end +0468 info{end+1,1} = ' '; +0469 info{end+1,1} = ['rho (INV): ',sprintf('%5.3f',invjoint.irho*1e6),' [µm/s]']; +0470 if isfield(data.import,'NMRMOD') +0471 info{end+1,1} = ['rho (MOD): ',... +0472 sprintf('%5.3f',data.import.NMRMOD.nmr.rho*1e6),' [µm/s]']; +0473 end +0474 end +0475 end +0476 end +0477 % and update the text box +0478 set(gui.listbox_handles.info_dist,'String',info,'Value',[],'Max',2,'Min',0); +0479 +0480 %% CPS panel info +0481 % check if the CPS panel is maximized +0482 isminimized = get(gui.plots.CPSPanel,'Minimized'); +0483 if ~isminimized +0484 clear info; +0485 info{1,1} = ' '; +0486 if isfield(data,'results') +0487 if isfield(data.results,'invjoint') +0488 invjoint = data.results.invjoint; +0489 nmr = invjoint.idata.nmr; +0490 levels = invjoint.levels; +0491 +0492 for i = 1:numel(levels) +0493 info{end+1,1} = nmr{levels(i)}.name; +0494 info{end+1,1} = ['press. : ',... +0495 sprintf('%5.4f',invjoint.p0(levels(i))*data.pressure.unitfac),... +0496 ' [',data.pressure.unit,']']; +0497 switch invjoint.T1T2 +0498 case 'T1' +0499 info{end+1,1} = ['sat. (INV) : ',... +0500 sprintf('%4.2f',invjoint.idata.nmr{levels(i)}.fit_g(end))]; +0501 case 'T2' +0502 info{end+1,1} = ['sat. (INV) : ',... +0503 sprintf('%4.2f',invjoint.idata.nmr{levels(i)}.fit_g(1))]; +0504 end +0505 info{end+1,1} = ['sat. (MOD) : ',... +0506 sprintf('%4.2f',invjoint.S0(levels(i)))]; +0507 info{end+1,1} = ' '; +0508 end +0509 end +0510 end +0511 set(gui.listbox_handles.info_cps,'String',info,'Value',[],'Max',2,'Min',0); +0512 end +0513 +0514 % update GUI data +0515 setappdata(fig,'data',data); +0516 setappdata(fig,'gui',gui); +0517 end +0518 +0519 end +0520 +0521 %------------- END OF CODE -------------- +0522 +0523 %% License: +0524 % MIT License +0525 % +0526 % Copyright (c) 2018 Thomas Hiller +0527 % +0528 % Permission is hereby granted, free of charge, to any person obtaining a copy +0529 % of this software and associated documentation files (the "Software"), to deal +0530 % in the Software without restriction, including without limitation the rights +0531 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0532 % copies of the Software, and to permit persons to whom the Software is +0533 % furnished to do so, subject to the following conditions: +0534 % +0535 % The above copyright notice and this permission notice shall be included in all +0536 % copies or substantial portions of the Software. +0537 % +0538 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0539 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0540 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0541 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0542 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0543 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0544 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/updateNMRsignals.html b/doc/nucleus/functions/interface/updateNMRsignals.html index d760015..6f26e6f 100644 --- a/doc/nucleus/functions/interface/updateNMRsignals.html +++ b/doc/nucleus/functions/interface/updateNMRsignals.html @@ -43,6 +43,7 @@

    DESCRIPTION ^DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • updatePlotsNMR plots the forward modeled NMR data in NUCLEUSmod
  • addNoiseToSignal adds noise with mean 'mu' and standard deviation 'sigma' to
  • This function is called by:
      -
    • onEditValue updates all edit field values, checks for wrong inputs and
    • calculateNMR calculates the NMR signals for the full and partially saturated
    +
  • onEditValue updates all edit field values, checks for wrong inputs and
  • onPopupNMRNoiseType selects the noise type to be aplied to the forward
  • calculateNMR calculates the NMR signals for the full and partially saturated
  • @@ -86,80 +87,108 @@

    SOURCE CODE ^% 0017 % Other m-files required: 0018 % addNoiseToSignal -0019 % -0020 % Subfunctions: -0021 % none -0022 % -0023 % MAT-files required: -0024 % none -0025 % -0026 % See also: NUCLEUSmod -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de -0029 % License: MIT License (at end) -0030 -0031 %------------- BEGIN CODE -------------- -0032 -0033 %% get GUI handle and data -0034 fig = findobj('Tag','MOD'); -0035 data = getappdata(fig,'data'); -0036 -0037 %% only proceed if the noise is larger than 0 -0038 if data.nmr.noise > 0 -0039 % scale noise by porosity -0040 noise = data.nmr.noise/data.nmr.porosity; -0041 % add noise to NMR signals -0042 [data.results.NMR.EiT1,~] = addNoiseToSignal(data.results.NMR.raw.EiT1,0,noise); -0043 [data.results.NMR.EdT1,~] = addNoiseToSignal(data.results.NMR.raw.EdT1,0,noise); -0044 [data.results.NMR.EiT2,~] = addNoiseToSignal(data.results.NMR.raw.EiT2,0,noise); -0045 [data.results.NMR.EdT2,~] = addNoiseToSignal(data.results.NMR.raw.EdT2,0,noise); -0046 else -0047 % reset the NMR signals with the raw data (without noise) -0048 data.results.NMR.EiT1 = data.results.NMR.raw.EiT1; -0049 data.results.NMR.EdT1 = data.results.NMR.raw.EdT1; -0050 data.results.NMR.EiT2 = data.results.NMR.raw.EiT2; -0051 data.results.NMR.EdT2 = data.results.NMR.raw.EdT2; -0052 end -0053 -0054 % scale NMR signals by porosity -0055 data.results.NMR.EiT1 = data.nmr.porosity.*data.results.NMR.EiT1; -0056 data.results.NMR.EdT1 = data.nmr.porosity.*data.results.NMR.EdT1; -0057 data.results.NMR.EiT2 = data.nmr.porosity.*data.results.NMR.EiT2; -0058 data.results.NMR.EdT2 = data.nmr.porosity.*data.results.NMR.EdT2; -0059 -0060 % save the noise value -0061 data.results.NMR.noise = data.nmr.noise; -0062 % save the porosity value -0063 data.results.NMR.porosity = data.nmr.porosity; -0064 % update the GUI data -0065 setappdata(fig,'data',data); -0066 -0067 end -0068 -0069 %------------- END OF CODE -------------- -0070 -0071 %% License: -0072 % MIT License -0073 % -0074 % Copyright (c) 2018 Thomas Hiller -0075 % -0076 % Permission is hereby granted, free of charge, to any person obtaining a copy -0077 % of this software and associated documentation files (the "Software"), to deal -0078 % in the Software without restriction, including without limitation the rights -0079 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0080 % copies of the Software, and to permit persons to whom the Software is -0081 % furnished to do so, subject to the following conditions: -0082 % -0083 % The above copyright notice and this permission notice shall be included in all -0084 % copies or substantial portions of the Software. -0085 % -0086 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0087 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0088 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0089 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0090 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0091 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0092 % SOFTWARE. +0019 % updatePlotsNMR +0020 % +0021 % Subfunctions: +0022 % none +0023 % +0024 % MAT-files required: +0025 % none +0026 % +0027 % See also: NUCLEUSmod +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md +0030 % License: MIT License (at end) +0031 +0032 %------------- BEGIN CODE -------------- +0033 +0034 %% get GUI handle and data +0035 fig = findobj('Tag','MOD'); +0036 data = getappdata(fig,'data'); +0037 +0038 %% first check what is the noise type +0039 +0040 switch data.nmr.noisetype +0041 case 'level' +0042 noise = data.nmr.noise; +0043 case 'SNR' +0044 SNR = data.nmr.noise; +0045 noise = 1./SNR; +0046 end +0047 +0048 %% only proceed if the noise is larger than 0 +0049 if noise > 0 +0050 switch data.nmr.noisetype +0051 case 'level' +0052 % scale noise by porosity +0053 noise = noise/data.nmr.porosity; +0054 % add noise to NMR signals +0055 [data.results.NMR.EiT1,~] = addNoiseToSignal(data.results.NMR.raw.EiT1,0,noise); +0056 [data.results.NMR.EdT1,~] = addNoiseToSignal(data.results.NMR.raw.EdT1,0,noise); +0057 [data.results.NMR.EiT2,~] = addNoiseToSignal(data.results.NMR.raw.EiT2,0,noise); +0058 [data.results.NMR.EdT2,~] = addNoiseToSignal(data.results.NMR.raw.EdT2,0,noise); +0059 noiseM = noise*ones(size(data.results.NMR.EiT1,2),4); +0060 case 'SNR' +0061 SNR = data.nmr.noise; +0062 noiseM(:,1) = data.results.NMR.EiT1(:,end)./SNR; +0063 [data.results.NMR.EiT1,~] = addNoiseToSignal(data.results.NMR.raw.EiT1,0,noiseM(:,1)); +0064 noiseM(:,2) = data.results.NMR.EdT1(:,end)./SNR; +0065 [data.results.NMR.EdT1,~] = addNoiseToSignal(data.results.NMR.raw.EdT1,0,noiseM(:,2)); +0066 noiseM(:,3) = data.results.NMR.EiT2(:,1)./SNR; +0067 [data.results.NMR.EiT2,~] = addNoiseToSignal(data.results.NMR.raw.EiT2,0,noiseM(:,3)); +0068 noiseM(:,4) = data.results.NMR.EdT2(:,1)./SNR; +0069 [data.results.NMR.EdT2,~] = addNoiseToSignal(data.results.NMR.raw.EdT2,0,noiseM(:,4)); +0070 end +0071 else +0072 % reset the NMR signals with the raw data (without noise) +0073 data.results.NMR.EiT1 = data.results.NMR.raw.EiT1; +0074 data.results.NMR.EdT1 = data.results.NMR.raw.EdT1; +0075 data.results.NMR.EiT2 = data.results.NMR.raw.EiT2; +0076 data.results.NMR.EdT2 = data.results.NMR.raw.EdT2; +0077 noiseM = zeros(size(data.results.NMR.EiT1,2),4); +0078 end +0079 +0080 % scale NMR signals by porosity +0081 data.results.NMR.EiT1 = data.nmr.porosity.*data.results.NMR.EiT1; +0082 data.results.NMR.EdT1 = data.nmr.porosity.*data.results.NMR.EdT1; +0083 data.results.NMR.EiT2 = data.nmr.porosity.*data.results.NMR.EiT2; +0084 data.results.NMR.EdT2 = data.nmr.porosity.*data.results.NMR.EdT2; +0085 +0086 % save the noise matrix values +0087 data.results.NMR.noise = noiseM; +0088 % save the porosity value +0089 data.results.NMR.porosity = data.nmr.porosity; +0090 % update the GUI data +0091 setappdata(fig,'data',data); +0092 % update the NMR plot window +0093 updatePlotsNMR; +0094 +0095 end +0096 +0097 %------------- END OF CODE -------------- +0098 +0099 %% License: +0100 % MIT License +0101 % +0102 % Copyright (c) 2018 Thomas Hiller +0103 % +0104 % Permission is hereby granted, free of charge, to any person obtaining a copy +0105 % of this software and associated documentation files (the "Software"), to deal +0106 % in the Software without restriction, including without limitation the rights +0107 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0108 % copies of the Software, and to permit persons to whom the Software is +0109 % furnished to do so, subject to the following conditions: +0110 % +0111 % The above copyright notice and this permission notice shall be included in all +0112 % copies or substantial portions of the Software. +0113 % +0114 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0115 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0116 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0117 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0118 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0119 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0120 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/updatePlotsCPS.html b/doc/nucleus/functions/interface/updatePlotsCPS.html index abb38c1..8f86f96 100644 --- a/doc/nucleus/functions/interface/updatePlotsCPS.html +++ b/doc/nucleus/functions/interface/updatePlotsCPS.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updatePlotsDistribution.html b/doc/nucleus/functions/interface/updatePlotsDistribution.html index f90c2ac..8d920cd 100644 --- a/doc/nucleus/functions/interface/updatePlotsDistribution.html +++ b/doc/nucleus/functions/interface/updatePlotsDistribution.html @@ -50,8 +50,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=clearSingleAxis clears an individual axis
  • updatePlotsDistributionInfo plots cut-offs and diffusion regime lines
  • This function is called by: +
  • onContextPlotsPSD checks the label of the distribution axis context menu
  • onContextPlotsRTD checks the label of the distribution axis context menu
  • onEditValue updates all edit field values, checks for wrong inputs and
  • onListboxData handles the calls from the context menu of the data
  • calibratePorosity determines a sample's porosity from a calibration
  • changeColorTheme changes the color theme of the calling figure
  • runInversionStd controls the standard inversion process to invert a
  • SUBFUNCTIONS ^

    @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- @@ -149,233 +149,499 @@

    SOURCE CODE ^case 'free' 0080 mymark = {'o-','+-','s-','d-','x-'}; -0081 mycols = [22 140 75;22 87 140;140 22 87;140 75 22;64 64 64]./255; -0082 switch nmrproc.T1T2 -0083 case 'T1' -0084 T = invstd.T1; -0085 case 'T2' -0086 T = invstd.T2; -0087 end -0088 -0089 lgdstr = cell(1,1); -0090 for i = 1:data.invstd.freeDT -0091 stem(T(i),invstd.E0(i),mymark{i},'Color',mycols(i,:),'LineWidth',2,'Parent',ax); -0092 lgdstr{i} = ['T',num2str(i)]; -0093 end -0094 -0095 % limits -0096 ticks = floor(log10(min(T)))-2 :1: ceil(log10(max(T)))+2; -0097 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); -0098 set(ax,'YScale','lin','YLim',[0 max(invstd.E0)*1.05]); -0099 % labels -0100 set(get(ax,'XLabel'),'String',xlstring); -0101 set(get(ax,'YLabel'),'String','individual amplitudes Ex [-]'); -0102 % grid -0103 grid(ax,'on'); -0104 -0105 case {'LU','NNLS'} -0106 % scale distribution by porosity -0107 F = invstd.T1T2f; -0108 if sum(F)>0 -0109 F = (data.invstd.porosity*100).*F./sum(F); -0110 ylims = [0 max(F)*1.05]; -0111 else -0112 ylims = [-1 1]; -0113 end -0114 if data.invstd.porosity == 1 -0115 ylab1 = 'amplitudes [-]'; -0116 ylab2 = 'cumulative amplitudes [-]'; -0117 else -0118 ylab1 = 'water content [vol. %]'; -0119 ylab2 = 'cumulative water content [vol. %]'; -0120 end -0121 % F = data.invstd.porosity.*F./trapz(T,F); -0122 -0123 switch data.info.RTDflag -0124 case 'freq' -0125 plot(invstd.T1T2me,F,'o-','Color',col.FIT,... -0126 'LineWidth',2,'Parent',ax); -0127 % find approx. TLGM amplitude -0128 amp = findApproxTlgmAmplitude(invstd.T1T2me,F,invstd.Tlgm); -0129 stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... -0130 'LineWidth',2,'Tag','TLGM','Parent',ax); -0131 -0132 % y-limits -0133 set(ax,'YScale','lin','YLim',ylims); -0134 % y-label -0135 set(get(ax,'YLabel'),'String',ylab1); -0136 -0137 case 'cum' -0138 plot(invstd.T1T2me,cumsum(F),'o-','Color',col.FIT,... -0139 'LineWidth',2,'Parent',ax); -0140 % find approx. TLGM amplitude -0141 amp = findApproxTlgmAmplitude(invstd.T1T2me,cumsum(F),invstd.Tlgm); -0142 stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... -0143 'LineWidth',2,'Tag','TLGM','Parent',ax); -0144 -0145 % y-limits -0146 set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); -0147 % y-label -0148 set(get(ax,'YLabel'),'String',ylab2); -0149 end -0150 -0151 % x-limits -0152 ticks = round(log10(min(invstd.T1T2me)) :1: log10(max(invstd.T1T2me))); -0153 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); -0154 % x-label -0155 set(get(ax,'XLabel'),'String',xlstring); -0156 % grid -0157 grid(ax,'on'); -0158 end -0159 -0160 %% PSD -0161 % PSD axis -0162 ax = gui.axes_handles.psd; -0163 clearSingleAxis(ax); -0164 hold(ax,'on'); -0165 set(gui.cm_handles.axes_psd_view,'Enable','on'); -0166 -0167 % x-axis label -0168 switch data.process.timescale -0169 case 's' -0170 xlstring = 'equiv. pore size [m]'; -0171 case 'ms' -0172 xlstring = 'equiv. pore size [mm]'; -0173 end -0174 -0175 rho = data.param.rho/1e6; % surface relaxivity [m/s] -0176 a = data.param.a; % geometry parameter -0177 -0178 switch data.invstd.invtype -0179 case 'mono' -0180 switch nmrproc.T1T2 -0181 case 'T1' -0182 T = invstd.T1; -0183 case 'T2' -0184 T = invstd.T2; -0185 end -0186 -0187 stem(T.*rho.*a,invstd.E0,'o-','Color',col.FIT,'LineWidth',2,'Parent',ax); -0188 -0189 % limits -0190 ticks = floor(log10(min(T.*rho.*a)))-2 :1: ceil(log10(max(T.*rho.*a)))+2; -0191 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); -0192 set(ax,'YScale','lin','YLim',[0 invstd.E0*1.05]); -0193 % labels -0194 set(get(ax,'XLabel'),'String',xlstring); -0195 set(get(ax,'YLabel'),'String','initial amplitude E0'); -0196 % grid -0197 grid(ax,'on'); -0198 -0199 case 'free' -0200 mymark = {'o-','+-','s-','d-','x-'}; -0201 mycols = [22 140 75;22 87 140;140 22 87;140 75 22;64 64 64]./255; -0202 switch nmrproc.T1T2 -0203 case 'T1' -0204 T = invstd.T1; -0205 case 'T2' -0206 T = invstd.T2; -0207 end -0208 -0209 lgdstr = cell(1,1); -0210 for i = 1:data.invstd.freeDT -0211 stem(T(i).*rho.*a,invstd.E0(i),mymark{i},'Color',mycols(i,:),'LineWidth',2,'Parent',ax); -0212 lgdstr{i} = ['T',num2str(i)]; -0213 end -0214 -0215 % limits -0216 ticks = floor(log10(min(T.*rho.*a)))-2 :1: ceil(log10(max(T.*rho.*a)))+2; -0217 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); -0218 set(ax,'YScale','lin','YLim',[0 max(invstd.E0)*1.05]); -0219 % labels -0220 set(get(ax,'XLabel'),'String',xlstring); -0221 set(get(ax,'YLabel'),'String','individual amplitudes Ex [-]'); -0222 % grid -0223 grid(ax,'on'); -0224 -0225 case {'LU','NNLS'} -0226 % very basic RTD to PSD conversion -0227 requiv = invstd.T1T2me.*rho.*a; -0228 Rlgm = invstd.Tlgm.*rho.*a; -0229 -0230 switch data.info.PSDflag -0231 case 'freq' -0232 plot(requiv,F,'o-','Color',col.FIT,... -0233 'LineWidth',2,'Parent',ax); -0234 % find approx. RLGM amplitude -0235 amp = findApproxTlgmAmplitude(requiv,F,Rlgm); -0236 stem(Rlgm,amp,'x-','Color',[0.3 0.3 0.3],'LineWidth',2,'Tag','TLGM','Parent',ax); -0237 -0238 % y-limits -0239 set(ax,'YScale','lin','YLim',ylims); -0240 % y-label -0241 set(get(ax,'YLabel'),'String',ylab1); -0242 -0243 case 'cum' -0244 plot(requiv,cumsum(F),'o-','Color',col.FIT,... -0245 'LineWidth',2,'Parent',ax); -0246 % find approx. RLGM amplitude -0247 amp = findApproxTlgmAmplitude(requiv,cumsum(F),Rlgm); -0248 stem(Rlgm,amp,'x-','Color',[0.3 0.3 0.3],'LineWidth',2,'Tag','TLGM','Parent',ax); -0249 -0250 % y-limits -0251 set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); -0252 % y-label -0253 set(get(ax,'YLabel'),'String',ylab2); +0081 mycols = [0.8941 0.1020 0.1098;0.3020 0.6863 0.2902; +0082 0.2157 0.4941 0.7216;0.5961 0.3059 0.6392;0.6510 0.3373 0.1569]; +0083 switch nmrproc.T1T2 +0084 case 'T1' +0085 T = invstd.T1; +0086 case 'T2' +0087 T = invstd.T2; +0088 end +0089 +0090 lgdstr = cell(1,1); +0091 for i = 1:data.invstd.freeDT +0092 stem(T(i),invstd.E0(i),mymark{i},'Color',mycols(i,:),'LineWidth',2,'Parent',ax); +0093 lgdstr{i} = ['T',num2str(i)]; +0094 end +0095 +0096 % limits +0097 ticks = floor(log10(min(T)))-2 :1: ceil(log10(max(T)))+2; +0098 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); +0099 set(ax,'YScale','lin','YLim',[0 max(invstd.E0)*1.05]); +0100 % labels +0101 set(get(ax,'XLabel'),'String',xlstring); +0102 set(get(ax,'YLabel'),'String','individual amplitudes Ex [-]'); +0103 % grid +0104 grid(ax,'on'); +0105 +0106 case {'LU'} +0107 % scale distribution by porosity +0108 F = invstd.T1T2f; +0109 if sum(F)>0 +0110 F = (data.invstd.porosity*100).*F./sum(F); +0111 ylims = [0 max(F)*1.05]; +0112 else +0113 ylims = [-1 1]; +0114 end +0115 if data.invstd.porosity == 1 +0116 ylab1 = 'amplitudes [-]'; +0117 ylab2 = 'cumulative amplitudes [-]'; +0118 else +0119 ylab1 = 'water content [vol. %]'; +0120 ylab2 = 'cumulative water content [vol. %]'; +0121 end +0122 % F = data.invstd.porosity.*F./trapz(T,F); +0123 +0124 switch data.info.RTDflag +0125 case 'freq' +0126 plot(invstd.T1T2me,F,'o-','Color',col.FIT,... +0127 'LineWidth',2,'Parent',ax); +0128 % find approx. TLGM amplitude +0129 amp = findApproxTlgmAmplitude(invstd.T1T2me,F,invstd.Tlgm); +0130 stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... +0131 'LineWidth',2,'Tag','TLGM','Parent',ax); +0132 +0133 % y-limits +0134 set(ax,'YScale','lin','YLim',ylims); +0135 % y-label +0136 set(get(ax,'YLabel'),'String',ylab1); +0137 +0138 case 'cum' +0139 plot(invstd.T1T2me,cumsum(F),'o-','Color',col.FIT,... +0140 'LineWidth',2,'Parent',ax); +0141 % find approx. TLGM amplitude +0142 amp = findApproxTlgmAmplitude(invstd.T1T2me,cumsum(F),invstd.Tlgm); +0143 stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... +0144 'LineWidth',2,'Tag','TLGM','Parent',ax); +0145 +0146 % y-limits +0147 set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); +0148 % y-label +0149 set(get(ax,'YLabel'),'String',ylab2); +0150 end +0151 +0152 % x-limits +0153 ticks = round(log10(min(invstd.T1T2me)) :1: log10(max(invstd.T1T2me))); +0154 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); +0155 % x-label +0156 set(get(ax,'XLabel'),'String',xlstring); +0157 % grid +0158 grid(ax,'on'); +0159 +0160 case {'NNLS'} +0161 % scale distribution by porosity +0162 F = invstd.T1T2f; +0163 if sum(F)>0 +0164 % apply same scaling to the uncertainty patch +0165 if isfield(data.results.invstd,'uncert') +0166 f_min = data.results.invstd.uncert.interp_f_min; +0167 f_max = data.results.invstd.uncert.interp_f_max; +0168 f_min = (data.invstd.porosity*100).*f_min./sum(F); +0169 f_max = (data.invstd.porosity*100).*f_max./sum(F); +0170 end +0171 F = (data.invstd.porosity*100).*F./sum(F); +0172 +0173 ylims = [0 max(F)*1.05]; +0174 else +0175 ylims = [-1 1]; +0176 end +0177 if data.invstd.porosity == 1 +0178 ylab1 = 'amplitudes [-]'; +0179 ylab2 = 'cumulative amplitudes [-]'; +0180 else +0181 ylab1 = 'water content [vol. %]'; +0182 ylab2 = 'cumulative water content [vol. %]'; +0183 end +0184 % F = data.invstd.porosity.*F./trapz(T,F); +0185 +0186 switch data.info.RTDflag +0187 case 'freq' +0188 if isfield(data.results.invstd,'uncert') +0189 % plot uncertainty +0190 for i = 1:size(invstd.uncert.interp_f,1) +0191 plot(invstd.T1T2me,(data.invstd.porosity*100).*invstd.uncert.interp_f(i,:)./sum(invstd.T1T2f),... +0192 '-','Color',[0.5 0.5 0.5],'LineWidth',1,'Parent',ax); +0193 end +0194 % verts = [invstd.T1T2me f_min'; flipud(invstd.T1T2me) flipud(f_max')]; +0195 % faces = 1:1:size(verts,1); +0196 % patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... +0197 % 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); +0198 % adjust y-limits +0199 ylims(2) = max([ylims(2) max(f_max)*1.05]); +0200 end +0201 +0202 plot(invstd.T1T2me,F,'-','Color',col.FIT,... +0203 'LineWidth',2,'Parent',ax); +0204 % find approx. TLGM amplitude +0205 amp = findApproxTlgmAmplitude(invstd.T1T2me,F,invstd.Tlgm); +0206 stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... +0207 'LineWidth',2,'Tag','TLGM','Parent',ax); +0208 +0209 % y-limits +0210 set(ax,'YScale','lin','YLim',ylims); +0211 % y-label +0212 set(get(ax,'YLabel'),'String',ylab1); +0213 +0214 case 'cum' +0215 if isfield(data.results.invstd,'uncert') +0216 verts = [invstd.T1T2me cumsum(F)-f_min'; flipud(invstd.T1T2me) flipud(cumsum(F)+f_max')]; +0217 faces = 1:1:size(verts,1); +0218 patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... +0219 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); +0220 end +0221 plot(invstd.T1T2me,cumsum(F),'-','Color',col.FIT,... +0222 'LineWidth',2,'Parent',ax); +0223 % find approx. TLGM amplitude +0224 amp = findApproxTlgmAmplitude(invstd.T1T2me,cumsum(F),invstd.Tlgm); +0225 stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... +0226 'LineWidth',2,'Tag','TLGM','Parent',ax); +0227 +0228 % y-limits +0229 set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); +0230 % y-label +0231 set(get(ax,'YLabel'),'String',ylab2); +0232 end +0233 +0234 % x-limits +0235 ticks = round(log10(min(invstd.T1T2me)) :1: log10(max(invstd.T1T2me))); +0236 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); +0237 % x-label +0238 set(get(ax,'XLabel'),'String',xlstring); +0239 % grid +0240 grid(ax,'on'); +0241 +0242 case {'MUMO'} +0243 % single distributions for different T, sigma and amplitude +0244 dist = zeros(length(invstd.x)/3,numel(invstd.T1T2me)); +0245 for i = 1:length(invstd.x)/3 +0246 mu = invstd.T(i); +0247 sigma = invstd.S(i); +0248 amp = invstd.E(i); +0249 +0250 tmp = 1./( sigma*sqrt(2*pi)).*exp(-((log(invstd.T1T2me) - log(mu))/ sqrt(2)/sigma).^2); +0251 +0252 % scale to amplitude +0253 dist(i,:) = (tmp/sum(tmp)) * amp; 0254 end 0255 -0256 % x-limits -0257 ticks = floor(log10(min(requiv))) :1: ceil(log10(max(requiv))); -0258 % set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); -0259 set(ax,'XScale','log','XLim',[min(requiv) max(requiv)],'XTick',10.^ticks); -0260 % x-label -0261 set(get(ax,'XLabel'),'String',xlstring); -0262 % grid -0263 grid(ax,'on'); -0264 end -0265 -0266 % show CBW and diffusion regime lines -0267 updatePlotsDistributionInfo; -0268 end -0269 -0270 end -0271 -0272 %% -0273 function amp = findApproxTlgmAmplitude(t,f,TLGM) -0274 -0275 if isnan(TLGM) -0276 amp = NaN; -0277 else -0278 index = find(abs(t-TLGM)==min(abs(t-TLGM))); -0279 amp = interp1(t(index-1:index+1),f(index-1:index+1),TLGM); -0280 end -0281 -0282 end -0283 -0284 %------------- END OF CODE -------------- -0285 -0286 %% License: -0287 % MIT License -0288 % -0289 % Copyright (c) 2018 Thomas Hiller -0290 % -0291 % Permission is hereby granted, free of charge, to any person obtaining a copy -0292 % of this software and associated documentation files (the "Software"), to deal -0293 % in the Software without restriction, including without limitation the rights -0294 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0295 % copies of the Software, and to permit persons to whom the Software is -0296 % furnished to do so, subject to the following conditions: -0297 % -0298 % The above copyright notice and this permission notice shall be included in all -0299 % copies or substantial portions of the Software. -0300 % -0301 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0302 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0303 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0304 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0305 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0306 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0307 % SOFTWARE. +0256 % scale distribution by porosity +0257 F = invstd.T1T2f; +0258 if sum(F)>0 +0259 for i = 1:length(invstd.x)/3 +0260 dist(i,:) = (data.invstd.porosity*100).*dist(i,:)./sum(F); +0261 end +0262 % apply same scaling to the uncertainty patch +0263 if isfield(data.results.invstd,'uncert') +0264 f_min = data.results.invstd.uncert.interp_f_min; +0265 f_max = data.results.invstd.uncert.interp_f_max; +0266 f_min = (data.invstd.porosity*100).*f_min./sum(F); +0267 f_max = (data.invstd.porosity*100).*f_max./sum(F); +0268 end +0269 F = (data.invstd.porosity*100).*F./sum(F); +0270 +0271 ylims = [0 max(F)*1.05]; +0272 else +0273 ylims = [-1 1]; +0274 end +0275 if data.invstd.porosity == 1 +0276 ylab1 = 'amplitudes [-]'; +0277 ylab2 = 'cumulative amplitudes [-]'; +0278 else +0279 ylab1 = 'water content [vol. %]'; +0280 ylab2 = 'cumulative water content [vol. %]'; +0281 end +0282 % F = data.invstd.porosity.*F./trapz(T,F); +0283 +0284 mycols = [0.2157 0.4941 0.7216;0.3020 0.6863 0.2902; +0285 0.5961 0.3059 0.6392;0.6510 0.3373 0.1569;0.8941 0.1020 0.1098]; +0286 +0287 switch data.info.RTDflag +0288 case 'freq' +0289 if isfield(data.results.invstd,'uncert') +0290 % plot uncertainty +0291 % lines +0292 % for i = 1:size(invstd.TDIST,1) +0293 % plot(invstd.T1T2me,(data.invstd.porosity*100).*invstd.TDIST(i,:)./sum(invstd.T1T2f),... +0294 % '-','Color',[0.5 0.5 0.5],'LineWidth',1,'Parent',ax); +0295 % end +0296 % patch +0297 % TDIST = invstd.TDIST; +0298 % for i = 1:size(invstd.TDIST,1) +0299 % TDIST(i,:) = (data.invstd.porosity*100).*invstd.TDIST(i,:)./sum(invstd.T1T2f); +0300 % end +0301 % TDISTmin = min(TDIST); +0302 % TDISTmax = max(TDIST); +0303 % verts = [nmrproc.t(nmrproc.t>0) s_min; flipud(nmrproc.t(nmrproc.t>0)) flipud(s_max)]; +0304 % faces = 1:1:size(verts,1); +0305 % +0306 verts = [invstd.T1T2me f_min'; flipud(invstd.T1T2me) flipud(f_max')]; +0307 faces = 1:1:size(verts,1); +0308 patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... +0309 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); +0310 % adjust y-limits +0311 ylims(2) = max([ylims(2) max(f_max)*1.05]); +0312 end +0313 +0314 % plot total RTD +0315 plot(invstd.T1T2me,F,'-','Color',col.FIT,... +0316 'LineWidth',2,'Parent',ax); +0317 % plot individual RTDs +0318 for i = 1:length(invstd.x)/3 +0319 plot(invstd.T1T2me,dist(i,:),'--','Color',mycols(i,:),... +0320 'LineWidth',2,'Parent',ax); +0321 end +0322 % find approx. TLGM amplitude +0323 amp = findApproxTlgmAmplitude(invstd.T1T2me,F,invstd.Tlgm); +0324 stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... +0325 'LineWidth',2,'Tag','TLGM','Parent',ax); +0326 +0327 % y-limits +0328 set(ax,'YScale','lin','YLim',ylims); +0329 % y-label +0330 set(get(ax,'YLabel'),'String',ylab1); +0331 +0332 case 'cum' +0333 if isfield(data.results.invstd,'uncert') +0334 verts = [invstd.T1T2me cumsum(F)-f_min'; flipud(invstd.T1T2me) flipud(cumsum(F)+f_max')]; +0335 faces = 1:1:size(verts,1); +0336 patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... +0337 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); +0338 end +0339 plot(invstd.T1T2me,cumsum(F),'-','Color',col.FIT,... +0340 'LineWidth',2,'Parent',ax); +0341 for i = 1:length(invstd.x)/3 +0342 plot(invstd.T1T2me,cumsum(dist(i,:)),'--','Color',mycols(i,:),... +0343 'LineWidth',2,'Parent',ax); +0344 end +0345 % find approx. TLGM amplitude +0346 amp = findApproxTlgmAmplitude(invstd.T1T2me,cumsum(F),invstd.Tlgm); +0347 stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... +0348 'LineWidth',2,'Tag','TLGM','Parent',ax); +0349 +0350 % y-limits +0351 set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); +0352 % y-label +0353 set(get(ax,'YLabel'),'String',ylab2); +0354 end +0355 +0356 % x-limits +0357 ticks = round(log10(min(invstd.T1T2me)) :1: log10(max(invstd.T1T2me))); +0358 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); +0359 % x-label +0360 set(get(ax,'XLabel'),'String',xlstring); +0361 % grid +0362 grid(ax,'on'); +0363 end +0364 +0365 %% PSD +0366 % PSD axis +0367 ax = gui.axes_handles.psd; +0368 clearSingleAxis(ax); +0369 hold(ax,'on'); +0370 set(gui.cm_handles.axes_psd_view,'Enable','on'); +0371 +0372 % x-axis label +0373 switch data.process.timescale +0374 case 's' +0375 xlstring = 'equiv. pore size [m]'; +0376 case 'ms' +0377 xlstring = 'equiv. pore size [mm]'; +0378 end +0379 +0380 rho = data.param.rho/1e6; % surface relaxivity [m/s] +0381 a = data.param.a; % geometry parameter +0382 +0383 switch data.invstd.invtype +0384 case 'mono' +0385 switch nmrproc.T1T2 +0386 case 'T1' +0387 T = invstd.T1; +0388 case 'T2' +0389 T = invstd.T2; +0390 end +0391 +0392 stem(T.*rho.*a,invstd.E0,'o-','Color',col.FIT,'LineWidth',2,'Parent',ax); +0393 +0394 % limits +0395 ticks = floor(log10(min(T.*rho.*a)))-2 :1: ceil(log10(max(T.*rho.*a)))+2; +0396 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); +0397 set(ax,'YScale','lin','YLim',[0 invstd.E0*1.05]); +0398 % labels +0399 set(get(ax,'XLabel'),'String',xlstring); +0400 set(get(ax,'YLabel'),'String','initial amplitude E0'); +0401 % grid +0402 grid(ax,'on'); +0403 +0404 case 'free' +0405 mymark = {'o-','+-','s-','d-','x-'}; +0406 mycols = [0.8941 0.1020 0.1098;0.3020 0.6863 0.2902; +0407 0.2157 0.4941 0.7216;0.5961 0.3059 0.6392;0.6510 0.3373 0.1569]; +0408 switch nmrproc.T1T2 +0409 case 'T1' +0410 T = invstd.T1; +0411 case 'T2' +0412 T = invstd.T2; +0413 end +0414 +0415 lgdstr = cell(1,1); +0416 for i = 1:data.invstd.freeDT +0417 stem(T(i).*rho.*a,invstd.E0(i),mymark{i},'Color',mycols(i,:),'LineWidth',2,'Parent',ax); +0418 lgdstr{i} = ['T',num2str(i)]; +0419 end +0420 +0421 % limits +0422 ticks = floor(log10(min(T.*rho.*a)))-2 :1: ceil(log10(max(T.*rho.*a)))+2; +0423 set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); +0424 set(ax,'YScale','lin','YLim',[0 max(invstd.E0)*1.05]); +0425 % labels +0426 set(get(ax,'XLabel'),'String',xlstring); +0427 set(get(ax,'YLabel'),'String','individual amplitudes Ex [-]'); +0428 % grid +0429 grid(ax,'on'); +0430 +0431 case {'LU','NNLS'} +0432 % very basic RTD to PSD conversion +0433 requiv = invstd.T1T2me.*rho.*a; +0434 Rlgm = invstd.Tlgm.*rho.*a; +0435 +0436 switch data.info.PSDflag +0437 case 'freq' +0438 plot(requiv,F,'o-','Color',col.FIT,... +0439 'LineWidth',2,'Parent',ax); +0440 % find approx. RLGM amplitude +0441 amp = findApproxTlgmAmplitude(requiv,F,Rlgm); +0442 stem(Rlgm,amp,'x-','Color',col.axisL,'LineWidth',2,'Tag','TLGM','Parent',ax); +0443 +0444 % y-limits +0445 set(ax,'YScale','lin','YLim',ylims); +0446 % y-label +0447 set(get(ax,'YLabel'),'String',ylab1); +0448 +0449 case 'cum' +0450 plot(requiv,cumsum(F),'o-','Color',col.FIT,... +0451 'LineWidth',2,'Parent',ax); +0452 % find approx. RLGM amplitude +0453 amp = findApproxTlgmAmplitude(requiv,cumsum(F),Rlgm); +0454 stem(Rlgm,amp,'x-','Color',col.axisL,'LineWidth',2,'Tag','TLGM','Parent',ax); +0455 +0456 % y-limits +0457 set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); +0458 % y-label +0459 set(get(ax,'YLabel'),'String',ylab2); +0460 end +0461 +0462 % x-limits +0463 ticks = floor(log10(min(requiv))) :1: ceil(log10(max(requiv))); +0464 % set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); +0465 set(ax,'XScale','log','XLim',[min(requiv) max(requiv)],'XTick',10.^ticks); +0466 % x-label +0467 set(get(ax,'XLabel'),'String',xlstring); +0468 % grid +0469 grid(ax,'on'); +0470 +0471 case {'MUMO'} +0472 % very basic RTD to PSD conversion +0473 requiv = invstd.T1T2me.*rho.*a; +0474 Rlgm = invstd.Tlgm.*rho.*a; +0475 +0476 switch data.info.PSDflag +0477 case 'freq' +0478 if isfield(data.results.invstd,'uncert') +0479 verts = [requiv f_min'; flipud(requiv) flipud(f_max')]; +0480 patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... +0481 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); +0482 % adjust y-limits +0483 ylims(2) = max([ylims(2) max(f_max)*1.05]); +0484 end +0485 plot(requiv,F,'-','Color',col.FIT,... +0486 'LineWidth',2,'Parent',ax); +0487 for i = 1:length(invstd.x)/3 +0488 plot(requiv,dist(i,:),'--','Color',mycols(i,:),... +0489 'LineWidth',2,'Parent',ax); +0490 end +0491 % find approx. RLGM amplitude +0492 amp = findApproxTlgmAmplitude(requiv,F,Rlgm); +0493 stem(Rlgm,amp,'x-','Color',col.axisL,'LineWidth',2,'Tag','TLGM','Parent',ax); +0494 +0495 % y-limits +0496 set(ax,'YScale','lin','YLim',ylims); +0497 % y-label +0498 set(get(ax,'YLabel'),'String',ylab1); +0499 +0500 case 'cum' +0501 if isfield(data.results.invstd,'uncert') +0502 verts = [requiv cumsum(F)-f_min'; flipud(requiv) flipud(cumsum(F)+f_max')]; +0503 patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... +0504 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); +0505 end +0506 plot(requiv,cumsum(F),'-','Color',col.FIT,... +0507 'LineWidth',2,'Parent',ax); +0508 for i = 1:length(invstd.x)/3 +0509 plot(requiv,cumsum(dist(i,:)),'--','Color',mycols(i,:),... +0510 'LineWidth',2,'Parent',ax); +0511 end +0512 % find approx. RLGM amplitude +0513 amp = findApproxTlgmAmplitude(requiv,cumsum(F),Rlgm); +0514 stem(Rlgm,amp,'x-','Color',col.axisL,'LineWidth',2,'Tag','TLGM','Parent',ax); +0515 +0516 % y-limits +0517 set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); +0518 % y-label +0519 set(get(ax,'YLabel'),'String',ylab2); +0520 end +0521 +0522 % x-limits +0523 ticks = floor(log10(min(requiv))) :1: ceil(log10(max(requiv))); +0524 % set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); +0525 set(ax,'XScale','log','XLim',[min(requiv) max(requiv)],'XTick',10.^ticks); +0526 % x-label +0527 set(get(ax,'XLabel'),'String',xlstring); +0528 % grid +0529 grid(ax,'on'); +0530 end +0531 +0532 % show CBW and diffusion regime lines +0533 updatePlotsDistributionInfo; +0534 end +0535 +0536 end +0537 +0538 %% +0539 function amp = findApproxTlgmAmplitude(t,f,TLGM) +0540 +0541 if isnan(TLGM) +0542 amp = NaN; +0543 else +0544 index = find(abs(t-TLGM)==min(abs(t-TLGM))); +0545 amp = interp1(t(index-1:index+1),f(index-1:index+1),TLGM); +0546 end +0547 +0548 end +0549 +0550 %------------- END OF CODE -------------- +0551 +0552 %% License: +0553 % MIT License +0554 % +0555 % Copyright (c) 2018 Thomas Hiller +0556 % +0557 % Permission is hereby granted, free of charge, to any person obtaining a copy +0558 % of this software and associated documentation files (the "Software"), to deal +0559 % in the Software without restriction, including without limitation the rights +0560 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0561 % copies of the Software, and to permit persons to whom the Software is +0562 % furnished to do so, subject to the following conditions: +0563 % +0564 % The above copyright notice and this permission notice shall be included in all +0565 % copies or substantial portions of the Software. +0566 % +0567 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0568 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0569 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0570 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0571 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0572 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0573 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/updatePlotsDistributionInfo.html b/doc/nucleus/functions/interface/updatePlotsDistributionInfo.html index d420e2f..90de642 100644 --- a/doc/nucleus/functions/interface/updatePlotsDistributionInfo.html +++ b/doc/nucleus/functions/interface/updatePlotsDistributionInfo.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updatePlotsGeometryType.html b/doc/nucleus/functions/interface/updatePlotsGeometryType.html index 03d66ec..b446367 100644 --- a/doc/nucleus/functions/interface/updatePlotsGeometryType.html +++ b/doc/nucleus/functions/interface/updatePlotsGeometryType.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updatePlotsJointInversion.html b/doc/nucleus/functions/interface/updatePlotsJointInversion.html index b679f41..b80ef6e 100644 --- a/doc/nucleus/functions/interface/updatePlotsJointInversion.html +++ b/doc/nucleus/functions/interface/updatePlotsJointInversion.html @@ -52,8 +52,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=beautifyAxes can be used to globally change the general appearance of axes
  • clearSingleAxis clears an individual axis
  • getColorIndex exports graphics from both GUIs into various formats
  • This function is called by: +
  • onContextAxisLogLin changes the label of an axis context menu which allows to
  • onContextPlotsPSDJ checks the label of the distribution axis context menu
  • onListboxData handles the calls from the context menu of the data
  • changeColorTheme changes the color theme of the calling figure
  • runInversionJoint controls the joint inversion process to infer a pore size
  • @@ -96,8 +96,8 @@

    SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSinv -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updatePlotsLcurve.html b/doc/nucleus/functions/interface/updatePlotsLcurve.html index 53c1ad7..0a3638d 100644 --- a/doc/nucleus/functions/interface/updatePlotsLcurve.html +++ b/doc/nucleus/functions/interface/updatePlotsLcurve.html @@ -51,8 +51,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=beautifyAxes can be used to globally change the general appearance of axes
  • clearSingleAxis clears an individual axis
  • This function is called by: +
  • onListboxData handles the calls from the context menu of the data
  • runInversionJoint controls the joint inversion process to infer a pore size
  • runInversionStd controls the standard inversion process to invert a
  • @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updatePlotsNMR.html b/doc/nucleus/functions/interface/updatePlotsNMR.html index 5e600ea..b5b1223 100644 --- a/doc/nucleus/functions/interface/updatePlotsNMR.html +++ b/doc/nucleus/functions/interface/updatePlotsNMR.html @@ -50,8 +50,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=beautifyAxes can be used to globally change the general appearance of axes
  • clearSingleAxis clears an individual axis
  • getColorIndex exports graphics from both GUIs into various formats
  • This function is called by: +
  • onContextAxisLogLin changes the label of an axis context menu which allows to
  • onContextAxisT1T2 checks the axis context menu for plotting either T1 or
  • onContextTableSelect selects or deselects whole drainage and imbibition
  • onEditCPSTable updates entries made in the CPS table of NUCLEUSinv
  • calculateNMR calculates the NMR signals for the full and partially saturated
  • changeColorTheme changes the color theme of the calling figure
  • importMOD2MOD imports previously saved NUCLEUSmod data back into the GUI
  • updateNMRsignals adds noise to the forward NMR signals and scales the
  • @@ -92,8 +92,8 @@

    SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updatePlotsPSD.html b/doc/nucleus/functions/interface/updatePlotsPSD.html index 54e2311..e190f48 100644 --- a/doc/nucleus/functions/interface/updatePlotsPSD.html +++ b/doc/nucleus/functions/interface/updatePlotsPSD.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: NUCLEUSmod -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updatePlotsSignal.html b/doc/nucleus/functions/interface/updatePlotsSignal.html index 32b13e5..eb00eb4 100644 --- a/doc/nucleus/functions/interface/updatePlotsSignal.html +++ b/doc/nucleus/functions/interface/updatePlotsSignal.html @@ -51,8 +51,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=beautifyAxes can be used to globally change the general appearance of axes
  • clearSingleAxis clears an individual axis
  • getColorIndex exports graphics from both GUIs into various formats
  • This function is called by: +
  • onContextAxisLogLin changes the label of an axis context menu which allows to
  • onEditCPSTable updates entries made in the CPS table of NUCLEUSinv
  • onEditValue updates all edit field values, checks for wrong inputs and
  • onListboxData handles the calls from the context menu of the data
  • onMenuJointInversion handles the call from the menu that activates / deactivates
  • onRadioGates selects the re-sampling / gating method ("log", "lin" or "none")
  • onRadioNormalize selects whether to normalize a NMR signal to 1
  • onRadioTimescale selects whether the time scale should be "s" or "ms"
  • changeColorTheme changes the color theme of the calling figure
  • clearInversion removes inversion results from the internal data structure
  • runInversionStd controls the standard inversion process to invert a
  • @@ -94,8 +94,8 @@

    SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- @@ -191,283 +191,324 @@

    SOURCE CODE ^'LineStyle','--','LineWidth',1,'Color','k','Parent',axI); 0122 imag_mean = mean(imag(nmrraw.s)); 0123 imag_std = std(imag(nmrraw.s)); -0124 yticks = linspace(min(imag(nmrraw.s)),max(imag(nmrraw.s)),3); -0125 set(axI,'XTickLabel','','YTick',yticks,'YTickLabelMode','auto'); -0126 switch loglinx -0127 case 'x-axis -> lin' % log axes -0128 set(axI,'XScale','log','XLim',xlims); -0129 case 'x-axis -> log' % lin axes -0130 set(axI,'XScale','lin','XLim',xlims); -0131 end -0132 set(get(axI,'YLabel'),'String','\Immag'); -0133 end -0134 -0135 % grid -0136 grid(ax,'on'); -0137 -0138 %% PROC data axis -0139 ax = gui.axes_handles.proc; -0140 axE = gui.axes_handles.err; -0141 clearSingleAxis(ax); -0142 clearSingleAxis(axE); -0143 hold(ax,'on'); -0144 hold(axE,'on'); -0145 -0146 % data -0147 plot(nmrproc.t,nmrproc.s,'o','Color',col.RE,'LineWidth',1,'Parent',ax); -0148 if isfield(data.results,'invstd') -0149 plot(invstd.fit_t,invstd.fit_s,'Color',col.FIT,'LineWidth',2,'Parent',ax); -0150 if nmrproc.noise > 0 -0151 plot(nmrproc.t,invstd.residual./nmrproc.e,'Color',col.IM,... -0152 'LineWidth',1,'Parent',axE); -0153 else -0154 plot(nmrproc.t,invstd.residual,'Color',col.IM,... -0155 'LineWidth',1,'Parent',axE); -0156 end -0157 end -0158 -0159 % limits & ticks -0160 xlimraw = get(gui.axes_handles.raw,'XLim'); -0161 loglinx = get(gui.cm_handles.axes_proc_xaxis,'Label'); -0162 switch loglinx -0163 case 'x-axis -> lin' % log axes -0164 ticks = floor(min(log10(nmrproc.t(nmrproc.t>0)))):1:ceil(log10(nmrproc.t(end))); -0165 set(ax,'XScale','log','XLim',xlimraw,'XTick',10.^ticks); -0166 case 'x-axis -> log' % lin axes -0167 set(ax,'XScale','lin','XLim',xlimraw,'XTickMode','auto'); -0168 end -0169 logliny = get(gui.cm_handles.axes_proc_yaxis,'Label'); -0170 switch nmrproc.T1T2 -0171 case 'T1' -0172 ymin = min(real(nmrproc.s)); -0173 ymax = max(real(nmrproc.s)); -0174 if isfield(data.results,'invstd') -0175 ymin = min([ymin min(invstd.residual)]); -0176 ymax = max([ymax max(data.results.invstd.fit_s)]); -0177 end -0178 if ymin>0 -0179 ymin = ymin*0.8; -0180 else -0181 ymin = ymin*1.2; -0182 end -0183 switch logliny -0184 case 'y-axis -> lin' % log axes -0185 ticks = floor(min(log10(nmrproc.s(nmrproc.s>0))))-1:1:ceil(log10(nmrproc.s(end))); -0186 set(ax,'YScale','log','YLim',[10^(ticks(1)) 10^(ticks(end))],... -0187 'YTick',10.^ticks); -0188 case 'y-axis -> log' % lin axes -0189 set(ax,'YScale','lin','YLim',[ymin ymax*1.05],... -0190 'YTickMode','auto'); -0191 end -0192 case 'T2' -0193 ymin = min([min(real(nmrraw.s)) min(imag(nmrraw.s))]); -0194 ymax = max(real(nmrraw.s)); -0195 if isfield(data.results,'invstd') -0196 ymin = min([ymin min(invstd.residual)]); -0197 ymax = max([ymax max(data.results.invstd.fit_s)]); -0198 end -0199 switch logliny -0200 case 'y-axis -> lin' % log axes -0201 ticks = floor(log10(ymin))-1 :1: ceil(log10(ymax)); -0202 set(ax,'YScale','log','YLim',[10^(ticks(1)) ymax*1.05],... -0203 'YTick',10.^ticks); -0204 case 'y-axis -> log' % lin axes -0205 set(ax,'YScale','lin','YLim',[ymin ymax*1.05],... -0206 'YTickMode','auto'); -0207 end -0208 end -0209 if isfield(data.results,'invstd') -0210 ylims = get(ax,'YLim'); -0211 set(gui.axes_handles.raw,'YLim',ylims); -0212 end -0213 -0214 % labels -0215 if strcmp(data.process.timescale,'s') -0216 set(get(ax,'XLabel'),'String','time [s]'); -0217 else -0218 set(get(ax,'XLabel'),'String','time [ms]'); -0219 end -0220 set(get(ax,'YLabel'),'String','amplitude [a.u.]'); -0221 -0222 % legend -0223 if isfield(data.results,'invstd') -0224 lgdstr = {'signal','fit'}; -0225 switch nmrproc.T1T2 -0226 case 'T1' -0227 lgh = legend(ax,lgdstr,'Location','NorthWest',... -0228 'Tag','fitlegend','FontSize',10); -0229 case 'T2' -0230 lgh = legend(ax,lgdstr,'Location','NorthEast',... -0231 'Tag','fitlegend','FontSize',10); -0232 end -0233 set(lgh,'TextColor',gui.myui.colors.panelFG); -0234 end -0235 -0236 % grid -0237 grid(ax,'on'); -0238 -0239 %% residual plot -0240 if isfield(data.results,'invstd') -0241 col = gui.myui.colors.axisL; -0242 xlims = get(ax,'XLim'); -0243 line(xlims,[0 0],'LineStyle','--','LineWidth',1,'Color',col,'Parent',axE); -0244 if nmrproc.noise > 0 -0245 err_mean = mean(invstd.residual./nmrproc.e); -0246 err_std = std(invstd.residual./nmrproc.e); -0247 line(xlims,[err_mean-err_std err_mean-err_std],... -0248 'LineStyle','--','LineWidth',1,'Color','r','Parent',axE); -0249 line(xlims,[err_mean+err_std err_mean+err_std],... -0250 'LineStyle','--','LineWidth',1,'Color','r','Parent',axE); -0251 line(xlims,[-1 -1],'LineStyle','-.','LineWidth',1,... -0252 'Color',col,'Parent',axE); -0253 line(xlims,[1 1],'LineStyle','-.','LineWidth',1,... -0254 'Color',col,'Parent',axE); -0255 set(axE,'XTickLabel',''); -0256 set(axE,'YLim',[-2 2]); -0257 set(axE,'YTick',[-1 0 1],'YTickLabelMode','auto'); -0258 set(get(axE,'YLabel'),'String',{'noise';'weighted';'residuals'},... -0259 'FontWeight','normal'); -0260 else -0261 err_mean = mean(invstd.residual); -0262 err_std = std(invstd.residual); -0263 line(xlims,[err_mean-1*err_std err_mean-1*err_std],... -0264 'LineStyle','-.','LineWidth',1,'Color',col,'Parent',axE); -0265 line(xlims,[err_mean+1*err_std err_mean+1*err_std],... -0266 'LineStyle','-.','LineWidth',1,'Color',col,'Parent',axE); -0267 set(axE,'XTickLabel',''); -0268 set(axE,'YLim',[err_mean-3*err_std err_mean+3*err_std]); -0269 set(axE,'YTick',[err_mean-3*err_std 0 err_mean+3*err_std],... -0270 'YTickLabelMode','auto') -0271 set(get(axE,'YLabel'),'String','residuals',... -0272 'FontWeight','normal'); +0124 % yticks = linspace(min(imag(nmrraw.s)),max(imag(nmrraw.s)),3); +0125 yticks = [imag_mean-imag_std*2 0 imag_mean+imag_std*2]; +0126 ylim = [imag_mean-imag_std*3 imag_mean+imag_std*3]; +0127 set(axI,'XTickLabel','','YLim',ylim,'YTick',yticks,'YTickLabelMode','auto'); +0128 switch loglinx +0129 case 'x-axis -> lin' % log axes +0130 set(axI,'XScale','log','XLim',xlims); +0131 case 'x-axis -> log' % lin axes +0132 set(axI,'XScale','lin','XLim',xlims); +0133 end +0134 set(get(axI,'YLabel'),'String','\Immag'); +0135 end +0136 +0137 % grid +0138 grid(ax,'on'); +0139 +0140 %% PROC data axis +0141 ax = gui.axes_handles.proc; +0142 axE = gui.axes_handles.err; +0143 clearSingleAxis(ax); +0144 clearSingleAxis(axE); +0145 hold(ax,'on'); +0146 hold(axE,'on'); +0147 +0148 % data +0149 switch data.invstd.invtype +0150 case {'MUMO','NNLS'} +0151 if isfield(data.results,'invstd') && isfield(data.results.invstd,'uncert') +0152 % uncertainty patch created from min max of uncertainty +0153 % data +0154 s_min = data.results.invstd.uncert.interp_s_min; +0155 s_max = data.results.invstd.uncert.interp_s_max; +0156 t = data.results.invstd.uncert.interp_t; +0157 verts = [t(t>0) s_min(t>0); flipud(t(t>0)) flipud(s_max(t>0))]; +0158 faces = 1:1:size(verts,1); +0159 patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... +0160 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); +0161 end +0162 +0163 if isfield(data.results,'invstd') +0164 plot(nmrproc.t,nmrproc.s,'-','Color',col.RE,'LineWidth',1,'Parent',ax); +0165 plot(invstd.fit_t,invstd.fit_s,'Color',col.FIT,'LineWidth',2,'Parent',ax); +0166 if nmrproc.noise > 0 +0167 plot(nmrproc.t,invstd.residual./nmrproc.e,'Color',col.IM,... +0168 'LineWidth',1,'Parent',axE); +0169 else +0170 plot(nmrproc.t,invstd.residual,'Color',col.IM,... +0171 'LineWidth',1,'Parent',axE); +0172 end +0173 else +0174 plot(nmrproc.t,nmrproc.s,'o','Color',col.RE,'LineWidth',1,'Parent',ax); +0175 end +0176 otherwise +0177 if isfield(data.results,'invstd') +0178 plot(nmrproc.t,nmrproc.s,'-','Color',col.RE,'LineWidth',1,'Parent',ax); +0179 plot(invstd.fit_t,invstd.fit_s,'Color',col.FIT,'LineWidth',2,'Parent',ax); +0180 if nmrproc.noise > 0 +0181 plot(nmrproc.t,invstd.residual./nmrproc.e,'Color',col.IM,... +0182 'LineWidth',1,'Parent',axE); +0183 else +0184 plot(nmrproc.t,invstd.residual,'Color',col.IM,... +0185 'LineWidth',1,'Parent',axE); +0186 end +0187 else +0188 plot(nmrproc.t,nmrproc.s,'o','Color',col.RE,'LineWidth',1,'Parent',ax); +0189 end +0190 end +0191 +0192 % limits & ticks +0193 xlimraw = get(gui.axes_handles.raw,'XLim'); +0194 loglinx = get(gui.cm_handles.axes_proc_xaxis,'Label'); +0195 switch loglinx +0196 case 'x-axis -> lin' % log axes +0197 ticks = floor(min(log10(nmrproc.t(nmrproc.t>0)))):1:ceil(log10(nmrproc.t(end))); +0198 set(ax,'XScale','log','XLim',xlimraw,'XTick',10.^ticks); +0199 case 'x-axis -> log' % lin axes +0200 set(ax,'XScale','lin','XLim',xlimraw,'XTickMode','auto'); +0201 end +0202 logliny = get(gui.cm_handles.axes_proc_yaxis,'Label'); +0203 switch nmrproc.T1T2 +0204 case 'T1' +0205 ymin = min(real(nmrproc.s)); +0206 ymax = max(real(nmrproc.s)); +0207 if isfield(data.results,'invstd') +0208 ymin = min([ymin min(invstd.residual)]); +0209 ymax = max([ymax max(data.results.invstd.fit_s)]); +0210 end +0211 if ymin>0 +0212 ymin = ymin*0.8; +0213 else +0214 ymin = ymin*1.2; +0215 end +0216 switch logliny +0217 case 'y-axis -> lin' % log axes +0218 ticks = floor(min(log10(nmrproc.s(nmrproc.s>0))))-1:1:ceil(log10(nmrproc.s(end))); +0219 set(ax,'YScale','log','YLim',[10^(ticks(1)) 10^(ticks(end))],... +0220 'YTick',10.^ticks); +0221 case 'y-axis -> log' % lin axes +0222 set(ax,'YScale','lin','YLim',[ymin ymax*1.05],... +0223 'YTickMode','auto'); +0224 end +0225 case 'T2' +0226 ymin = min([min(real(nmrraw.s)) min(imag(nmrraw.s))]); +0227 ymax = max(real(nmrraw.s)); +0228 if isfield(data.results,'invstd') +0229 ymin = min([ymin min(invstd.residual)]); +0230 ymax = max([ymax max(data.results.invstd.fit_s)]); +0231 end +0232 switch logliny +0233 case 'y-axis -> lin' % log axes +0234 ticks = floor(log10(ymin))-1 :1: ceil(log10(ymax)); +0235 set(ax,'YScale','log','YLim',[10^(ticks(1)) ymax*1.1],... +0236 'YTick',10.^ticks); +0237 case 'y-axis -> log' % lin axes +0238 set(ax,'YScale','lin','YLim',[ymin ymax*1.1],... +0239 'YTickMode','auto'); +0240 end +0241 end +0242 if isfield(data.results,'invstd') +0243 ylims = get(ax,'YLim'); +0244 set(gui.axes_handles.raw,'YLim',ylims); +0245 end +0246 +0247 % labels +0248 if strcmp(data.process.timescale,'s') +0249 set(get(ax,'XLabel'),'String','time [s]'); +0250 else +0251 set(get(ax,'XLabel'),'String','time [ms]'); +0252 end +0253 set(get(ax,'YLabel'),'String','amplitude [a.u.]'); +0254 +0255 % legend +0256 if isfield(data.results,'invstd') +0257 if isfield(data.results,'invstd') && isfield(data.results.invstd,'uncert') +0258 lgdstr = {'uncert','signal','fit'}; +0259 else +0260 lgdstr = {'signal','fit'}; +0261 end +0262 % switch data.invstd.invtype +0263 % case {'MUMO','NNLS'} +0264 % otherwise +0265 % end +0266 switch nmrproc.T1T2 +0267 case 'T1' +0268 lgh = legend(ax,lgdstr,'Location','NorthWest',... +0269 'Tag','fitlegend','FontSize',10); +0270 case 'T2' +0271 lgh = legend(ax,lgdstr,'Location','NorthEast',... +0272 'Tag','fitlegend','FontSize',10); 0273 end -0274 -0275 switch loglinx -0276 case 'x-axis -> lin' % log axes -0277 set(axE,'XScale','log','XLim',xlims); -0278 case 'x-axis -> log' % lin axes -0279 set(axE,'XScale','lin','XLim',xlims); -0280 end -0281 end -0282 % finalize -0283 beautifyAxes(fig); -0284 end -0285 -0286 %% if joint inversion is activated all NMR signals are plotted into the -0287 % "ALL (joint)" panel - this is just a rough overview if no joint inversion -0288 % result is yet availabe -0289 if isjoint && ~isfield(data.results,'invjoint') && ... -0290 ~strcmp(data.invstd.regtype,'lcurve') -0291 -0292 ax = gui.axes_handles.all; -0293 clearSingleAxis(ax); -0294 -0295 INVdata = getappdata(fig,'INVdata'); -0296 -0297 nINV = size(INVdata,1); -0298 E0 = zeros(nINV,1); -0299 c = 0; -0300 invlevels = 0; -0301 for i = 1:nINV -0302 if isstruct(INVdata{i}) -0303 c = c + 1; -0304 invlevels(c) = i; %#ok<AGROW> -0305 E0(i,1) = sum(INVdata{i}.results.invstd.E0); -0306 end -0307 end -0308 -0309 % the pressure / saturation data -0310 table = data.pressure.table; -0311 -0312 if size(table,1) == 1 & invlevels ~= 0 %#ok<AND2> -0313 % apparently no CPS data was loaded but joint inversion is -0314 % activated ... so just plot the data -0315 if invlevels == 0 -0316 levels = []; -0317 else -0318 levels = invlevels; -0319 S = E0(invlevels)./max(E0(invlevels)); -0320 end -0321 else -0322 uselevel = cell2mat(table(:,1)); -0323 tablelevels = 1:size(table,1); -0324 tablelevels = tablelevels(uselevel); -0325 S = cell2mat(table(:,3)); -0326 % if numel(S)~=nINV -0327 % % S() -0328 % end -0329 [isin,levels] = ismember(invlevels,tablelevels); -0330 levels = tablelevels(levels(isin)); -0331 end -0332 -0333 if ~isempty(levels) && levels(1) > 0 && c > 0 -0334 hold(ax,'on'); -0335 -0336 mycol = flipud(parula(128)); -0337 for i = 1:numel(levels) -0338 t = INVdata{levels(i)}.results.invstd.fit_t; -0339 s = INVdata{levels(i)}.results.invstd.fit_s; -0340 s = S(levels(i)).*(s./sum(INVdata{levels(i)}.results.invstd.E0)); -0341 if i == 1 -0342 xlims = [min(t) max(t)]; -0343 ylims = [min(s) max(s)]; -0344 else -0345 xlims = [min([xlims(1) min(t)]) max([xlims(2) max(t)])]; -0346 ylims = [min([ylims(1) min(s)]) max([ylims(2) max(s)])]; -0347 end -0348 colind = getColorIndex(S(levels(i)),128); -0349 plot(t,s,'LineStyle','-','Color',mycol(colind,:),'Parent',ax); -0350 end -0351 set(ax,'YLim',ylims); -0352 -0353 loglinx = get(gui.cm_handles.axes_all_xaxis,'Label'); -0354 switch loglinx -0355 case 'x-axis -> lin' % log axes -0356 ticks = floor(min(log10(nmrproc.t(nmrproc.t>0)))):1:ceil(log10(nmrproc.t(end))); -0357 set(ax,'XScale','log','XLim',xlims,'XTick',10.^ticks); -0358 case 'x-axis -> log' % lin axes -0359 set(ax,'XScale','lin','XLim',xlims,'XTickMode','auto'); -0360 end -0361 logliny = get(gui.cm_handles.axes_all_yaxis,'Label'); -0362 switch logliny -0363 case 'y-axis -> lin' % log axes -0364 set(ax,'YScale','log'); -0365 case 'y-axis -> log' % lin axes -0366 set(ax,'YScale','lin'); -0367 end -0368 end -0369 end -0370 -0371 % update GUI data -0372 setappdata(fig,'data',data); -0373 setappdata(fig,'gui',gui); -0374 -0375 end -0376 -0377 %------------- END OF CODE -------------- -0378 -0379 %% License: -0380 % MIT License -0381 % -0382 % Copyright (c) 2018 Thomas Hiller -0383 % -0384 % Permission is hereby granted, free of charge, to any person obtaining a copy -0385 % of this software and associated documentation files (the "Software"), to deal -0386 % in the Software without restriction, including without limitation the rights -0387 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0388 % copies of the Software, and to permit persons to whom the Software is -0389 % furnished to do so, subject to the following conditions: -0390 % -0391 % The above copyright notice and this permission notice shall be included in all -0392 % copies or substantial portions of the Software. -0393 % -0394 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0395 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0396 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0397 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0398 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0399 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0400 % SOFTWARE. +0274 set(lgh,'TextColor',gui.myui.colors.panelFG); +0275 end +0276 +0277 % grid +0278 grid(ax,'on'); +0279 +0280 %% residual plot +0281 if isfield(data.results,'invstd') +0282 col = gui.myui.colors.axisL; +0283 xlims = get(ax,'XLim'); +0284 line(xlims,[0 0],'LineStyle','--','LineWidth',1,'Color',col,'Parent',axE); +0285 if nmrproc.noise > 0 +0286 err_mean = mean(invstd.residual./nmrproc.e); +0287 err_std = std(invstd.residual./nmrproc.e); +0288 line(xlims,[err_mean-err_std err_mean-err_std],... +0289 'LineStyle','--','LineWidth',1,'Color','r','Parent',axE); +0290 line(xlims,[err_mean+err_std err_mean+err_std],... +0291 'LineStyle','--','LineWidth',1,'Color','r','Parent',axE); +0292 line(xlims,[-1 -1],'LineStyle','-.','LineWidth',1,... +0293 'Color',col,'Parent',axE); +0294 line(xlims,[1 1],'LineStyle','-.','LineWidth',1,... +0295 'Color',col,'Parent',axE); +0296 set(axE,'XTickLabel',''); +0297 set(axE,'YLim',[-2 2]); +0298 set(axE,'YTick',[-1 0 1],'YTickLabelMode','auto'); +0299 set(get(axE,'YLabel'),'String',{'noise';'weighted';'residuals'},... +0300 'FontWeight','normal'); +0301 else +0302 err_mean = mean(invstd.residual); +0303 err_std = std(invstd.residual); +0304 line(xlims,[err_mean-1*err_std err_mean-1*err_std],... +0305 'LineStyle','-.','LineWidth',1,'Color',col,'Parent',axE); +0306 line(xlims,[err_mean+1*err_std err_mean+1*err_std],... +0307 'LineStyle','-.','LineWidth',1,'Color',col,'Parent',axE); +0308 set(axE,'XTickLabel',''); +0309 set(axE,'YLim',[err_mean-3*err_std err_mean+3*err_std]); +0310 set(axE,'YTick',[err_mean-3*err_std 0 err_mean+3*err_std],... +0311 'YTickLabelMode','auto') +0312 set(get(axE,'YLabel'),'String','residuals',... +0313 'FontWeight','normal'); +0314 end +0315 +0316 switch loglinx +0317 case 'x-axis -> lin' % log axes +0318 set(axE,'XScale','log','XLim',xlims); +0319 case 'x-axis -> log' % lin axes +0320 set(axE,'XScale','lin','XLim',xlims); +0321 end +0322 end +0323 % finalize +0324 beautifyAxes(fig); +0325 end +0326 +0327 %% if joint inversion is activated all NMR signals are plotted into the +0328 % "ALL (joint)" panel - this is just a rough overview if no joint inversion +0329 % result is yet availabe +0330 if isjoint && ~isfield(data.results,'invjoint') && ... +0331 ~strcmp(data.invstd.regtype,'lcurve') +0332 +0333 ax = gui.axes_handles.all; +0334 clearSingleAxis(ax); +0335 +0336 INVdata = getappdata(fig,'INVdata'); +0337 +0338 nINV = size(INVdata,1); +0339 E0 = zeros(nINV,1); +0340 c = 0; +0341 invlevels = 0; +0342 for i = 1:nINV +0343 if isstruct(INVdata{i}) +0344 c = c + 1; +0345 invlevels(c) = i; %#ok<AGROW> +0346 E0(i,1) = sum(INVdata{i}.results.invstd.E0); +0347 end +0348 end +0349 +0350 % the pressure / saturation data +0351 table = data.pressure.table; +0352 +0353 if size(table,1) == 1 & invlevels ~= 0 %#ok<AND2> +0354 % apparently no CPS data was loaded but joint inversion is +0355 % activated ... so just plot the data +0356 if invlevels == 0 +0357 levels = []; +0358 else +0359 levels = invlevels; +0360 S = E0(invlevels)./max(E0(invlevels)); +0361 end +0362 else +0363 uselevel = cell2mat(table(:,1)); +0364 tablelevels = 1:size(table,1); +0365 tablelevels = tablelevels(uselevel); +0366 S = cell2mat(table(:,3)); +0367 % if numel(S)~=nINV +0368 % % S() +0369 % end +0370 [isin,levels] = ismember(invlevels,tablelevels); +0371 levels = tablelevels(levels(isin)); +0372 end +0373 +0374 if ~isempty(levels) && levels(1) > 0 && c > 0 +0375 hold(ax,'on'); +0376 +0377 mycol = flipud(parula(128)); +0378 for i = 1:numel(levels) +0379 t = INVdata{levels(i)}.results.invstd.fit_t; +0380 s = INVdata{levels(i)}.results.invstd.fit_s; +0381 s = S(levels(i)).*(s./sum(INVdata{levels(i)}.results.invstd.E0)); +0382 if i == 1 +0383 xlims = [min(t) max(t)]; +0384 ylims = [min(s) max(s)]; +0385 else +0386 xlims = [min([xlims(1) min(t)]) max([xlims(2) max(t)])]; +0387 ylims = [min([ylims(1) min(s)]) max([ylims(2) max(s)])]; +0388 end +0389 colind = getColorIndex(S(levels(i)),128); +0390 plot(t,s,'LineStyle','-','Color',mycol(colind,:),'Parent',ax); +0391 end +0392 set(ax,'YLim',ylims); +0393 +0394 loglinx = get(gui.cm_handles.axes_all_xaxis,'Label'); +0395 switch loglinx +0396 case 'x-axis -> lin' % log axes +0397 ticks = floor(min(log10(nmrproc.t(nmrproc.t>0)))):1:ceil(log10(nmrproc.t(end))); +0398 set(ax,'XScale','log','XLim',xlims,'XTick',10.^ticks); +0399 case 'x-axis -> log' % lin axes +0400 set(ax,'XScale','lin','XLim',xlims,'XTickMode','auto'); +0401 end +0402 logliny = get(gui.cm_handles.axes_all_yaxis,'Label'); +0403 switch logliny +0404 case 'y-axis -> lin' % log axes +0405 set(ax,'YScale','log'); +0406 case 'y-axis -> log' % lin axes +0407 set(ax,'YScale','lin'); +0408 end +0409 end +0410 end +0411 +0412 % update GUI data +0413 setappdata(fig,'data',data); +0414 setappdata(fig,'gui',gui); +0415 +0416 end +0417 +0418 %------------- END OF CODE -------------- +0419 +0420 %% License: +0421 % MIT License +0422 % +0423 % Copyright (c) 2018 Thomas Hiller +0424 % +0425 % Permission is hereby granted, free of charge, to any person obtaining a copy +0426 % of this software and associated documentation files (the "Software"), to deal +0427 % in the Software without restriction, including without limitation the rights +0428 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0429 % copies of the Software, and to permit persons to whom the Software is +0430 % furnished to do so, subject to the following conditions: +0431 % +0432 % The above copyright notice and this permission notice shall be included in all +0433 % copies or substantial portions of the Software. +0434 % +0435 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0436 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0437 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0438 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0439 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0440 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0441 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/updateStatusInformation.html b/doc/nucleus/functions/interface/updateStatusInformation.html index 56521a0..eb31287 100644 --- a/doc/nucleus/functions/interface/updateStatusInformation.html +++ b/doc/nucleus/functions/interface/updateStatusInformation.html @@ -50,8 +50,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv, NUCLEUSmod -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/interface/updateToolTips.html b/doc/nucleus/functions/interface/updateToolTips.html index 9b6f925..69b26ea 100644 --- a/doc/nucleus/functions/interface/updateToolTips.html +++ b/doc/nucleus/functions/interface/updateToolTips.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: NUCLEUSinv -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- @@ -114,120 +114,126 @@

    SOURCE CODE ^'<u>Available options:</u><br>',... 0045 '<b>Mono exp.</b> Mono-exponential fitting.<br>',... 0046 '<b>Several free exp. (2-5)</b> Multi-exponential fitting with up to 5 free relaxation times.<br>',... -0047 '<b>Multi exp. (LSQ)</b> Multi-exponential fitting with Optimization Toolbox.<br>',... -0048 '<b>Multi exp. (LU decomp.)</b> Multi-exponential fitting using a LU decomposition and Matlab''s "\"-operator.<br><br>',... -0049 'Depending on the chosen method there are additional options available.<br><br>',... -0050 '<u>Default value:</u><br>',... -0051 '<b>Multi exp. (LSQ)</b><br>']; -0052 reg_tstr = ['<HTML>Choose additional options depending on the chosen inversion (fitting) method.<br><br>',... -0053 '<u>Available options:</u><br>',... -0054 '<font color="red">Mono exp.:<br>',... -0055 '<font color="black"><b>none</b><br>',... -0056 '<font color="red">Several free exp. (2-5):<br>',... -0057 '<font color="black"><b>1-5</b> choose how many free relaxation times to use.<br>',... -0058 '<font color="red">Multi exp. (LSQ):<br>',... -0059 '<font color="black"><b>Manual</b> Manual regularization.<br>',... -0060 '<font color="black"><b>Tikhonov (GCV)</b> Tikhonov regularization (SVD-Toolbox).<br>',... -0061 '<font color="black"><b>TSVD (GCV)</b> Regularization via Truncated SVD (SVD-Toolbox).<br>',... -0062 '<font color="black"><b>DSVD (GCV)</b> Regularization via Damped SVD (SVD-Toolbox).<br>',... -0063 '<font color="black"><b>Discrep.</b> Regularization according to discrepancy principle (SVD-Toolbox).<br>',... -0064 '<font color="black"><b>L-curve</b> Perform the L-curve test to find optimal regularization parameter lambda.<br>',... -0065 '<font color="red">Multi exp. (LU decomp.):<br>',... -0066 '<font color="black"><b>Manual</b> Manual regularization.<br>',... -0067 '<font color="black"><b>Automatic</b> Automatic regularization.<br><br>',... -0068 '<u>Default value:</u><br>',... -0069 '<b>Manual</b><br>']; -0070 case 'lsqnonneg' -0071 inv_tstr = ['<HTML>Choose between different inversion (fitting) methods.<br><br>',... -0072 '<u>Available options:</u><br>',... -0073 '<b>Mono exp.</b> Mono-exponential fitting.<br>',... -0074 '<b>Several free exp. (2-5)</b> Multi-exponential fitting with up to 5 free relaxation times.<br>',... -0075 '<b>Multi exp. (LSQ)</b> Multi-exponential fitting with Non Negative Least Squares (LSQNONNEG).<br>',... -0076 '<b>Multi exp. (LU decomp.)</b> Multi-exponential fitting using a LU decomposition and Matlab''s "\"-operator.<br><br>',... -0077 'Depending on the chosen method there are additional options available.<br><br>',... -0078 '<u>Default value:</u><br>',... -0079 '<b>Multi exp. (LSQ)</b><br>']; -0080 reg_tstr = ['<HTML>Choose additional options depending on the chosen inversion (fitting) method.<br><br>',... -0081 '<u>Available options:</u><br>',... -0082 '<font color="red">Mono exp.:<br>',... -0083 '<font color="black"><b>none</b><br>',... -0084 '<font color="red">Several free exp. (2-5):<br>',... -0085 '<font color="black"><b>1-5</b> choose how many free relaxation times to use.<br>',... -0086 '<font color="red">Multi exp. (LSQ):<br>',... -0087 '<font color="black"><b>Manual</b> Manual regularization.<br>',... -0088 '<font color="black"><b>Tikhonov (GCV)</b> Tikhonov regularization (SVD-Toolbox).<br>',... -0089 '<font color="black"><b>TSVD (GCV)</b> Regularization via Truncated SVD (SVD-Toolbox).<br>',... -0090 '<font color="black"><b>DSVD (GCV)</b> Regularization via Damped SVD (SVD-Toolbox).<br>',... -0091 '<font color="black"><b>Discrep.</b> Regularization according to discrepancy principle (SVD-Toolbox).<br>',... -0092 '<font color="black"><b>L-curve</b> Perform the L-curve test to find optimal regularization parameter lambda.<br>',... -0093 '<font color="red">Multi exp. (LU decomp.):<br>',... -0094 '<font color="black"><b>Manual</b> Manual regularization.<br>',... -0095 '<font color="black"><b>Automatic</b> Automatic regularization.<br><br>',... -0096 '<u>Default value:</u><br>',... -0097 '<b>Manual</b><br>']; -0098 end -0099 case 'off' -0100 inv_tstr = ['<HTML>Choose between different inversion (fitting) methods.<br><br>',... -0101 '<u>Available options:</u><br>',... -0102 '<b>Mono exp.</b> Mono-exponential fitting.<br>',... -0103 '<b>Several free exp. (2-5).</b> Multi-exponential fitting with up to 5 free relaxation times.<br>',... -0104 '<b>Multi exp. (LSQ)</b> Multi-exponential fitting with Non Negative Least Squares (LSQNONNEG).<br><br>',... -0105 'Depending on the chosen method there are additional options available.<br><br>',... -0106 '<u>Default value:</u><br>',... -0107 '<b>Multi exp. (LSQ)</b><br>']; -0108 reg_tstr = ['<HTML>Choose additional options depending on the chosen inversion (fitting) method.<br><br>',... -0109 '<u>Available options:</u><br>',... -0110 '<font color="red">Mono exp.:<br>',... -0111 '<font color="black"><b>none</b><br>',... -0112 '<font color="red">Several free exp. (2-5):<br>',... -0113 '<font color="black"><b>1-5</b> choose how many free relaxation times to use.<br>',... -0114 '<font color="red">Multi exp. (LSQ):<br>',... -0115 '<font color="black"><b>Manual</b> Manual regularization.<br>',... -0116 '<font color="black"><b>L-curve</b> Perform the L-curve test to find optimal regularization parameter lambda.<br><br>',... -0117 '<u>Default value:</u><br>',... -0118 '<b>Manual</b><br>']; -0119 end -0120 % update the tool tips -0121 set(gui.popup_handles.invstd_InvType,'UserData',struct('Tooltipstr',inv_tstr)); -0122 set(gui.popup_handles.invstd_InvTypeOpt,'UserData',struct('Tooltipstr',reg_tstr)); -0123 -0124 % update GUI data -0125 setappdata(fig,'gui',gui); -0126 setappdata(fig,'data',data); -0127 % if tool tips are activated they need to be updated on-the-fly -0128 switch data.info.ToolTips -0129 case 'on' -0130 switchToolTips(gui,'on'); -0131 otherwise -0132 % nothing to do -0133 end -0134 -0135 end -0136 -0137 %------------- END OF CODE -------------- -0138 -0139 %% License: -0140 % MIT License -0141 % -0142 % Copyright (c) 2019 Thomas Hiller -0143 % -0144 % Permission is hereby granted, free of charge, to any person obtaining a copy -0145 % of this software and associated documentation files (the "Software"), to deal -0146 % in the Software without restriction, including without limitation the rights -0147 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0148 % copies of the Software, and to permit persons to whom the Software is -0149 % furnished to do so, subject to the following conditions: -0150 % -0151 % The above copyright notice and this permission notice shall be included in all -0152 % copies or substantial portions of the Software. -0153 % -0154 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0155 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0156 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0157 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0158 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0159 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0160 % SOFTWARE. +0047 '<b>Multi exp. (LSQ)</b> Multi-exponential fitting using the Optimization Toolbox.<br>',... +0048 '<b>Multi exp. (LU decomp.)</b> Multi-exponential fitting using a LU decomposition and Matlab''s "\"-operator.<br>',... +0049 '<b>Multi modal</b> Multi modal fitting using the Optimization Toolbox.<br><br>',... +0050 'Depending on the chosen method there are additional options available.<br><br>',... +0051 '<u>Default value:</u><br>',... +0052 '<b>Multi exp. (LSQ)</b><br>']; +0053 reg_tstr = ['<HTML>Choose additional options depending on the chosen inversion (fitting) method.<br><br>',... +0054 '<u>Available options:</u><br>',... +0055 '<font color="red">Mono exp.:<br>',... +0056 '<font color="black"><b>none</b><br>',... +0057 '<font color="red">Several free exp. (2-5):<br>',... +0058 '<font color="black"><b>1-5</b> choose how many free relaxation times to use.<br>',... +0059 '<font color="red">Multi exp. (LSQ):<br>',... +0060 '<font color="black"><b>Manual</b> Manual regularization.<br>',... +0061 '<font color="black"><b>Tikhonov (GCV)</b> Tikhonov regularization (SVD-Toolbox).<br>',... +0062 '<font color="black"><b>TSVD (GCV)</b> Regularization via Truncated SVD (SVD-Toolbox).<br>',... +0063 '<font color="black"><b>DSVD (GCV)</b> Regularization via Damped SVD (SVD-Toolbox).<br>',... +0064 '<font color="black"><b>Discrep.</b> Regularization according to discrepancy principle (SVD-Toolbox).<br>',... +0065 '<font color="black"><b>L-curve</b> Perform the L-curve test to find optimal regularization parameter lambda.<br>',... +0066 '<font color="red">Multi exp. (LU decomp.):<br>',... +0067 '<font color="black"><b>Manual</b> Manual regularization.<br>',... +0068 '<font color="black"><b>Automatic</b> Automatic regularization.<br>',... +0069 '<font color="red">Multi modal:<br>',... +0070 '<font color="black"><b>1-4</b> choose how many modes to use.<br><br>',... +0071 '<u>Default value:</u><br>',... +0072 '<b>Manual</b><br>']; +0073 case 'lsqnonneg' +0074 inv_tstr = ['<HTML>Choose between different inversion (fitting) methods.<br><br>',... +0075 '<u>Available options:</u><br>',... +0076 '<b>Mono exp.</b> Mono-exponential fitting.<br>',... +0077 '<b>Several free exp. (2-5)</b> Multi-exponential fitting with up to 5 free relaxation times.<br>',... +0078 '<b>Multi exp. (LSQ)</b> Multi-exponential fitting with Non Negative Least Squares (LSQNONNEG).<br>',... +0079 '<b>Multi exp. (LU decomp.)</b> Multi-exponential fitting using a LU decomposition and Matlab''s "\"-operator.<br>',... +0080 '<b>Multi modal</b> Multi modal fitting using fminsearchbnd.<br><br>',... +0081 'Depending on the chosen method there are additional options available.<br><br>',... +0082 '<u>Default value:</u><br>',... +0083 '<b>Multi exp. (LSQ)</b><br>']; +0084 reg_tstr = ['<HTML>Choose additional options depending on the chosen inversion (fitting) method.<br><br>',... +0085 '<u>Available options:</u><br>',... +0086 '<font color="red">Mono exp.:<br>',... +0087 '<font color="black"><b>none</b><br>',... +0088 '<font color="red">Several free exp. (2-5):<br>',... +0089 '<font color="black"><b>1-5</b> choose how many free relaxation times to use.<br>',... +0090 '<font color="red">Multi exp. (LSQ):<br>',... +0091 '<font color="black"><b>Manual</b> Manual regularization.<br>',... +0092 '<font color="black"><b>Tikhonov (GCV)</b> Tikhonov regularization (SVD-Toolbox).<br>',... +0093 '<font color="black"><b>TSVD (GCV)</b> Regularization via Truncated SVD (SVD-Toolbox).<br>',... +0094 '<font color="black"><b>DSVD (GCV)</b> Regularization via Damped SVD (SVD-Toolbox).<br>',... +0095 '<font color="black"><b>Discrep.</b> Regularization according to discrepancy principle (SVD-Toolbox).<br>',... +0096 '<font color="black"><b>L-curve</b> Perform the L-curve test to find optimal regularization parameter lambda.<br>',... +0097 '<font color="red">Multi exp. (LU decomp.):<br>',... +0098 '<font color="black"><b>Manual</b> Manual regularization.<br>',... +0099 '<font color="black"><b>Automatic</b> Automatic regularization.<br>',... +0100 '<font color="red">Multi modal:<br>',... +0101 '<font color="black"><b>1-4</b> choose how many modes to use.<br><br>',... +0102 '<u>Default value:</u><br>',... +0103 '<b>Manual</b><br>']; +0104 end +0105 case 'off' +0106 inv_tstr = ['<HTML>Choose between different inversion (fitting) methods.<br><br>',... +0107 '<u>Available options:</u><br>',... +0108 '<b>Mono exp.</b> Mono-exponential fitting.<br>',... +0109 '<b>Several free exp. (2-5).</b> Multi-exponential fitting with up to 5 free relaxation times.<br>',... +0110 '<b>Multi exp. (LSQ)</b> Multi-exponential fitting with Non Negative Least Squares (LSQNONNEG).<br><br>',... +0111 'Depending on the chosen method there are additional options available.<br><br>',... +0112 '<u>Default value:</u><br>',... +0113 '<b>Multi exp. (LSQ)</b><br>']; +0114 reg_tstr = ['<HTML>Choose additional options depending on the chosen inversion (fitting) method.<br><br>',... +0115 '<u>Available options:</u><br>',... +0116 '<font color="red">Mono exp.:<br>',... +0117 '<font color="black"><b>none</b><br>',... +0118 '<font color="red">Several free exp. (2-5):<br>',... +0119 '<font color="black"><b>1-5</b> choose how many free relaxation times to use.<br>',... +0120 '<font color="red">Multi exp. (LSQ):<br>',... +0121 '<font color="black"><b>Manual</b> Manual regularization.<br>',... +0122 '<font color="black"><b>L-curve</b> Perform the L-curve test to find optimal regularization parameter lambda.<br><br>',... +0123 '<u>Default value:</u><br>',... +0124 '<b>Manual</b><br>']; +0125 end +0126 % update the tool tips +0127 set(gui.popup_handles.invstd_InvType,'UserData',struct('Tooltipstr',inv_tstr)); +0128 set(gui.popup_handles.invstd_InvTypeOpt,'UserData',struct('Tooltipstr',reg_tstr)); +0129 +0130 % update GUI data +0131 setappdata(fig,'gui',gui); +0132 setappdata(fig,'data',data); +0133 % if tool tips are activated they need to be updated on-the-fly +0134 switch data.info.ToolTips +0135 case 'on' +0136 switchToolTips(gui,'on'); +0137 otherwise +0138 % nothing to do +0139 end +0140 +0141 end +0142 +0143 %------------- END OF CODE -------------- +0144 +0145 %% License: +0146 % MIT License +0147 % +0148 % Copyright (c) 2019 Thomas Hiller +0149 % +0150 % Permission is hereby granted, free of charge, to any person obtaining a copy +0151 % of this software and associated documentation files (the "Software"), to deal +0152 % in the Software without restriction, including without limitation the rights +0153 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0154 % copies of the Software, and to permit persons to whom the Software is +0155 % furnished to do so, subject to the following conditions: +0156 % +0157 % The above copyright notice and this permission notice shall be included in all +0158 % copies or substantial portions of the Software. +0159 % +0160 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0161 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0162 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0163 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0164 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0165 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0166 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/interface/useSignalAsCalibration.html b/doc/nucleus/functions/interface/useSignalAsCalibration.html index af5e10c..6d94f18 100644 --- a/doc/nucleus/functions/interface/useSignalAsCalibration.html +++ b/doc/nucleus/functions/interface/useSignalAsCalibration.html @@ -50,15 +50,15 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • calibratePorosity determines a sample's porosity from a calibration
  • displayStatusText shows status information either in the GUI or on the
  • This function is called by: @@ -92,8 +92,8 @@

    SOURCE CODE ^% none 0024 % 0025 % See also: NUCLEUSinv -0026 % Author: Thomas Hiller -0027 % email: thomas.hiller[at]leibniz-liag.de +0026 % Author: see AUTHORS.md +0027 % email: see AUTHORS.md 0028 % License: MIT License (at end) 0029 0030 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/applyGatesToSignal.html b/doc/nucleus/functions/inversion/applyGatesToSignal.html index 5779130..57ac6db 100644 --- a/doc/nucleus/functions/inversion/applyGatesToSignal.html +++ b/doc/nucleus/functions/inversion/applyGatesToSignal.html @@ -59,8 +59,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0033 % 0034 % See also: -0035 % Author: Thomas Hiller -0036 % email: thomas.hiller[at]leibniz-liag.de +0035 % Author: see AUTHORS.md +0036 % email: see AUTHORS.md 0037 % License: MIT License (at end) 0038 0039 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/applyRegularization.html b/doc/nucleus/functions/inversion/applyRegularization.html index e2b8cd3..a2db257 100644 --- a/doc/nucleus/functions/inversion/applyRegularization.html +++ b/doc/nucleus/functions/inversion/applyRegularization.html @@ -64,8 +64,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0038 % 0039 % See also: -0040 % Author: Thomas Hiller -0041 % email: thomas.hiller[at]leibniz-liag.de +0040 % Author: see AUTHORS.md +0041 % email: see AUTHORS.md 0042 % License: MIT License (at end) 0043 0044 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/createKernelMatrix.html b/doc/nucleus/functions/inversion/createKernelMatrix.html index d562c4c..fa9799a 100644 --- a/doc/nucleus/functions/inversion/createKernelMatrix.html +++ b/doc/nucleus/functions/inversion/createKernelMatrix.html @@ -23,7 +23,7 @@

    PURPOSE ^ creates a Kernel matrix from signal time vector "t"

    SYNOPSIS ^

    -
    function K = createKernelMatrix(t,T,Tbulk,Tflag,T1IRfac)
    +
    function K = createKernelMatrix(t,T,Tbulk,Tdiff,Tflag,T1IRfac)

    DESCRIPTION ^

    createKernelMatrix creates a Kernel matrix from signal time vector "t"
    @@ -36,6 +36,7 @@ 

    DESCRIPTION ^DESCRIPTION ^DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 </ul>
 This function is called by:
 <ul style= -
  • fitDataLSQ is a control routine that fits NMR data multi-exponentially;
  • fitDataLUdecomp is a control routine that uses a LU decomposition and the
  • +
  • estimateUncertainty calculates pseudo uncertainty estimates for multi
  • fcn_fitMultiModal is the objective function for N free distribution
  • fitDataLSQ is a control routine that fits NMR data multi-exponentially;
  • fitDataLUdecomp is a control routine that uses a LU decomposition and the
  • fitDataMultiModal is a control routine that uses either 'lsqnonlin' or
  • SOURCE CODE ^

    -
    0001 function K = createKernelMatrix(t,T,Tbulk,Tflag,T1IRfac)
    +
    0001 function K = createKernelMatrix(t,T,Tbulk,Tdiff,Tflag,T1IRfac)
     0002 %createKernelMatrix creates a Kernel matrix from signal time vector "t"
     0003 %and relaxation time vector "T"
     0004 %
    @@ -83,70 +84,71 @@ 

    SOURCE CODE ^% t - signal time vector 0010 % T - relaxation times vector 0011 % Tbulk - bulk relaxation time -0012 % Tflag - 'T1' or 'T2' -0013 % T1IRfac - 1 or 2 (Sat. or Inv. Recovery) -0014 % -0015 % Outputs: -0016 % K - Kernel matrix size(length(t),length(T)) -0017 % -0018 % Example: -0019 % K = createKernelMatrix(t,T,2,'T1') -0020 % -0021 % Other m-files required: -0022 % none -0023 % -0024 % Subfunctions: -0025 % none -0026 % -0027 % MAT-files required: -0028 % none -0029 % -0030 % See also: -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de -0033 % License: MIT License (at end) -0034 -0035 %------------- BEGIN CODE -------------- -0036 -0037 %% init data -0038 K = zeros(length(t),length(T)); -0039 tr = repmat(t(:),[1,numel(T)]); -0040 Tr = repmat(T,[numel(t),1]); -0041 -0042 %% calculate K -0043 switch Tflag -0044 case 'T1' -0045 K = 1-T1IRfac.*(exp(-tr./Tr).*exp(-tr./Tbulk)); -0046 case 'T2' -0047 K = exp(-tr./Tr).*exp(-tr./Tbulk); -0048 end -0049 -0050 return -0051 -0052 %------------- END OF CODE -------------- -0053 -0054 %% License: -0055 % MIT License -0056 % -0057 % Copyright (c) 2018 Thomas Hiller -0058 % -0059 % Permission is hereby granted, free of charge, to any person obtaining a copy -0060 % of this software and associated documentation files (the "Software"), to deal -0061 % in the Software without restriction, including without limitation the rights -0062 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0063 % copies of the Software, and to permit persons to whom the Software is -0064 % furnished to do so, subject to the following conditions: -0065 % -0066 % The above copyright notice and this permission notice shall be included in all -0067 % copies or substantial portions of the Software. -0068 % -0069 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0070 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0071 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0072 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0073 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0074 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0075 % SOFTWARE.

    +0012 % Tdiff - diffusion relaxation time +0013 % Tflag - 'T1' or 'T2' +0014 % T1IRfac - 1 or 2 (Sat. or Inv. Recovery) +0015 % +0016 % Outputs: +0017 % K - Kernel matrix size(length(t),length(T)) +0018 % +0019 % Example: +0020 % K = createKernelMatrix(t,T,2,3,'T1',1) +0021 % +0022 % Other m-files required: +0023 % none +0024 % +0025 % Subfunctions: +0026 % none +0027 % +0028 % MAT-files required: +0029 % none +0030 % +0031 % See also: +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md +0034 % License: MIT License (at end) +0035 +0036 %------------- BEGIN CODE -------------- +0037 +0038 %% init data +0039 K = zeros(length(t),length(T)); +0040 tr = repmat(t(:),[1,numel(T)]); +0041 Tr = repmat(T,[numel(t),1]); +0042 +0043 %% calculate K +0044 switch Tflag +0045 case 'T1' +0046 K = 1-T1IRfac.*(exp(-tr./Tr).*exp(-tr./Tbulk).*exp(-tr./Tdiff)); +0047 case 'T2' +0048 K = exp(-tr./Tr).*exp(-tr./Tbulk).*exp(-tr./Tdiff); +0049 end +0050 +0051 return +0052 +0053 %------------- END OF CODE -------------- +0054 +0055 %% License: +0056 % MIT License +0057 % +0058 % Copyright (c) 2018 Thomas Hiller +0059 % +0060 % Permission is hereby granted, free of charge, to any person obtaining a copy +0061 % of this software and associated documentation files (the "Software"), to deal +0062 % in the Software without restriction, including without limitation the rights +0063 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0064 % copies of the Software, and to permit persons to whom the Software is +0065 % furnished to do so, subject to the following conditions: +0066 % +0067 % The above copyright notice and this permission notice shall be included in all +0068 % copies or substantial portions of the Software. +0069 % +0070 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0071 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0072 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0073 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0074 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0075 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0076 % SOFTWARE.

    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/estimateJacobian.html b/doc/nucleus/functions/inversion/estimateJacobian.html new file mode 100644 index 0000000..0e2f4e0 --- /dev/null +++ b/doc/nucleus/functions/inversion/estimateJacobian.html @@ -0,0 +1,153 @@ + + + + Description of estimateJacobian + + + + + + + + + + + +

    estimateJacobian +

    + +

    PURPOSE ^

    +
    numerically estimates (in a very simple manner) a
    + +

    SYNOPSIS ^

    +
    function J = estimateJacobian(f,x)
    + +

    DESCRIPTION ^

    +
    estimateJacobian numerically estimates (in a very simple manner) a
    +Jacobian at point x for a given function f
    +
    + Syntax:
    +       estimateJacobian
    +
    + Inputs:
    +       f - function handle
    +       x - point on function f
    +
    + Outputs:
    +       J - Jacobian
    +
    + Example:
    +       estimateJacobian(@(x)fcn_fitMultiModal(x,iparam),x);
    +
    + Other m-files required:
    +       none
    +
    + Subfunctions:
    +       none
    +
    + MAT-files required:
    +       none
    +
    + See also: NUCLEUSinv
    + Author: see AUTHORS.md
    + email: see AUTHORS.md
    + License: MIT License (at end)
    + + +

    CROSS-REFERENCE INFORMATION ^

    +This function calls: +
      +
    +This function is called by: + + + + + +

    SOURCE CODE ^

    +
    0001 function J = estimateJacobian(f,x)
    +0002 %estimateJacobian numerically estimates (in a very simple manner) a
    +0003 %Jacobian at point x for a given function f
    +0004 %
    +0005 % Syntax:
    +0006 %       estimateJacobian
    +0007 %
    +0008 % Inputs:
    +0009 %       f - function handle
    +0010 %       x - point on function f
    +0011 %
    +0012 % Outputs:
    +0013 %       J - Jacobian
    +0014 %
    +0015 % Example:
    +0016 %       estimateJacobian(@(x)fcn_fitMultiModal(x,iparam),x);
    +0017 %
    +0018 % Other m-files required:
    +0019 %       none
    +0020 %
    +0021 % Subfunctions:
    +0022 %       none
    +0023 %
    +0024 % MAT-files required:
    +0025 %       none
    +0026 %
    +0027 % See also: NUCLEUSinv
    +0028 % Author: see AUTHORS.md
    +0029 % email: see AUTHORS.md
    +0030 % License: MIT License (at end)
    +0031 
    +0032 %------------- BEGIN CODE --------------
    +0033 
    +0034 % define increment
    +0035 delta = 1e-7*sqrt(norm(x));
    +0036 % evaluate function at point x
    +0037 y = feval(f,x);
    +0038 % get dimensions of J
    +0039 n = length(y);
    +0040 m = length(x);
    +0041 % initialize J
    +0042 J = zeros(n,m);
    +0043 % loop over paramters
    +0044 for i = 1:m
    +0045     dx = zeros(1,m);
    +0046     dx(i) = delta/2;
    +0047     % evaluate single parameters at x+dx and x-dx
    +0048     % and divide the differenece by the increment
    +0049     col = (feval(f,x+dx)-feval(f,x-dx))/delta;
    +0050     % save result
    +0051     J(:,i) = col;
    +0052 end
    +0053 
    +0054 return
    +0055 
    +0056 %------------- END OF CODE --------------
    +0057 
    +0058 %% License:
    +0059 % MIT License
    +0060 %
    +0061 % Copyright (c) 2022 Thomas Hiller
    +0062 %
    +0063 % Permission is hereby granted, free of charge, to any person obtaining a copy
    +0064 % of this software and associated documentation files (the "Software"), to deal
    +0065 % in the Software without restriction, including without limitation the rights
    +0066 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +0067 % copies of the Software, and to permit persons to whom the Software is
    +0068 % furnished to do so, subject to the following conditions:
    +0069 %
    +0070 % The above copyright notice and this permission notice shall be included in all
    +0071 % copies or substantial portions of the Software.
    +0072 %
    +0073 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +0074 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +0075 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +0076 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +0077 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +0078 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +0079 % SOFTWARE.
    +
    Generated by m2html © 2005
    + + \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/estimateUncertainty.html b/doc/nucleus/functions/inversion/estimateUncertainty.html new file mode 100644 index 0000000..ccbded2 --- /dev/null +++ b/doc/nucleus/functions/inversion/estimateUncertainty.html @@ -0,0 +1,606 @@ + + + + Description of estimateUncertainty + + + + + + + + + + + +

    estimateUncertainty +

    + +

    PURPOSE ^

    +
    calculates pseudo uncertainty estimates for multi
    + +

    SYNOPSIS ^

    +
    function [invstd,uncert] = estimateUncertainty(invtype,invstd,iparam,parameter)
    + +

    DESCRIPTION ^

    +
    estimateUncertainty calculates pseudo uncertainty estimates for multi
    +modal and LSQ inversion results
    +
    + Syntax:
    +       estimateUncertainty(invtype,invstd,iparam,parameter)
    +
    + Inputs:
    +       invtype - string indicating the inversion method of the optimal
    +                 fit ('NNLS' or 'MUMO')
    +       invstd - struct holding inversion results of the optimal fit
    +       iparam - struct holding original inversion settings
    +       parameter - struct that holds settings:
    +                   uncertMethod : which calculation method to use for
    +                                  'MUMO' the options are 'thresh' and 'ci' for
    +                                  'NNLS' the options are 'RTD_var', 'Lambda',
    +                                  'RMS_bound' and 'RMS_free'
    +                   uncertThresh : threshold for uncertainty search range
    +                   uncertChi2   : stop criteria for the chi2 deviation
    +                   uncertN      : number of models to calculate
    +                   uncertMax    : total number of unsuccessful attempts
    +                                  after which the calculation is stopped
    +
    + Outputs:
    +       invstd - same as input struct
    +       uncert - uncertainty data
    +
    + Example:
    +       [invstd] = estimateUncertainty('MUMO',invstd,iparam,uparam)
    +
    + Other m-files required:
    +       createKernelMatrix
    +       displayStatusText
    +       fitDataLSQ
    +       getFitErrors
    +
    + Subfunctions:
    +       none
    +
    + MAT-files required:
    +       none
    +
    + See also:
    + Author: see AUTHORS.md
    + email: see AUTHORS.md
    + License: MIT License (at end)
    + + +

    CROSS-REFERENCE INFORMATION ^

    +This function calls: + +This function is called by: + + + + + +

    SOURCE CODE ^

    +
    0001 function [invstd,uncert] = estimateUncertainty(invtype,invstd,iparam,parameter)
    +0002 %estimateUncertainty calculates pseudo uncertainty estimates for multi
    +0003 %modal and LSQ inversion results
    +0004 %
    +0005 % Syntax:
    +0006 %       estimateUncertainty(invtype,invstd,iparam,parameter)
    +0007 %
    +0008 % Inputs:
    +0009 %       invtype - string indicating the inversion method of the optimal
    +0010 %                 fit ('NNLS' or 'MUMO')
    +0011 %       invstd - struct holding inversion results of the optimal fit
    +0012 %       iparam - struct holding original inversion settings
    +0013 %       parameter - struct that holds settings:
    +0014 %                   uncertMethod : which calculation method to use for
    +0015 %                                  'MUMO' the options are 'thresh' and 'ci' for
    +0016 %                                  'NNLS' the options are 'RTD_var', 'Lambda',
    +0017 %                                  'RMS_bound' and 'RMS_free'
    +0018 %                   uncertThresh : threshold for uncertainty search range
    +0019 %                   uncertChi2   : stop criteria for the chi2 deviation
    +0020 %                   uncertN      : number of models to calculate
    +0021 %                   uncertMax    : total number of unsuccessful attempts
    +0022 %                                  after which the calculation is stopped
    +0023 %
    +0024 % Outputs:
    +0025 %       invstd - same as input struct
    +0026 %       uncert - uncertainty data
    +0027 %
    +0028 % Example:
    +0029 %       [invstd] = estimateUncertainty('MUMO',invstd,iparam,uparam)
    +0030 %
    +0031 % Other m-files required:
    +0032 %       createKernelMatrix
    +0033 %       displayStatusText
    +0034 %       fitDataLSQ
    +0035 %       getFitErrors
    +0036 %
    +0037 % Subfunctions:
    +0038 %       none
    +0039 %
    +0040 % MAT-files required:
    +0041 %       none
    +0042 %
    +0043 % See also:
    +0044 % Author: see AUTHORS.md
    +0045 % email: see AUTHORS.md
    +0046 % License: MIT License (at end)
    +0047 
    +0048 %------------- BEGIN CODE --------------
    +0049 
    +0050 %% get GUI handle and data
    +0051 fig = findobj('Tag','INV');
    +0052 if ~isempty(fig)
    +0053     gui = getappdata(fig,'gui');
    +0054 else
    +0055     % this routine will sill call 'displayStatusText' but then the output
    +0056     % is displayed at the command line
    +0057     gui = 0;
    +0058 end
    +0059 
    +0060 % get the main parameters
    +0061 uncertMethod = parameter.uncertMethod;
    +0062 uncertChi2 = parameter.uncertChi2;
    +0063 uncertThresh = parameter.uncertThresh;
    +0064 uncertN = parameter.uncertN;
    +0065 uncertMax = parameter.uncertMax;
    +0066 
    +0067 % original data that was fitted
    +0068 time = parameter.time;
    +0069 signal = parameter.signal;
    +0070 
    +0071 % kernel matrices for pure (single) E0 estimation and a second one
    +0072 % that extends the original time vector to "0" -> needed for nicer plots of
    +0073 % uncertainty towards shorter times
    +0074 switch iparam.T1T2
    +0075     case 'T1'
    +0076         K0 = createKernelMatrix(10*time(end),invstd.T1T2me',...
    +0077             iparam.Tb,iparam.Td,'T1',iparam.T1IRfac);
    +0078         
    +0079         time0 = [time' 2*time(end) 5*time(end) 10*time(end)];
    +0080         K0f = createKernelMatrix(time0,invstd.T1T2me',...
    +0081             iparam.Tb,iparam.Td,'T1',iparam.T1IRfac);
    +0082     case 'T2'
    +0083         K0 = createKernelMatrix(0,invstd.T1T2me',iparam.Tb,...
    +0084             iparam.Td,'T2',iparam.T1IRfac);
    +0085         
    +0086         time0 = [0 1e-6 time(1)/10 time(1)/5 time(1)/3 time(1)/2 time'];
    +0087         K0f = createKernelMatrix(time0,invstd.T1T2me',iparam.Tb,...
    +0088             iparam.Td,'T2',iparam.T1IRfac);
    +0089 end
    +0090 
    +0091 % switch depending on inversion method
    +0092 switch invtype
    +0093     case 'MUMO'
    +0094         % data needed from the optimal fit
    +0095         T = invstd.T;
    +0096         S = invstd.S;
    +0097         E = invstd.E;
    +0098         x = invstd.x;
    +0099         lb = invstd.lb;
    +0100         ub = invstd.ub;
    +0101         ci = invstd.ci;
    +0102         
    +0103         % kernel for the original fit needed for comparison of the uncertainty models
    +0104         K = createKernelMatrix(time,invstd.T1T2me',iparam.Tb,iparam.Td,...
    +0105             iparam.T1T2,iparam.T1IRfac);
    +0106         
    +0107         % counter
    +0108         count = 0;
    +0109         countm = 0;
    +0110         
    +0111         % initialize variables
    +0112         TDIST = zeros(uncertN,numel(invstd.T1T2me));
    +0113         SINTERP = zeros(numel(time0),uncertN);
    +0114         E0INTERP = zeros(uncertN,1);
    +0115         % calculate uncertainty models
    +0116         while count < uncertN
    +0117             switch uncertMethod
    +0118                 case 'thresh'
    +0119                     % randomly vary all parameters +- thresh
    +0120                     a = 1-uncertThresh;
    +0121                     b = 1+uncertThresh;
    +0122                     rr = (b-a).*rand(1,length(ci)) + a;
    +0123                     Ti = log(T).*rr(1:3:end); % do it on log-scale
    +0124                     Si = S.*rr(2:3:end);
    +0125                     Ei = E.*rr(3:3:end);
    +0126                     
    +0127                     xi = zeros(size(x));
    +0128                     xi(1:3:end) = Ti;
    +0129                     xi(2:3:end) = Si;
    +0130                     xi(3:3:end) = Ei;
    +0131                 case 'ci'
    +0132                     % randomly vary parameters within confidence interval
    +0133                     rr = 2.*rand(1,length(ci))-1;
    +0134                     xi = zeros(size(x));
    +0135                     xi(1:3:end) = log(T);
    +0136                     xi(2:3:end) = S;
    +0137                     xi(3:3:end) = E;
    +0138                     xi = xi+ci'.*rr;
    +0139             end
    +0140             
    +0141             % adjust for bounds if necessary
    +0142             xi(xi<lb) = lb(xi<lb);
    +0143             xi(xi>ub) = lb(xi>ub);
    +0144             
    +0145             % temporary values
    +0146             Ti = exp(xi(1:3:end)); % transform back to lin-scale
    +0147             Si = xi(2:3:end);
    +0148             Ei = xi(3:3:end);
    +0149             
    +0150             % create a temporary distribution with the new parameters
    +0151             TdistI = 0;
    +0152             for i = 1:numel(T)
    +0153                 tmp = 1./( Si(i)*sqrt(2*pi)).*exp(-((log(invstd.T1T2me') - log(Ti(i)))/ sqrt(2)/Si(i)).^2);
    +0154                 % scale to amplitude
    +0155                 if sum(tmp)>0
    +0156                     tmp = (tmp/sum(tmp)) * Ei(i);
    +0157                 end
    +0158                 % add the tmp per mu to Tdist
    +0159                 TdistI = TdistI + tmp;
    +0160             end
    +0161             % calculate temporary signal(s)
    +0162             s_interp = K*TdistI';
    +0163             s0_interp = K0f*TdistI';
    +0164             
    +0165             % get residuals and error measures
    +0166             if isfield(iparam,'W')
    +0167                 % when signal gating was used the error estimates need to be adjusted
    +0168                 outI = getFitErrors(signal,s_interp,iparam.noise,iparam.W);
    +0169             else
    +0170                 outI = getFitErrors(signal,s_interp,iparam.noise);
    +0171             end
    +0172             
    +0173             % check if the temporary chi2 is within the desired limit
    +0174             if abs(1-outI.chi2/invstd.chi2) <= uncertChi2
    +0175                 % if YES then keep it
    +0176                 count = count + 1;
    +0177                 % save RTD
    +0178                 TDIST(count,:) = TdistI;
    +0179                 % save signal
    +0180                 SINTERP(:,count) = s0_interp;
    +0181                 % save E0
    +0182                 E0INTERP(count,1) = K0*TdistI';
    +0183                 % status bar info
    +0184                 infostring = ['Calculating uncertainty models: ',...
    +0185                     num2str(count),' / ',num2str(uncertN)];
    +0186                 displayStatusText(gui,infostring);
    +0187                 % reset max counter
    +0188                 countm = 0;
    +0189             else
    +0190                 % as long as we did not find a model keep counting
    +0191                 if count < 1
    +0192                     countm = countm + 1;
    +0193                     infostring = ['Trying to find uncertainty model: ',...
    +0194                         num2str(countm),' / ',num2str(uncertMax)];
    +0195                     displayStatusText(gui,infostring);
    +0196                 end
    +0197             end
    +0198             % after to many unsuccessful attempts STOP
    +0199             if countm > uncertMax
    +0200                 infostring = ['No uncertainty model found: ',...
    +0201                     num2str(countm),' / ',num2str(uncertMax)];
    +0202                 displayStatusText(gui,infostring);
    +0203                 break;
    +0204             end
    +0205         end
    +0206         
    +0207         % output data
    +0208         % simple E0 confidence interval
    +0209         invstd.ciE0 = 2*std(E0INTERP);
    +0210         
    +0211         % uncertainty calculation results
    +0212         uncert.interp_t = time0(:);
    +0213         uncert.interp_E0 = E0INTERP;
    +0214         uncert.interp_f = TDIST;
    +0215         uncert.interp_s = SINTERP;
    +0216         
    +0217         % uncertainty patch for fitted signal
    +0218         uncert.interp_s_min = min(SINTERP,[],2);
    +0219         uncert.interp_s_max = max(SINTERP,[],2);
    +0220         
    +0221         % uncertainty patch for fitted RTD
    +0222         uncert.interp_f_min = min(TDIST);
    +0223         uncert.interp_f_max = max(TDIST);
    +0224         
    +0225         invstd.uncert = uncert;
    +0226         
    +0227     case 'NNLS'
    +0228         
    +0229         % 'RTD_var' | 'Lambda' | 'RMS_bound' | 'RMS_free'
    +0230         % uncertMethod = 'RMS_bound';
    +0231         
    +0232         switch uncertMethod
    +0233             case 'RTD_var'
    +0234                 % find uncertainty models by varying the optimal RTD bins
    +0235                 % individually
    +0236                 
    +0237                 % uncertN = 5;
    +0238                 % uncertThresh = 0.1;
    +0239                 % uncertChi2 = 0.05;
    +0240                 f_final = invstd.T1T2f;
    +0241                 
    +0242                 % initialize variables
    +0243                 % NOTE: we save 'uncertN' models for each RTD bin
    +0244                 TDIST = zeros(uncertN*numel(invstd.T1T2me),numel(invstd.T1T2me));
    +0245                 SINTERP = zeros(numel(time0),uncertN*numel(invstd.T1T2me));
    +0246                 E0INTERP = zeros(uncertN*numel(invstd.T1T2me),1);
    +0247                 % loop over all RTD bins
    +0248                 for i1 = 1:numel(f_final)
    +0249                     count = 0;
    +0250                     while count < uncertN
    +0251                         % start RTD is always the optimal one
    +0252                         x0 = f_final;
    +0253                         % global bounds
    +0254                         lb = zeros(size(x0));
    +0255                         ub = max(f_final).*3.*ones(size(x0));
    +0256                         % now draw a random value for the current RTD bin
    +0257                         a = 1-uncertThresh;
    +0258                         b = 1+uncertThresh;
    +0259                         rr = (b-a).*rand(1,1) + a;
    +0260                         % adjust the initial model and bounds accordingly
    +0261                         x0(i1) = f_final(i1)*rr;
    +0262                         lb(i1) = x0(i1);
    +0263                         ub(i1) = x0(i1);
    +0264                         
    +0265                         % save bounds for the LSQ inversion
    +0266                         iparam.bounds.lb = lb;
    +0267                         iparam.bounds.ub = ub;
    +0268                         iparam.bounds.f0 = x0;
    +0269                         
    +0270                         % calculate solution
    +0271                         invtmp = fitDataLSQ(time,signal,iparam);
    +0272                         s0_interp = K0f*invtmp.T1T2f;
    +0273                         
    +0274                         % check if the temporary chi2 and model norm are
    +0275                         % within the desired limits
    +0276                         if abs(1-invtmp.chi2/invstd.chi2) <= uncertChi2 &&  ...
    +0277                                 abs(1-invtmp.xn/invstd.xn) <= uncertChi2/2
    +0278                             % if YES then keep it
    +0279                             count = count + 1;
    +0280                             % save RTD
    +0281                             TDIST(i1*uncertN-(uncertN-count),:) = invtmp.T1T2f;
    +0282                             % save signal
    +0283                             SINTERP(:,i1*uncertN-(uncertN-count)) = s0_interp;
    +0284                             % save E0
    +0285                             E0INTERP(i1*uncertN-(uncertN-count),1) = invtmp.E0;
    +0286                             % status bar info
    +0287                             infostring = ['Calculating uncertainty models: ',...
    +0288                                 num2str(count),' / ',num2str(uncertN),...
    +0289                                 ' for RTD bin: ',num2str(i1),' / ',num2str(numel(f_final))];
    +0290                             displayStatusText(gui,infostring);
    +0291                         end
    +0292                     end
    +0293                 end
    +0294                 
    +0295             case 'Lambda'
    +0296                 % find uncertainty models by varying the optimal
    +0297                 % regularization parameter lambda
    +0298                 
    +0299                 % set regularization to 'manual' just in case
    +0300                 iparam.regMethod = 'manual';
    +0301                 
    +0302                 % lambda search range
    +0303                 a = log10(invstd.lambda_out/100);
    +0304                 b = log10(invstd.lambda_out*10);
    +0305                 
    +0306                 % counter
    +0307                 count = 0;
    +0308                 countm = 0;
    +0309                 
    +0310                 % initialize variables
    +0311                 TDIST = zeros(uncertN,numel(invstd.T1T2me));
    +0312                 SINTERP = zeros(numel(time0),uncertN);
    +0313                 E0INTERP = zeros(uncertN,1);
    +0314                 % calculate uncertainty models
    +0315                 while count < uncertN
    +0316                     % draw a random lambda value
    +0317                     rr = (b-a).*rand(1,1) + a;
    +0318                     iparam.lambda = 10^(rr);
    +0319                     % calculate solution
    +0320                     invtmp = fitDataLSQ(time,signal,iparam);
    +0321                     s0_interp = K0f*invtmp.T1T2f;
    +0322                     
    +0323                     % check if temporary chi2 and model norm are within the
    +0324                     % desired limits
    +0325                     if abs(1-invtmp.chi2/invstd.chi2) <= uncertChi2 &&...
    +0326                             abs(1-invtmp.xn/invstd.xn) <= uncertChi2*10
    +0327                         % if YES then keep it
    +0328                         count = count + 1;
    +0329                         % save RTD
    +0330                         TDIST(count,:) = invtmp.T1T2f;
    +0331                         % save signal
    +0332                         SINTERP(:,count) = s0_interp;
    +0333                         % save E0
    +0334                         E0INTERP(count,1) = invtmp.E0;
    +0335                         % status bar info
    +0336                         infostring = ['Calculating uncertainty models: ',...
    +0337                             num2str(count),' / ',num2str(uncertN)];
    +0338                         displayStatusText(gui,infostring);
    +0339                         % reset max counter
    +0340                         countm = 0;
    +0341                     else
    +0342 %                         % update the lambda search range
    +0343 %                         if invtmp.xn > invstd.xn % lambda was too small
    +0344 %                             % new lower lambda search bound
    +0345 %                             a = rr;
    +0346 %                         end
    +0347 %                         if invtmp.chi2 > invstd.chi2 % lambda was too big
    +0348 %                             % new upper lambda search bound
    +0349 %                             b = rr;
    +0350 %                         end
    +0351                         % as long as we did not find a model keep counting
    +0352                         if count < 1
    +0353                             countm = countm + 1;
    +0354                             infostring = ['Trying to find uncertainty model: ',...
    +0355                                 num2str(countm),' / ',num2str(uncertMax)];
    +0356                             displayStatusText(gui,infostring);
    +0357                         end
    +0358                     end
    +0359                     % after to many unsuccessful attempts STOP
    +0360                     if countm > uncertMax
    +0361                         infostring = ['No uncertainty model found: ',...
    +0362                             num2str(countm),' / ',num2str(uncertMax)];
    +0363                         displayStatusText(gui,infostring);
    +0364                         break;
    +0365                     end                    
    +0366                 end
    +0367                 
    +0368             case 'RMS_bound'
    +0369                 % find uncertainty models by adding random noise (based on
    +0370                 % fit RMS) on the optimal fit to create new "raw data" and
    +0371                 % invert them with the original optimal inversion settings
    +0372                 % select models based on chi2 and model norm bounds
    +0373                 
    +0374                 % set regularization to 'manual' just in case
    +0375                 iparam.regMethod = 'manual';
    +0376                 
    +0377                 % counter
    +0378                 count = 0;
    +0379                 countm = 0;
    +0380                 
    +0381                 % initialize variables
    +0382                 TDIST = zeros(uncertN,numel(invstd.T1T2me));
    +0383                 SINTERP = zeros(numel(time0),uncertN);
    +0384                 E0INTERP = zeros(uncertN,1);
    +0385                 % calculate uncertainty models
    +0386                 while count < uncertN
    +0387                     % the original fit
    +0388                     sig1 = invstd.fit_s;
    +0389                     % create some random noise based on original fit RMS
    +0390                     [signalN,~] = addNoiseToSignal(sig1,0,invstd.rms);
    +0391                     % calculate solution
    +0392                     invtmp = fitDataLSQ(time,signalN,iparam);
    +0393                     s0_interp = K0f*invtmp.T1T2f;
    +0394                     
    +0395                     % check if temporary chi2 and model norm are within the
    +0396                     % desired limits
    +0397                     if abs(1-invtmp.chi2/invstd.chi2) <= uncertChi2 &&...
    +0398                             abs(1-invtmp.xn/invstd.xn) <= uncertChi2*10
    +0399                         % if YES then keep it
    +0400                         count = count + 1;
    +0401                         % save RTD
    +0402                         TDIST(count,:) = invtmp.T1T2f;
    +0403                         % save signal
    +0404                         SINTERP(:,count) = s0_interp;
    +0405                         % save E0
    +0406                         E0INTERP(count,1) = invtmp.E0;
    +0407                         % status bar info
    +0408                         infostring = ['Calculating uncertainty models: ',...
    +0409                             num2str(count),' / ',num2str(uncertN)];
    +0410                         displayStatusText(gui,infostring);
    +0411                         % reset max counter
    +0412                         countm = 0;
    +0413                     else
    +0414                         % as long as we did not find a model keep counting
    +0415                         if count < 1
    +0416                             countm = countm + 1;
    +0417                             infostring = ['Trying to find uncertainty model: ',...
    +0418                                 num2str(countm),' / ',num2str(uncertMax)];
    +0419                             displayStatusText(gui,infostring);
    +0420                         end
    +0421                     end
    +0422                     % after to many unsuccessful attempts STOP
    +0423                     if countm > uncertMax
    +0424                         infostring = ['No uncertainty model found: ',...
    +0425                             num2str(countm),' / ',num2str(uncertMax)];
    +0426                         displayStatusText(gui,infostring);
    +0427                         break;
    +0428                     end
    +0429                 end
    +0430                    
    +0431             case 'RMS_free'
    +0432                 % find uncertainty models by adding random noise (based on
    +0433                 % fit RMS) on the optimal fit to create new "raw data" and
    +0434                 % invert them with the original optimal inversion settings
    +0435                 
    +0436                 % set regularization to 'manual' just in case
    +0437                 iparam.regMethod = 'manual';
    +0438                 
    +0439                 % initialize variables
    +0440                 TDIST = zeros(uncertN,numel(invstd.T1T2me));
    +0441                 SINTERP = zeros(numel(time0),uncertN);
    +0442                 E0INTERP = zeros(uncertN,1);
    +0443                 % calculate uncertainty models
    +0444                 for count = 1:uncertN
    +0445                     % the original fit
    +0446                     sig1 = invstd.fit_s;
    +0447                     % create some random noise based on original fit RMS
    +0448                     [signalN,~] = addNoiseToSignal(sig1,0,invstd.rms);
    +0449                     
    +0450                     % calculate solution
    +0451                     invtmp = fitDataLSQ(time,signalN,iparam);
    +0452                     s0_interp = K0f*invtmp.T1T2f;
    +0453                     % save RTD
    +0454                     TDIST(count,:) = invtmp.T1T2f;
    +0455                     % save signal
    +0456                     SINTERP(:,count) = s0_interp;
    +0457                     % save E0
    +0458                     E0INTERP(count,1) = invtmp.E0;
    +0459                     % status bar info
    +0460                     infostring = ['Calculating uncertainty models: ',...
    +0461                         num2str(count),' / ',num2str(uncertN)];
    +0462                     displayStatusText(gui,infostring);
    +0463                 end
    +0464         end
    +0465         
    +0466         % output data
    +0467         % simple E0 confidence interval
    +0468         invstd.ciE0 = 2*std(E0INTERP);
    +0469         
    +0470         % uncertainty calculation results
    +0471         uncert.interp_t = time0(:);
    +0472         uncert.interp_E0 = E0INTERP;
    +0473         uncert.interp_f = TDIST;
    +0474         uncert.interp_s = SINTERP;
    +0475         
    +0476         % uncertainty patch for fitted signal
    +0477         uncert.interp_s_min = min(SINTERP,[],2);
    +0478         uncert.interp_s_max = max(SINTERP,[],2);
    +0479         
    +0480         % uncertainty patch for fitted RTD
    +0481         uncert.interp_f_min = min(TDIST);
    +0482         uncert.interp_f_max = max(TDIST);
    +0483         
    +0484         invstd.uncert = uncert;
    +0485         
    +0486     otherwise
    +0487         % nothing to do
    +0488         uncert = [];
    +0489 end
    +0490 
    +0491 return
    +0492 
    +0493 %------------- END OF CODE --------------
    +0494 
    +0495 %% License:
    +0496 % MIT License
    +0497 %
    +0498 % Copyright (c) 2022 Thomas Hiller
    +0499 %
    +0500 % Permission is hereby granted, free of charge, to any person obtaining a copy
    +0501 % of this software and associated documentation files (the "Software"), to deal
    +0502 % in the Software without restriction, including without limitation the rights
    +0503 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +0504 % copies of the Software, and to permit persons to whom the Software is
    +0505 % furnished to do so, subject to the following conditions:
    +0506 %
    +0507 % The above copyright notice and this permission notice shall be included in all
    +0508 % copies or substantial portions of the Software.
    +0509 %
    +0510 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +0511 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +0512 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +0513 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +0514 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +0515 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +0516 % SOFTWARE.
    +
    Generated by m2html © 2005
    + + \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/fcn_JointInvfixed.html b/doc/nucleus/functions/inversion/fcn_JointInvfixed.html index 50e2ab4..4131afb 100644 --- a/doc/nucleus/functions/inversion/fcn_JointInvfixed.html +++ b/doc/nucleus/functions/inversion/fcn_JointInvfixed.html @@ -40,6 +40,7 @@

    DESCRIPTION ^DESCRIPTION ^SOURCE CODE ^% g : signal vector (all NMR signals) 0014 % indt : number of echoes/points per NMR signal 0015 % Tb : bulk relaxation time -0016 % T1T2 : flag between 'T1' or 'T2' inversion -0017 % T1IRfac : either '1' or '2' depending on T1 method -0018 % SatImbDrain : string indicating if a NMR signal is from -0019 % the drainage or imbibition branch (e.g. 'DDID') -0020 % p : pressure values -0021 % igeom : geometry struct -0022 % x : relaxation time vector -0023 % f : relaxation time distribution (RTD) -0024 % -0025 % Outputs: -0026 % F - norm of the residual vector -0027 % varargout - cell that holds several more data -0028 % ig : fitted NMR signals -0029 % XX : Kernel matrix -0030 % igeom : final geometry struct -0031 % iSAT : final pressure/saturation struct -0032 % -0033 % Example: -0034 % F = fcn_JointInvfixed(X,iparam) -0035 % -0036 % Other m-files required: -0037 % getConstants -0038 % getCornerNMRparameter -0039 % getGeometryParameter -0040 % getPartialSaturationMatrix -0041 % getSaturationFromPressureBatch -0042 % -0043 % Subfunctions: -0044 % none -0045 % -0046 % MAT-files required: -0047 % none -0048 % -0049 % See also: -0050 % Author: Thomas Hiller -0051 % email: thomas.hiller[at]leibniz-liag.de -0052 % License: MIT License (at end) -0053 -0054 %------------- BEGIN CODE -------------- -0055 -0056 %% input parameters -0057 t = iparam.t; -0058 g = iparam.g; -0059 indt = iparam.indt; -0060 Tb = iparam.Tb; -0061 T1T2 = iparam.T1T2; -0062 T1IRfac = iparam.T1IRfac; -0063 SatImbDrain = iparam.SatImbDrain; -0064 p = iparam.p; -0065 igeom = iparam.igeom; -0066 x = iparam.x; -0067 f = iparam.f; -0068 constants = getConstants; -0069 -0070 %% wait-bar option -0071 wbopts.show = false; -0072 -0073 %% surface relaxivity as log10 value -0074 rhos = 10^X(1); -0075 -0076 %% switch depending on geometry -0077 switch igeom.type -0078 case 'cyl' -0079 % new PSD with updated rhos -0080 ipsddata.r = x.*2.*rhos; -0081 ipsddata.psd = f; -0082 % new saturation state -0083 igeom.radius = ipsddata.r'; -0084 igeom = getGeometryParameter(igeom); -0085 iSAT = getSaturationFromPressureBatch(igeom,p,ipsddata,constants,wbopts); -0086 IPS = getPartialSaturationMatrix(iSAT,indt,SatImbDrain); -0087 -0088 % get the surface-to-volume ratio -0089 SV = igeom.P0./igeom.A0; -0090 -0091 % Kernel matrix -0092 Kf = zeros(length(t),length(SV)); -0093 switch T1T2 -0094 case 'T1' -0095 for i=1:length(SV) -0096 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); -0097 end -0098 case 'T2' -0099 for i=1:length(SV) -0100 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); -0101 end -0102 end -0103 -0104 K = Kf; -0105 % Kernel matrix times saturation matrix -0106 XX = K.*IPS; -0107 -0108 case {'ang','poly'} -0109 % new PSD with updated rhos -0110 ipsddata.r = x.*igeom.a.*rhos; -0111 ipsddata.psd = f; -0112 igeom.radius = ipsddata.r'; -0113 % new saturation state -0114 igeom = getGeometryParameter(igeom); -0115 iSAT = getSaturationFromPressureBatch(igeom,p,ipsddata,constants,wbopts); -0116 IPS = getPartialSaturationMatrix(iSAT,indt,SatImbDrain); -0117 -0118 % get the amplitudes and surface-to-volume ratios for the partially -0119 % saturated corners -0120 SVdata = getCornerNMRparameter(igeom,iSAT,indt,SatImbDrain); -0121 SVdata.TT = repmat(t',[1 length(SVdata.SVF)]); -0122 -0123 SV = SVdata.SVF'; -0124 SVC = SVdata.SVC; -0125 Amp = SVdata.Ampl; -0126 TT = SVdata.TT; -0127 -0128 % Kernel matrix -0129 Kf = zeros(length(t),length(SV)); -0130 switch T1T2 -0131 case 'T1' -0132 for i=1:length(SV) -0133 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); -0134 end -0135 % Kernel matrix for partial saturation -0136 Kc = zeros(length(t),length(SV)); -0137 for i=1:size(SVC,1) -0138 Kc = Kc + ( squeeze(Amp(i,:,:)) .* ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) )); -0139 end -0140 case 'T2' -0141 for i=1:length(SV) -0142 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); -0143 end -0144 % Kernel matrix for partial saturation -0145 Kc = zeros(length(t),length(SV)); -0146 for i=1:size(SVC,1) -0147 Kc = Kc + ( squeeze(Amp(i,:,:)) .* exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) ); -0148 end -0149 end -0150 -0151 K = Kf; -0152 K(IPS~=1) = Kc(IPS~=1); -0153 % Kernel matrix times saturation matrix -0154 XX = K; -0155 -0156 otherwise -0157 % nothing to do -0158 end -0159 -0160 %% weighting -0161 if isfield(iparam,'W') -0162 g = iparam.W*g'; -0163 XX = iparam.W*XX; -0164 g = g'; -0165 end -0166 -0167 %% corresponding signal g = Kf -0168 ig = XX*f'; -0169 -0170 %% residual -0171 F = norm(ig - g'); -0172 -0173 %% output -0174 if nargout > 1 -0175 varargout{1} = ig; -0176 varargout{2} = XX; -0177 varargout{3} = igeom; -0178 varargout{4} = iSAT; -0179 end -0180 -0181 return -0182 -0183 %------------- END OF CODE -------------- +0016 % Td : diffusion relaxation time +0017 % T1T2 : flag between 'T1' or 'T2' inversion +0018 % T1IRfac : either '1' or '2' depending on T1 method +0019 % SatImbDrain : string indicating if a NMR signal is from +0020 % the drainage or imbibition branch (e.g. 'DDID') +0021 % p : pressure values +0022 % igeom : geometry struct +0023 % x : relaxation time vector +0024 % f : relaxation time distribution (RTD) +0025 % +0026 % Outputs: +0027 % F - norm of the residual vector +0028 % varargout - cell that holds several more data +0029 % ig : fitted NMR signals +0030 % XX : Kernel matrix +0031 % igeom : final geometry struct +0032 % iSAT : final pressure/saturation struct +0033 % +0034 % Example: +0035 % F = fcn_JointInvfixed(X,iparam) +0036 % +0037 % Other m-files required: +0038 % getConstants +0039 % getCornerNMRparameter +0040 % getGeometryParameter +0041 % getPartialSaturationMatrix +0042 % getSaturationFromPressureBatch +0043 % +0044 % Subfunctions: +0045 % none +0046 % +0047 % MAT-files required: +0048 % none +0049 % +0050 % See also: +0051 % Author: see AUTHORS.md +0052 % email: see AUTHORS.md +0053 % License: MIT License (at end) +0054 +0055 %------------- BEGIN CODE -------------- +0056 +0057 %% input parameters +0058 t = iparam.t; +0059 g = iparam.g; +0060 indt = iparam.indt; +0061 Tb = iparam.Tb; +0062 Td = iparam.Td; +0063 T1T2 = iparam.T1T2; +0064 T1IRfac = iparam.T1IRfac; +0065 SatImbDrain = iparam.SatImbDrain; +0066 p = iparam.p; +0067 igeom = iparam.igeom; +0068 x = iparam.x; +0069 f = iparam.f; +0070 constants = getConstants; +0071 +0072 %% wait-bar option +0073 wbopts.show = false; +0074 +0075 %% surface relaxivity as log10 value +0076 rhos = 10^X(1); +0077 +0078 %% switch depending on geometry +0079 switch igeom.type +0080 case 'cyl' +0081 % new PSD with updated rhos +0082 ipsddata.r = x.*2.*rhos; +0083 ipsddata.psd = f; +0084 % new saturation state +0085 igeom.radius = ipsddata.r'; +0086 igeom = getGeometryParameter(igeom); +0087 iSAT = getSaturationFromPressureBatch(igeom,p,ipsddata,constants,wbopts); +0088 IPS = getPartialSaturationMatrix(iSAT,indt,SatImbDrain); +0089 +0090 % get the surface-to-volume ratio +0091 SV = igeom.P0./igeom.A0; +0092 +0093 % Kernel matrix +0094 Kf = zeros(length(t),length(SV)); +0095 switch T1T2 +0096 case 'T1' +0097 for i=1:length(SV) +0098 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0099 end +0100 case 'T2' +0101 for i=1:length(SV) +0102 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0103 end +0104 end +0105 +0106 K = Kf; +0107 % Kernel matrix times saturation matrix +0108 XX = K.*IPS; +0109 +0110 case {'ang','poly'} +0111 % new PSD with updated rhos +0112 ipsddata.r = x.*igeom.a.*rhos; +0113 ipsddata.psd = f; +0114 igeom.radius = ipsddata.r'; +0115 % new saturation state +0116 igeom = getGeometryParameter(igeom); +0117 iSAT = getSaturationFromPressureBatch(igeom,p,ipsddata,constants,wbopts); +0118 IPS = getPartialSaturationMatrix(iSAT,indt,SatImbDrain); +0119 +0120 % get the amplitudes and surface-to-volume ratios for the partially +0121 % saturated corners +0122 SVdata = getCornerNMRparameter(igeom,iSAT,indt,SatImbDrain); +0123 SVdata.TT = repmat(t',[1 length(SVdata.SVF)]); +0124 +0125 SV = SVdata.SVF'; +0126 SVC = SVdata.SVC; +0127 Amp = SVdata.Ampl; +0128 TT = SVdata.TT; +0129 +0130 % Kernel matrix +0131 Kf = zeros(length(t),length(SV)); +0132 switch T1T2 +0133 case 'T1' +0134 for i=1:length(SV) +0135 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0136 end +0137 % Kernel matrix for partial saturation +0138 Kc = zeros(length(t),length(SV)); +0139 for i=1:size(SVC,1) +0140 Kc = Kc + ( squeeze(Amp(i,:,:)) .*... +0141 ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) )); +0142 end +0143 case 'T2' +0144 for i=1:length(SV) +0145 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0146 end +0147 % Kernel matrix for partial saturation +0148 Kc = zeros(length(t),length(SV)); +0149 for i=1:size(SVC,1) +0150 Kc = Kc + ( squeeze(Amp(i,:,:)) .*... +0151 exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) ); +0152 end +0153 end +0154 +0155 K = Kf; +0156 K(IPS~=1) = Kc(IPS~=1); +0157 % Kernel matrix times saturation matrix +0158 XX = K; +0159 +0160 otherwise +0161 % nothing to do +0162 end +0163 +0164 %% weighting +0165 if isfield(iparam,'W') +0166 g = iparam.W*g'; +0167 XX = iparam.W*XX; +0168 g = g'; +0169 end +0170 +0171 %% corresponding signal g = Kf +0172 ig = XX*f'; +0173 +0174 %% residual +0175 F = norm(ig - g'); +0176 +0177 %% output +0178 if nargout > 1 +0179 varargout{1} = ig; +0180 varargout{2} = XX; +0181 varargout{3} = igeom; +0182 varargout{4} = iSAT; +0183 end 0184 -0185 %% License: -0186 % MIT License -0187 % -0188 % Copyright (c) 2018 Thomas Hiller -0189 % -0190 % Permission is hereby granted, free of charge, to any person obtaining a copy -0191 % of this software and associated documentation files (the "Software"), to deal -0192 % in the Software without restriction, including without limitation the rights -0193 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0194 % copies of the Software, and to permit persons to whom the Software is -0195 % furnished to do so, subject to the following conditions: -0196 % -0197 % The above copyright notice and this permission notice shall be included in all -0198 % copies or substantial portions of the Software. -0199 % -0200 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0201 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0202 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0203 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0204 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0205 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0206 % SOFTWARE.

    +0185 return +0186 +0187 %------------- END OF CODE -------------- +0188 +0189 %% License: +0190 % MIT License +0191 % +0192 % Copyright (c) 2018 Thomas Hiller +0193 % +0194 % Permission is hereby granted, free of charge, to any person obtaining a copy +0195 % of this software and associated documentation files (the "Software"), to deal +0196 % in the Software without restriction, including without limitation the rights +0197 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0198 % copies of the Software, and to permit persons to whom the Software is +0199 % furnished to do so, subject to the following conditions: +0200 % +0201 % The above copyright notice and this permission notice shall be included in all +0202 % copies or substantial portions of the Software. +0203 % +0204 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0205 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0206 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0207 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0208 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0209 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0210 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/fcn_JointInvfree.html b/doc/nucleus/functions/inversion/fcn_JointInvfree.html index 46b190d..de4b3e7 100644 --- a/doc/nucleus/functions/inversion/fcn_JointInvfree.html +++ b/doc/nucleus/functions/inversion/fcn_JointInvfree.html @@ -38,6 +38,7 @@

    DESCRIPTION ^DESCRIPTION ^SOURCE CODE ^% t : augmented time vector 0012 % g : augmented signal vector 0013 % Tb : bulk relaxation time -0014 % T1T2 : 'T1' / 'T2' flag -0015 % T1IRfac : either '1' or '2' depending on T1 method -0016 % L : smoothness constraint -0017 % lambda : regularization parameter -0018 % igeom : geometry structure data -0019 % IPS : saturation status matrix -0020 % SVdata : corner saturation data -0021 % -0022 % Outputs: -0023 % F - residual -0024 % J - Jacobian (optional) -0025 % ig - fitted signal (optional) -0026 % XX - augmented Kernel matrix (optional) -0027 % -0028 % Example: -0029 % [F,J,ig,XX] = fcn_JointInvfree(X,iparam) -0030 % -0031 % Other m-files required: -0032 % none -0033 % -0034 % Subfunctions: -0035 % none -0036 % -0037 % MAT-files required: -0038 % none -0039 % -0040 % See also: -0041 % Author: Thomas Hiller -0042 % email: thomas.hiller[at]leibniz-liag.de -0043 % License: MIT License (at end) -0044 -0045 %------------- BEGIN CODE -------------- -0046 -0047 %% input parameters -0048 t = iparam.t; -0049 g = iparam.g; -0050 Tb = iparam.Tb; -0051 T1T2 = iparam.T1T2; -0052 T1IRfac = iparam.T1IRfac; -0053 L = iparam.L; -0054 lambda = iparam.lambda; -0055 igeom = iparam.igeom; -0056 IPS = iparam.IPS; -0057 -0058 % length of relaxation time distr. -0059 n = length(X)-1; -0060 % amplitude of relaxation time distr. -0061 x = X(1:n); -0062 % surface relaxivity as scaled log10 value -0063 rhos = 10^X(n+1); -0064 -0065 %% switch depending on geometry -0066 switch igeom.type -0067 case 'cyl' -0068 % for cylindrical pores SV is simply the full saturated S/V ratio -0069 SV = iparam.SVdata.SVF; -0070 -0071 % Kernel matrix -0072 Kf = zeros(length(t),length(SV)); -0073 switch T1T2 -0074 case 'T1' -0075 for i=1:length(SV) -0076 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); -0077 end -0078 case 'T2' -0079 for i=1:length(SV) -0080 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); -0081 end -0082 end -0083 K = Kf; -0084 % Kernel matrix times saturation matrix -0085 XX = K.*IPS; -0086 -0087 case {'ang','poly'} -0088 % for angular and polygonal pores there are full saturation S/V and -0089 % partial saturation S/V ratios and amplitudes -0090 SV = iparam.SVdata.SVF; -0091 SVC = iparam.SVdata.SVC; -0092 Amp = iparam.SVdata.Ampl; -0093 TT = iparam.SVdata.TT; -0094 -0095 % Kernel matrix -0096 Kf = zeros(length(t),length(SV)); -0097 switch T1T2 -0098 case 'T1' -0099 for i=1:length(SV) -0100 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); -0101 end -0102 % Kernel matrix for partial saturation -0103 Kc = zeros(length(t),length(SV)); -0104 for i=1:size(SVC,1) -0105 Kc = Kc + ( squeeze(Amp(i,:,:)) .*... -0106 ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) )); -0107 end -0108 case 'T2' -0109 for i=1:length(SV) -0110 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); -0111 end -0112 % Kernel matrix for partial saturation -0113 Kc = zeros(length(t),length(SV)); -0114 for i=1:size(SVC,1) -0115 Kc = Kc + ( squeeze(Amp(i,:,:)) .*... -0116 exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) ); -0117 end -0118 end -0119 % full saturation matrix -0120 K = Kf; -0121 % for partial saturation points use the Kc values -0122 K(IPS~=1) = Kc(IPS~=1); -0123 % Kernel matrix times saturation matrix -0124 XX = K; -0125 end -0126 -0127 % error weighing -0128 if isfield(iparam,'W') -0129 g = iparam.W*g'; -0130 XX = iparam.W*XX; -0131 g = g'; -0132 end -0133 -0134 % corresponding signal g = Kf -0135 ig = XX*x'; -0136 % residual -0137 F1 = (ig - g'); -0138 % regularization -0139 F2 = (lambda*L)*x'; -0140 % fcn should return the residual as output for lsqnonlin -0141 % see e.g. Aster et al. S. 240 eq.10.4 -0142 F = [F1; F2]; -0143 -0144 % jacobian - speeds up inversion! -0145 J = 0; -0146 if nargout > 1 -0147 % see Mohnke, 2014 WRR paper for info -0148 -0149 % J = dGAMMA/df -0150 J = XX; -0151 -0152 switch T1T2 -0153 case 'T1' -0154 % Jr = dGAMMA/drho -0155 % for T1 it's a bit more tricky because -0156 % d/drho 1-IR*exp(-t*rho*SV) = IR*t*SV * exp(-t*rho*SV) -0157 % where exp(-t*rho*SV) is essentially the T2 Kernel matrix -0158 -0159 % DD = exp(-t*rho*SV) -0160 switch igeom.type -0161 case 'cyl' -0162 DD = zeros(length(t),length(SV)); -0163 for i=1:length(SV) -0164 DD(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); -0165 end -0166 -0167 case {'ang','poly'} -0168 % Kernel matrix for full saturation -0169 DD = zeros(length(t),length(SV)); -0170 for i=1:length(SV) -0171 DD(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); -0172 end -0173 % Kernel matrix for partial saturation -0174 D = zeros(length(t),length(SV)); -0175 for i=1:size(SVC,1) -0176 D = D + ( squeeze(Amp(i,:,:)).* exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) ); -0177 end -0178 DD(IPS~=1) = D(IPS~=1); -0179 end -0180 -0181 % and now using DD in the derivative: -0182 Jr = zeros(1,length(t)); -0183 for i = 1:length(t) -0184 Jr(i) = t(i).*sum(x.*T1IRfac.*SV.*rhos.*DD(i,:)); -0185 end -0186 -0187 case 'T2' -0188 % Jr = dGAMMA/drho -0189 % in the case of T2 the derivate of dGAMMA/drho is simple -0190 Jr = zeros(1,length(t)); -0191 for i = 1:length(t) -0192 Jr(i) = t(i).*sum(-x.*SV.*rhos.*XX(i,:)); -0193 end -0194 end -0195 -0196 JJ = [J Jr']; -0197 LL = [lambda*L 0*L(:,1)]; -0198 J = [JJ;LL]; -0199 end -0200 -0201 return -0202 -0203 %------------- END OF CODE -------------- -0204 -0205 %% License: -0206 % MIT License -0207 % -0208 % Copyright (c) 2018 Thomas Hiller -0209 % -0210 % Permission is hereby granted, free of charge, to any person obtaining a copy -0211 % of this software and associated documentation files (the "Software"), to deal -0212 % in the Software without restriction, including without limitation the rights -0213 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0214 % copies of the Software, and to permit persons to whom the Software is -0215 % furnished to do so, subject to the following conditions: -0216 % -0217 % The above copyright notice and this permission notice shall be included in all -0218 % copies or substantial portions of the Software. +0014 % Td : diffusion relaxation time +0015 % T1T2 : 'T1' / 'T2' flag +0016 % T1IRfac : either '1' or '2' depending on T1 method +0017 % L : smoothness constraint +0018 % lambda : regularization parameter +0019 % igeom : geometry structure data +0020 % IPS : saturation status matrix +0021 % SVdata : corner saturation data +0022 % +0023 % Outputs: +0024 % F - residual +0025 % J - Jacobian (optional) +0026 % ig - fitted signal (optional) +0027 % XX - augmented Kernel matrix (optional) +0028 % +0029 % Example: +0030 % [F,J,ig,XX] = fcn_JointInvfree(X,iparam) +0031 % +0032 % Other m-files required: +0033 % none +0034 % +0035 % Subfunctions: +0036 % none +0037 % +0038 % MAT-files required: +0039 % none +0040 % +0041 % See also: +0042 % Author: see AUTHORS.md +0043 % email: see AUTHORS.md +0044 % License: MIT License (at end) +0045 +0046 %------------- BEGIN CODE -------------- +0047 +0048 %% input parameters +0049 t = iparam.t; +0050 g = iparam.g; +0051 Tb = iparam.Tb; +0052 Td = iparam.Td; +0053 T1T2 = iparam.T1T2; +0054 T1IRfac = iparam.T1IRfac; +0055 L = iparam.L; +0056 lambda = iparam.lambda; +0057 igeom = iparam.igeom; +0058 IPS = iparam.IPS; +0059 +0060 % length of relaxation time distr. +0061 n = length(X)-1; +0062 % amplitude of relaxation time distr. +0063 x = X(1:n); +0064 % surface relaxivity as scaled log10 value +0065 rhos = 10^X(n+1); +0066 +0067 %% switch depending on geometry +0068 switch igeom.type +0069 case 'cyl' +0070 % for cylindrical pores SV is simply the full saturated S/V ratio +0071 SV = iparam.SVdata.SVF; +0072 +0073 % Kernel matrix +0074 Kf = zeros(length(t),length(SV)); +0075 switch T1T2 +0076 case 'T1' +0077 for i=1:length(SV) +0078 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0079 end +0080 case 'T2' +0081 for i=1:length(SV) +0082 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0083 end +0084 end +0085 K = Kf; +0086 % Kernel matrix times saturation matrix +0087 XX = K.*IPS; +0088 +0089 case {'ang','poly'} +0090 % for angular and polygonal pores there are full saturation S/V and +0091 % partial saturation S/V ratios and amplitudes +0092 SV = iparam.SVdata.SVF; +0093 SVC = iparam.SVdata.SVC; +0094 Amp = iparam.SVdata.Ampl; +0095 TT = iparam.SVdata.TT; +0096 +0097 % Kernel matrix +0098 Kf = zeros(length(t),length(SV)); +0099 switch T1T2 +0100 case 'T1' +0101 for i=1:length(SV) +0102 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0103 end +0104 % Kernel matrix for partial saturation +0105 Kc = zeros(length(t),length(SV)); +0106 for i=1:size(SVC,1) +0107 Kc = Kc + ( squeeze(Amp(i,:,:)) .*... +0108 ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) )); +0109 end +0110 case 'T2' +0111 for i=1:length(SV) +0112 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0113 end +0114 % Kernel matrix for partial saturation +0115 Kc = zeros(length(t),length(SV)); +0116 for i=1:size(SVC,1) +0117 Kc = Kc + ( squeeze(Amp(i,:,:)) .*... +0118 exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) ); +0119 end +0120 end +0121 % full saturation matrix +0122 K = Kf; +0123 % for partial saturation points use the Kc values +0124 K(IPS~=1) = Kc(IPS~=1); +0125 % Kernel matrix times saturation matrix +0126 XX = K; +0127 end +0128 +0129 % error weighing +0130 if isfield(iparam,'W') +0131 g = iparam.W*g'; +0132 XX = iparam.W*XX; +0133 g = g'; +0134 end +0135 +0136 % corresponding signal g = Kf +0137 ig = XX*x'; +0138 % residual +0139 F1 = (ig - g'); +0140 % regularization +0141 F2 = (lambda*L)*x'; +0142 % fcn should return the residual as output for lsqnonlin +0143 % see e.g. Aster et al. S. 240 eq.10.4 +0144 F = [F1; F2]; +0145 +0146 % jacobian - speeds up inversion! +0147 J = 0; +0148 if nargout > 1 +0149 % see Mohnke, 2014 WRR paper for info +0150 +0151 % J = dGAMMA/df +0152 J = XX; +0153 +0154 switch T1T2 +0155 case 'T1' +0156 % Jr = dGAMMA/drho +0157 % for T1 it's a bit more tricky because +0158 % d/drho 1-IR*exp(-t*rho*SV) = IR*t*SV * exp(-t*rho*SV) +0159 % where exp(-t*rho*SV) is essentially the T2 Kernel matrix +0160 +0161 % DD = exp(-t*rho*SV) +0162 switch igeom.type +0163 case 'cyl' +0164 DD = zeros(length(t),length(SV)); +0165 for i=1:length(SV) +0166 DD(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0167 end +0168 +0169 case {'ang','poly'} +0170 % Kernel matrix for full saturation +0171 DD = zeros(length(t),length(SV)); +0172 for i=1:length(SV) +0173 DD(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0174 end +0175 % Kernel matrix for partial saturation +0176 D = zeros(length(t),length(SV)); +0177 for i=1:size(SVC,1) +0178 D = D + ( squeeze(Amp(i,:,:)).*... +0179 exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) ); +0180 end +0181 DD(IPS~=1) = D(IPS~=1); +0182 end +0183 +0184 % and now using DD in the derivative: +0185 Jr = zeros(1,length(t)); +0186 for i = 1:length(t) +0187 Jr(i) = t(i).*sum(x.*T1IRfac.*SV.*rhos.*DD(i,:)); +0188 end +0189 +0190 case 'T2' +0191 % Jr = dGAMMA/drho +0192 % in the case of T2 the derivate of dGAMMA/drho is simple +0193 Jr = zeros(1,length(t)); +0194 for i = 1:length(t) +0195 Jr(i) = t(i).*sum(-x.*SV.*rhos.*XX(i,:)); +0196 end +0197 end +0198 +0199 JJ = [J Jr']; +0200 LL = [lambda*L 0*L(:,1)]; +0201 J = [JJ;LL]; +0202 end +0203 +0204 return +0205 +0206 %------------- END OF CODE -------------- +0207 +0208 %% License: +0209 % MIT License +0210 % +0211 % Copyright (c) 2018 Thomas Hiller +0212 % +0213 % Permission is hereby granted, free of charge, to any person obtaining a copy +0214 % of this software and associated documentation files (the "Software"), to deal +0215 % in the Software without restriction, including without limitation the rights +0216 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0217 % copies of the Software, and to permit persons to whom the Software is +0218 % furnished to do so, subject to the following conditions: 0219 % -0220 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0221 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0222 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0223 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0224 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0225 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0226 % SOFTWARE. +0220 % The above copyright notice and this permission notice shall be included in all +0221 % copies or substantial portions of the Software. +0222 % +0223 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0224 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0225 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0226 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0227 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0228 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0229 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/fcn_JointInvshape.html b/doc/nucleus/functions/inversion/fcn_JointInvshape.html index 6e7c230..5f25011 100644 --- a/doc/nucleus/functions/inversion/fcn_JointInvshape.html +++ b/doc/nucleus/functions/inversion/fcn_JointInvshape.html @@ -42,6 +42,7 @@

    DESCRIPTION ^DESCRIPTION ^SOURCE CODE ^% g : signal vector (all NMR signals) 0016 % indt : number of echoes/points per NMR signal 0017 % Tb : bulk relaxation time -0018 % T1T2 : flag between 'T1' or 'T2' inversion -0019 % T1IRfac : either '1' or '2' depending on T1 method -0020 % SatImbDrain : string indicating if a NMR signal is from -0021 % the drainage or imbibition branch (e.g. 'DDID') -0022 % p : pressure values -0023 % igeom : geometry struct -0024 % x : relaxation time vector -0025 % f : relaxation time distribution (RTD) -0026 % -0027 % Outputs: -0028 % F - norm of the residual vector -0029 % varargout - cell that holds several more data -0030 % ig : fitted NMR signals -0031 % XX : Kernel matrix -0032 % igeom : final geometry struct -0033 % iSAT : final pressure/saturation struct -0034 % -0035 % Example: -0036 % F = fcn_JointInvshape(X,iparam) -0037 % -0038 % Other m-files required: -0039 % getConstants -0040 % getCornerNMRparameter -0041 % getGeometryParameter -0042 % getPartialSaturationMatrix -0043 % getSaturationFromPressureBatch -0044 % -0045 % Subfunctions: -0046 % none -0047 % -0048 % MAT-files required: -0049 % none -0050 % -0051 % See also: -0052 % Author: Thomas Hiller -0053 % email: thomas.hiller[at]leibniz-liag.de -0054 % License: MIT License (at end) -0055 -0056 %------------- BEGIN CODE -------------- -0057 -0058 %% input parameters -0059 t = iparam.t; -0060 g = iparam.g; -0061 indt = iparam.indt; -0062 Tb = iparam.Tb; -0063 T1T2 = iparam.T1T2; -0064 T1IRfac = iparam.T1IRfac; -0065 SatImbDrain = iparam.SatImbDrain; -0066 p = iparam.p; -0067 igeom = iparam.igeom; -0068 x = iparam.x; -0069 f = iparam.f; -0070 constants = getConstants; -0071 -0072 %% waitbar option -0073 wbopts.show = false; -0074 -0075 %% surface relaxivity as log10 value and "second" angle -0076 rhos = 10^X(1); -0077 beta = X(2); -0078 -0079 %% only works for right angular triangles -0080 switch igeom.type -0081 case 'ang' -0082 % get a new geometry parameter "a" (only shape dependent) -0083 % to shift the PSD -0084 tmp.type = igeom.type; -0085 tmp.radius = 1; -0086 tmp.angles = [igeom.angles(1) beta igeom.angles(1)-beta]; -0087 tmp = getGeometryParameter(tmp); -0088 -0089 % new PSD with updated "rhos" and "a" -0090 ipsddata.r = x.*tmp.a.*rhos; -0091 ipsddata.psd = f; -0092 igeom.radius = ipsddata.r'; -0093 % new saturation state -0094 igeom.angles(2) = beta; -0095 igeom.angles(3) = igeom.angles(1)-igeom.angles(2); -0096 igeom = getGeometryParameter(igeom); -0097 iSAT = getSaturationFromPressureBatch(igeom,p,ipsddata,constants,wbopts); -0098 IPS = getPartialSaturationMatrix(iSAT,indt,SatImbDrain); -0099 -0100 % get the amplitudes and surface-to-volume ratios for the partially -0101 % saturated corners -0102 SVdata = getCornerNMRparameter(igeom,iSAT,indt,SatImbDrain); -0103 SVdata.TT = repmat(t',[1 length(SVdata.SVF)]); -0104 -0105 SV = SVdata.SVF'; -0106 SVC = SVdata.SVC; -0107 Amp = SVdata.Ampl; -0108 TT = SVdata.TT; -0109 -0110 % Kernel matrix -0111 Kf = zeros(length(t),length(SV)); -0112 switch T1T2 -0113 case 'T1' -0114 for i=1:length(SV) -0115 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); -0116 end -0117 % Kernel matrix for partial saturation -0118 Kc = zeros(length(t),length(SV)); -0119 for i=1:size(SVC,1) -0120 Kc = Kc + ( squeeze(Amp(i,:,:)) .* ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) )); -0121 end -0122 case 'T2' -0123 for i=1:length(SV) -0124 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); -0125 end -0126 % Kernel matrix for partial saturation -0127 Kc = zeros(length(t),length(SV)); -0128 for i=1:size(SVC,1) -0129 Kc = Kc + ( squeeze(Amp(i,:,:)) .* exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) ); -0130 end -0131 end -0132 -0133 K = Kf; -0134 K(IPS~=1) = Kc(IPS~=1); -0135 % Kernel matrix times saturation matrix -0136 XX = K; -0137 -0138 otherwise -0139 % nothing to do -0140 end -0141 -0142 %% weighting -0143 if isfield(iparam,'W') -0144 g = iparam.W*g'; -0145 XX = iparam.W*XX; -0146 g = g'; -0147 end -0148 -0149 %% corresponding signal g = Kf -0150 ig = XX*f'; -0151 -0152 %% residual -0153 F = norm(ig - g'); -0154 -0155 %% output -0156 if nargout > 1 -0157 varargout{1} = ig; -0158 varargout{2} = XX; -0159 varargout{3} = igeom; -0160 varargout{4} = iSAT; -0161 end -0162 -0163 return -0164 -0165 %------------- END OF CODE -------------- +0018 % Td : diffusion relaxation time +0019 % T1T2 : flag between 'T1' or 'T2' inversion +0020 % T1IRfac : either '1' or '2' depending on T1 method +0021 % SatImbDrain : string indicating if a NMR signal is from +0022 % the drainage or imbibition branch (e.g. 'DDID') +0023 % p : pressure values +0024 % igeom : geometry struct +0025 % x : relaxation time vector +0026 % f : relaxation time distribution (RTD) +0027 % +0028 % Outputs: +0029 % F - norm of the residual vector +0030 % varargout - cell that holds several more data +0031 % ig : fitted NMR signals +0032 % XX : Kernel matrix +0033 % igeom : final geometry struct +0034 % iSAT : final pressure/saturation struct +0035 % +0036 % Example: +0037 % F = fcn_JointInvshape(X,iparam) +0038 % +0039 % Other m-files required: +0040 % getConstants +0041 % getCornerNMRparameter +0042 % getGeometryParameter +0043 % getPartialSaturationMatrix +0044 % getSaturationFromPressureBatch +0045 % +0046 % Subfunctions: +0047 % none +0048 % +0049 % MAT-files required: +0050 % none +0051 % +0052 % See also: +0053 % Author: see AUTHORS.md +0054 % email: see AUTHORS.md +0055 % License: MIT License (at end) +0056 +0057 %------------- BEGIN CODE -------------- +0058 +0059 %% input parameters +0060 t = iparam.t; +0061 g = iparam.g; +0062 indt = iparam.indt; +0063 Tb = iparam.Tb; +0064 Td = iparam.Td; +0065 T1T2 = iparam.T1T2; +0066 T1IRfac = iparam.T1IRfac; +0067 SatImbDrain = iparam.SatImbDrain; +0068 p = iparam.p; +0069 igeom = iparam.igeom; +0070 x = iparam.x; +0071 f = iparam.f; +0072 constants = getConstants; +0073 +0074 %% waitbar option +0075 wbopts.show = false; +0076 +0077 %% surface relaxivity as log10 value and "second" angle +0078 rhos = 10^X(1); +0079 beta = X(2); +0080 +0081 %% only works for right angular triangles +0082 switch igeom.type +0083 case 'ang' +0084 % get a new geometry parameter "a" (only shape dependent) +0085 % to shift the PSD +0086 tmp.type = igeom.type; +0087 tmp.radius = 1; +0088 tmp.angles = [igeom.angles(1) beta igeom.angles(1)-beta]; +0089 tmp = getGeometryParameter(tmp); +0090 +0091 % new PSD with updated "rhos" and "a" +0092 ipsddata.r = x.*tmp.a.*rhos; +0093 ipsddata.psd = f; +0094 igeom.radius = ipsddata.r'; +0095 % new saturation state +0096 igeom.angles(2) = beta; +0097 igeom.angles(3) = igeom.angles(1)-igeom.angles(2); +0098 igeom = getGeometryParameter(igeom); +0099 iSAT = getSaturationFromPressureBatch(igeom,p,ipsddata,constants,wbopts); +0100 IPS = getPartialSaturationMatrix(iSAT,indt,SatImbDrain); +0101 +0102 % get the amplitudes and surface-to-volume ratios for the partially +0103 % saturated corners +0104 SVdata = getCornerNMRparameter(igeom,iSAT,indt,SatImbDrain); +0105 SVdata.TT = repmat(t',[1 length(SVdata.SVF)]); +0106 +0107 SV = SVdata.SVF'; +0108 SVC = SVdata.SVC; +0109 Amp = SVdata.Ampl; +0110 TT = SVdata.TT; +0111 +0112 % Kernel matrix +0113 Kf = zeros(length(t),length(SV)); +0114 switch T1T2 +0115 case 'T1' +0116 for i=1:length(SV) +0117 Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0118 end +0119 % Kernel matrix for partial saturation +0120 Kc = zeros(length(t),length(SV)); +0121 for i=1:size(SVC,1) +0122 Kc = Kc + ( squeeze(Amp(i,:,:)) .*... +0123 ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) )); +0124 end +0125 case 'T2' +0126 for i=1:length(SV) +0127 Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); +0128 end +0129 % Kernel matrix for partial saturation +0130 Kc = zeros(length(t),length(SV)); +0131 for i=1:size(SVC,1) +0132 Kc = Kc + ( squeeze(Amp(i,:,:)) .*... +0133 exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) ); +0134 end +0135 end +0136 +0137 K = Kf; +0138 K(IPS~=1) = Kc(IPS~=1); +0139 % Kernel matrix times saturation matrix +0140 XX = K; +0141 +0142 otherwise +0143 % nothing to do +0144 end +0145 +0146 %% weighting +0147 if isfield(iparam,'W') +0148 g = iparam.W*g'; +0149 XX = iparam.W*XX; +0150 g = g'; +0151 end +0152 +0153 %% corresponding signal g = Kf +0154 ig = XX*f'; +0155 +0156 %% residual +0157 F = norm(ig - g'); +0158 +0159 %% output +0160 if nargout > 1 +0161 varargout{1} = ig; +0162 varargout{2} = XX; +0163 varargout{3} = igeom; +0164 varargout{4} = iSAT; +0165 end 0166 -0167 %% License: -0168 % MIT License -0169 % -0170 % Copyright (c) 2018 Thomas Hiller -0171 % -0172 % Permission is hereby granted, free of charge, to any person obtaining a copy -0173 % of this software and associated documentation files (the "Software"), to deal -0174 % in the Software without restriction, including without limitation the rights -0175 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0176 % copies of the Software, and to permit persons to whom the Software is -0177 % furnished to do so, subject to the following conditions: -0178 % -0179 % The above copyright notice and this permission notice shall be included in all -0180 % copies or substantial portions of the Software. -0181 % -0182 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0183 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0184 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0185 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0186 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0187 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0188 % SOFTWARE. +0167 return +0168 +0169 %------------- END OF CODE -------------- +0170 +0171 %% License: +0172 % MIT License +0173 % +0174 % Copyright (c) 2018 Thomas Hiller +0175 % +0176 % Permission is hereby granted, free of charge, to any person obtaining a copy +0177 % of this software and associated documentation files (the "Software"), to deal +0178 % in the Software without restriction, including without limitation the rights +0179 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0180 % copies of the Software, and to permit persons to whom the Software is +0181 % furnished to do so, subject to the following conditions: +0182 % +0183 % The above copyright notice and this permission notice shall be included in all +0184 % copies or substantial portions of the Software. +0185 % +0186 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0187 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0188 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0189 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0190 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0191 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0192 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/fcn_fitFreeT1.html b/doc/nucleus/functions/inversion/fcn_fitFreeT1.html index c066d9e..cec3bf4 100644 --- a/doc/nucleus/functions/inversion/fcn_fitFreeT1.html +++ b/doc/nucleus/functions/inversion/fcn_fitFreeT1.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/fcn_fitFreeT1_fmin.html b/doc/nucleus/functions/inversion/fcn_fitFreeT1_fmin.html index dcd3eec..7a8086a 100644 --- a/doc/nucleus/functions/inversion/fcn_fitFreeT1_fmin.html +++ b/doc/nucleus/functions/inversion/fcn_fitFreeT1_fmin.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/fcn_fitFreeT2.html b/doc/nucleus/functions/inversion/fcn_fitFreeT2.html index b6c1a48..600a985 100644 --- a/doc/nucleus/functions/inversion/fcn_fitFreeT2.html +++ b/doc/nucleus/functions/inversion/fcn_fitFreeT2.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/fcn_fitFreeT2_fmin.html b/doc/nucleus/functions/inversion/fcn_fitFreeT2_fmin.html index 719f909..37afeca 100644 --- a/doc/nucleus/functions/inversion/fcn_fitFreeT2_fmin.html +++ b/doc/nucleus/functions/inversion/fcn_fitFreeT2_fmin.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/fcn_fitFreeT2w.html b/doc/nucleus/functions/inversion/fcn_fitFreeT2w.html index 0a20d0a..a274a35 100644 --- a/doc/nucleus/functions/inversion/fcn_fitFreeT2w.html +++ b/doc/nucleus/functions/inversion/fcn_fitFreeT2w.html @@ -58,8 +58,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=getFitFreeJacobian calculates the Jacobi matrix for the NMR inversion This function is called by:
      -
    • fitDataFree is a control routine that uses 'lsqcurvefit' to fit NMR data
    + @@ -108,8 +108,8 @@

    SOURCE CODE ^% none 0032 % 0033 % See also: -0034 % Author: Thomas Hiller -0035 % email: thomas.hiller[at]leibniz-liag.de +0034 % Author: see AUTHORS.md +0035 % email: see AUTHORS.md 0036 % License: MIT License (at end) 0037 0038 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/fcn_fitMultiModal.html b/doc/nucleus/functions/inversion/fcn_fitMultiModal.html new file mode 100644 index 0000000..a624621 --- /dev/null +++ b/doc/nucleus/functions/inversion/fcn_fitMultiModal.html @@ -0,0 +1,197 @@ + + + + Description of fcn_fitMultiModal + + + + + + + + + + + +

    fcn_fitMultiModal +

    + +

    PURPOSE ^

    +
    is the objective function for N free distribution
    + +

    SYNOPSIS ^

    +
    function F = fcn_fitMultiModal(x,iparam)
    + +

    DESCRIPTION ^

    +
    fcn_fitMultiModal is the objective function for N free distribution
    +fitting that is minimized with 'lsqnonlin'
    +
    + Syntax:
    +       fcn_fitMultiModal(x,iparam)
    +
    + Inputs:
    +       x - parameter vector
    +           x(3*i-2) = mu (relaxation time)
    +           x(3*i-1) = sigma (width of distribution)
    +           x(3*i) = amp (relative amplitude)
    +       iparam - struct that holds additional settings:
    +                t : time vector
    +                s : signal vector
    +                T : relaxation times
    +                e : noise vector / error weights (optional)
    +
    + Outputs:
    +       F - residual
    +
    + Example:
    +       F = fcn_fitMultiModal(x,params)
    +
    + Other m-files required:
    +       createKernelMatrix
    +
    + Subfunctions:
    +       none
    +
    + MAT-files required:
    +       none
    +
    + See also:
    + Author: see AUTHORS.md
    + email: see AUTHORS.md
    + License: MIT License (at end)
    + + +

    CROSS-REFERENCE INFORMATION ^

    +This function calls: + +This function is called by: + + + + + +

    SOURCE CODE ^

    +
    0001 function F = fcn_fitMultiModal(x,iparam)
    +0002 %fcn_fitMultiModal is the objective function for N free distribution
    +0003 %fitting that is minimized with 'lsqnonlin'
    +0004 %
    +0005 % Syntax:
    +0006 %       fcn_fitMultiModal(x,iparam)
    +0007 %
    +0008 % Inputs:
    +0009 %       x - parameter vector
    +0010 %           x(3*i-2) = mu (relaxation time)
    +0011 %           x(3*i-1) = sigma (width of distribution)
    +0012 %           x(3*i) = amp (relative amplitude)
    +0013 %       iparam - struct that holds additional settings:
    +0014 %                t : time vector
    +0015 %                s : signal vector
    +0016 %                T : relaxation times
    +0017 %                e : noise vector / error weights (optional)
    +0018 %
    +0019 % Outputs:
    +0020 %       F - residual
    +0021 %
    +0022 % Example:
    +0023 %       F = fcn_fitMultiModal(x,params)
    +0024 %
    +0025 % Other m-files required:
    +0026 %       createKernelMatrix
    +0027 %
    +0028 % Subfunctions:
    +0029 %       none
    +0030 %
    +0031 % MAT-files required:
    +0032 %       none
    +0033 %
    +0034 % See also:
    +0035 % Author: see AUTHORS.md
    +0036 % email: see AUTHORS.md
    +0037 % License: MIT License (at end)
    +0038 
    +0039 %------------- BEGIN CODE --------------
    +0040 
    +0041 % get all neccessary parameters
    +0042 flag = iparam.flag;
    +0043 T1IRfac = iparam.T1IRfac;
    +0044 nModes = iparam.nModes;
    +0045 t = iparam.t;
    +0046 s = iparam.s;
    +0047 T = iparam.T;
    +0048 Tb = iparam.Tb;
    +0049 Td = iparam.Td;
    +0050 
    +0051 % get the global (combined) RTD distribution
    +0052 Tdist = 0;
    +0053 for i = 1:nModes
    +0054     mu = exp(x(3*i-2));
    +0055     sigma = x(3*i-1);
    +0056     amp = x(3*i);
    +0057     
    +0058     % get the temporary RTD with current mu and sigma
    +0059     tmp = 1./( sigma*sqrt(2*pi)).*exp(-((log(T) - log(mu))/ sqrt(2)/sigma).^2);
    +0060     
    +0061     % scale the temporary RDT to current amplitude
    +0062     tmp = (tmp/sum(tmp)) * amp;
    +0063     
    +0064     % add the current temporary RTD to the global Tdist
    +0065     Tdist = Tdist + tmp;   
    +0066 end
    +0067 
    +0068 % get the kernel function to calculate the signal out of the global RTD
    +0069 K = createKernelMatrix(t,T,Tb,Td,flag,T1IRfac);
    +0070 si = K*Tdist';
    +0071 
    +0072 
    +0073 % get error weights if available
    +0074 if isfield(iparam,'e')
    +0075     e = iparam.e;
    +0076 else
    +0077     e = ones(size(s));
    +0078 end
    +0079 
    +0080 % change output depending on solver
    +0081 switch iparam.optim
    +0082     case 'on' % lsqnonlin
    +0083         % scale the residual
    +0084         F = e.*(si - s);
    +0085     case 'off' % fminsearchbnd
    +0086         F = e.*(si - s);
    +0087         SSE = sum(F.^2);
    +0088         F = SSE;
    +0089 end
    +0090 
    +0091 return
    +0092 
    +0093 %------------- END OF CODE --------------
    +0094 
    +0095 %% License:
    +0096 % MIT License
    +0097 %
    +0098 % Copyright (c) 2022 Thomas Hiller
    +0099 %
    +0100 % Permission is hereby granted, free of charge, to any person obtaining a copy
    +0101 % of this software and associated documentation files (the "Software"), to deal
    +0102 % in the Software without restriction, including without limitation the rights
    +0103 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +0104 % copies of the Software, and to permit persons to whom the Software is
    +0105 % furnished to do so, subject to the following conditions:
    +0106 %
    +0107 % The above copyright notice and this permission notice shall be included in all
    +0108 % copies or substantial portions of the Software.
    +0109 %
    +0110 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +0111 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +0112 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +0113 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +0114 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +0115 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +0116 % SOFTWARE.
    +
    Generated by m2html © 2005
    + + \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/fitDataFree.html b/doc/nucleus/functions/inversion/fitDataFree.html index bacf961..56bfbab 100644 --- a/doc/nucleus/functions/inversion/fitDataFree.html +++ b/doc/nucleus/functions/inversion/fitDataFree.html @@ -81,18 +81,18 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • fcn_fitFreeT1 is the objective function for T1 mono- and free exponential
  • fcn_fitFreeT1_fmin is the objective function for T1 mono- and free exponential
  • fcn_fitFreeT2 is the objective function for T2 mono- and free exponential
  • fcn_fitFreeT2_fmin is the objective function for T2 mono- and free exponential
  • getConfInterval calculates the confidence interval for the inversion
  • getFitErrors calculates all relevant fitting errors for the NMR inversion
  • getFitFreeJacobian calculates the Jacobi matrix for the NMR inversion
  • This function is called by: +
  • LoadNMRData_driver loads NMR raw data from different file formats
  • importASCIIdata imports NMR data from ASCII files
  • runInversionBatch batch processes the inversion using for all NMR signals
  • runInversionStd controls the standard inversion process to invert a
  • fitDataMultiModal is a control routine that uses either 'lsqnonlin' or
  • @@ -154,8 +154,8 @@

    SOURCE CODE ^% none 0055 % 0056 % See also: -0057 % Author: Thomas Hiller -0058 % email: thomas.hiller[at]leibniz-liag.de +0057 % Author: see AUTHORS.md +0058 % email: see AUTHORS.md 0059 % License: MIT License (at end) 0060 0061 %------------- BEGIN CODE -------------- @@ -185,138 +185,139 @@

    SOURCE CODE ^% start values for E and T 0086 x0 = zeros(1,2*nExp); 0087 for i = 1:nExp -0088 x0(2*i-1) = max(signal)/nExp; -0089 x0(2*i) = i*max(t)/4; -0090 end -0091 -0092 switch parameter.optim -0093 case 'on' -0094 switch flag -0095 case 'T1' -0096 % solver options -0097 options = optimoptions('lsqcurvefit'); -0098 options.Display = parameter.info; -0099 options.OptimalityTolerance = 1e-18; -0100 options.StepTolerance = 1e-18; -0101 % options.MaxIterations = 1e3; -0102 [x,~,~,~,output,~,jacobian] = lsqcurvefit(@(x,t)fcn_fitFreeT1(x,t,IRfac),... -0103 x0,t,s,zeros(size(x0)),[],options); -0104 case 'T2' -0105 % solver options -0106 options = optimoptions('lsqnonlin'); -0107 options.Algorithm = 'levenberg-marquardt'; -0108 options.Display = parameter.info; -0109 options.OptimalityTolerance = 1e-18; -0110 options.StepTolerance = 1e-18; -0111 % options.MaxIterations = 1e3; -0112 -0113 iparam.t = t; -0114 iparam.s = s; -0115 [x,~,~,~,output,~,jacobian] = lsqnonlin(@(x)fcn_fitFreeT2w(x,iparam),... -0116 x0,zeros(size(x0)),[],options); -0117 % [x,~,~,~,output,~,jacobian] = lsqcurvefit(@fcn_fitFreeT2,... -0118 % x0,t,s,zeros(size(x0)),[],options); -0119 end -0120 case 'off' -0121 % solver options -0122 options = optimset('Display',parameter.info,'MaxFunEvals',10^6,... -0123 'MaxIter',5000,'TolFun',1e-12,'TolX',1e-12); -0124 switch flag -0125 case 'T1' -0126 [x,~,~,output] = fminsearchbnd(@(x) fcn_fitFreeT1_fmin(x,t,s,IRfac),... -0127 x0,zeros(size(x0)),[],options); -0128 case 'T2' -0129 [x,~,~,output] = fminsearchbnd(@(x) fcn_fitFreeT2_fmin(x,t,s,e),... -0130 x0,zeros(size(x0)),[],options); -0131 end -0132 end -0133 -0134 % get the fit -0135 fit_t = t; -0136 switch flag -0137 case 'T1' -0138 fit_s = fcn_fitFreeT1(x,fit_t,IRfac); -0139 case 'T2' -0140 fit_s = fcn_fitFreeT2(x,fit_t); -0141 end -0142 -0143 % get residuals and error measures -0144 if isfield(parameter,'W') -0145 % when signal gating was used the error estimates need to be adjusted -0146 out = getFitErrors(signal,fit_s,parameter.noise,parameter.W); -0147 else -0148 out = getFitErrors(signal,fit_s,parameter.noise); -0149 end -0150 -0151 % get Jacobian -0152 switch parameter.optim -0153 case 'on' -0154 % nothing to do because the Optim. Toolbox gives the jacobian as -0155 % output -0156 case 'off' -0157 jacobian = getFitFreeJacobian(x,t,flag,IRfac); -0158 end -0159 -0160 % confidence interval -0161 ci = getConfInterval(out.resnorm,jacobian,0.05); -0162 -0163 % sort the relaxation times in ascending order -0164 E0 = x(1:2:end); -0165 T = x(2:2:end); -0166 [T,idx] = sort(T); -0167 E0 = E0(idx); -0168 ciT = ci(2:2:end); -0169 ciE = ci(1:2:end); -0170 ciT = ciT(idx); -0171 ciE = ciE(idx); -0172 ci(2:2:end) = ciT; -0173 ci(1:2:end) = ciE; -0174 -0175 % output struct -0176 fitdata.E0 = E0; -0177 switch flag -0178 case 'T1' -0179 fitdata.T1 = T; -0180 case 'T2' -0181 fitdata.T2 = T; -0182 end -0183 fitdata.fit_t = fit_t; -0184 fitdata.fit_s = fit_s; -0185 fitdata.resnorm = out.resnorm; -0186 fitdata.residual = out.residual; -0187 fitdata.errornorm = out.errnorm1; -0188 fitdata.rms = out.rms; -0189 fitdata.chi2 = out.chi2; -0190 fitdata.ci = ci; -0191 fitdata.x = x; -0192 fitdata.output = output; -0193 -0194 return -0195 -0196 %------------- END OF CODE -------------- -0197 -0198 %% License: -0199 % MIT License -0200 % -0201 % Copyright (c) 2018 Thomas Hiller -0202 % -0203 % Permission is hereby granted, free of charge, to any person obtaining a copy -0204 % of this software and associated documentation files (the "Software"), to deal -0205 % in the Software without restriction, including without limitation the rights -0206 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0207 % copies of the Software, and to permit persons to whom the Software is -0208 % furnished to do so, subject to the following conditions: -0209 % -0210 % The above copyright notice and this permission notice shall be included in all -0211 % copies or substantial portions of the Software. -0212 % -0213 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0214 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0215 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0216 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0217 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0218 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0219 % SOFTWARE. +0088 x0(2*i-1) = i*max(signal)/nExp; +0089 x0(2*i) = i*max(t)/nExp; +0090 % x0(2*i) = exp(i*max(log(t))/nExp); +0091 end +0092 +0093 switch parameter.optim +0094 case 'on' +0095 switch flag +0096 case 'T1' +0097 % solver options +0098 options = optimoptions('lsqcurvefit'); +0099 options.Display = parameter.info; +0100 options.OptimalityTolerance = 1e-18; +0101 options.StepTolerance = 1e-18; +0102 % options.MaxIterations = 1e3; +0103 [x,~,~,~,output,~,jacobian] = lsqcurvefit(@(x,t)fcn_fitFreeT1(x,t,IRfac),... +0104 x0,t,s,zeros(size(x0)),[],options); +0105 case 'T2' +0106 % solver options +0107 options = optimoptions('lsqnonlin'); +0108 options.Algorithm = 'levenberg-marquardt'; +0109 options.Display = parameter.info; +0110 options.OptimalityTolerance = 1e-18; +0111 options.StepTolerance = 1e-18; +0112 % options.MaxIterations = 1e3; +0113 +0114 iparam.t = t; +0115 iparam.s = s; +0116 % [x,~,~,~,output,~,jacobian] = lsqnonlin(@(x)fcn_fitFreeT2w(x,iparam),... +0117 % x0,zeros(size(x0)),[],options); +0118 [x,~,~,~,output,~,jacobian] = lsqcurvefit(@fcn_fitFreeT2,... +0119 x0,t,s,zeros(size(x0)),[],options); +0120 end +0121 case 'off' +0122 % solver options +0123 options = optimset('Display',parameter.info,'MaxFunEvals',10^6,... +0124 'MaxIter',5000,'TolFun',1e-12,'TolX',1e-12); +0125 switch flag +0126 case 'T1' +0127 [x,~,~,output] = fminsearchbnd(@(x) fcn_fitFreeT1_fmin(x,t,s,IRfac),... +0128 x0,zeros(size(x0)),[],options); +0129 case 'T2' +0130 [x,~,~,output] = fminsearchbnd(@(x) fcn_fitFreeT2_fmin(x,t,s,e),... +0131 x0,zeros(size(x0)),[],options); +0132 end +0133 end +0134 +0135 % get the fit +0136 fit_t = t; +0137 switch flag +0138 case 'T1' +0139 fit_s = fcn_fitFreeT1(x,fit_t,IRfac); +0140 case 'T2' +0141 fit_s = fcn_fitFreeT2(x,fit_t); +0142 end +0143 +0144 % get residuals and error measures +0145 if isfield(parameter,'W') +0146 % when signal gating was used the error estimates need to be adjusted +0147 out = getFitErrors(signal,fit_s,parameter.noise,parameter.W); +0148 else +0149 out = getFitErrors(signal,fit_s,parameter.noise); +0150 end +0151 +0152 % get Jacobian +0153 switch parameter.optim +0154 case 'on' +0155 % nothing to do because the Optim. Toolbox gives the jacobian as +0156 % output +0157 case 'off' +0158 jacobian = getFitFreeJacobian(x,t,flag,IRfac); +0159 end +0160 +0161 % confidence interval +0162 ci = getConfInterval(out.resnorm,jacobian,0.05); +0163 +0164 % sort the relaxation times in ascending order +0165 E0 = x(1:2:end); +0166 T = x(2:2:end); +0167 [T,idx] = sort(T); +0168 E0 = E0(idx); +0169 ciT = ci(2:2:end); +0170 ciE = ci(1:2:end); +0171 ciT = ciT(idx); +0172 ciE = ciE(idx); +0173 ci(2:2:end) = ciT; +0174 ci(1:2:end) = ciE; +0175 +0176 % output struct +0177 fitdata.E0 = E0; +0178 switch flag +0179 case 'T1' +0180 fitdata.T1 = T; +0181 case 'T2' +0182 fitdata.T2 = T; +0183 end +0184 fitdata.fit_t = fit_t; +0185 fitdata.fit_s = fit_s; +0186 fitdata.resnorm = out.resnorm; +0187 fitdata.residual = out.residual; +0188 fitdata.errornorm = out.errnorm1; +0189 fitdata.rms = out.rms; +0190 fitdata.chi2 = out.chi2; +0191 fitdata.ci = ci; +0192 fitdata.x = x; +0193 fitdata.output = output; +0194 +0195 return +0196 +0197 %------------- END OF CODE -------------- +0198 +0199 %% License: +0200 % MIT License +0201 % +0202 % Copyright (c) 2018 Thomas Hiller +0203 % +0204 % Permission is hereby granted, free of charge, to any person obtaining a copy +0205 % of this software and associated documentation files (the "Software"), to deal +0206 % in the Software without restriction, including without limitation the rights +0207 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0208 % copies of the Software, and to permit persons to whom the Software is +0209 % furnished to do so, subject to the following conditions: +0210 % +0211 % The above copyright notice and this permission notice shall be included in all +0212 % copies or substantial portions of the Software. +0213 % +0214 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0215 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0216 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0217 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0218 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0219 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0220 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/fitDataLSQ.html b/doc/nucleus/functions/inversion/fitDataLSQ.html index 8fbca76..6f1f33a 100644 --- a/doc/nucleus/functions/inversion/fitDataLSQ.html +++ b/doc/nucleus/functions/inversion/fitDataLSQ.html @@ -41,6 +41,7 @@

    DESCRIPTION ^DESCRIPTION ^DESCRIPTION ^DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls: +
  • applyRegularization applies regularization procedures from the
  • createKernelMatrix creates a Kernel matrix from signal time vector "t"
  • getFitErrors calculates all relevant fitting errors for the NMR inversion
  • getTLogMean calculates the T logmean value out of a relaxation time
  • This function is called by: +
  • runInversionBatch batch processes the inversion using for all NMR signals
  • runInversionStd controls the standard inversion process to invert a
  • estimateUncertainty calculates pseudo uncertainty estimates for multi
  • @@ -124,220 +127,238 @@

    SOURCE CODE ^% T1T2 : flag between 'T1' or 'T2' inversion 0015 % T1IRfac : either '1' or '2' depending on T1 method 0016 % Tb : bulk relaxation time -0017 % Tint : relaxation times [log10(tmin) log10(tmax) Ndec] -0018 % regMethod: 'manual', 'gcv_tikh', 'gcv_trunc', -0019 % 'gcv_damp', 'discrep' -0020 % Lorder : smoothness constraint (derivative matrix) -0021 % lambda : regularization parameter (for 'manual') -0022 % noise : noise level needed for 'discrep' discrepancy -0023 % principle -0024 % W : error weighting matrix (optional) -0025 % solver : LSQ solver ('lsqlin' or 'lsqnonneg') -0026 % -0027 % Outputs: -0028 % fitdata - struct that holds the inversion results: -0029 % fit_t : time vector for plotting -0030 % fit_s : signal vector for plotting -0031 % T1T2me : relaxation time values -0032 % T1T2f : relaxation time spectrum -0033 % Tlgm : T logmean -0034 % E0 : initial amplitude at t=0 (T2) or t=inf (T1) -0035 % resnorm : residual norm -0036 % residual : vector of residuals -0037 % chi2 : chi square error -0038 % rms : RMS error -0039 % lambda_out : regularization parameter lambda determined -0040 % by the different options from the 'regu' -0041 % toolbox -0042 % KK : Kernel matrix -0043 % L : derivative matrix -0044 % xn : model norm |L*x|_2 -0045 % rn : residual norm |A*x-b|_2 -0046 % -0047 % Example: -0048 % [fitdata] = fitDataLSQ(t,s,parameter) +0017 % Td : diffusion relaxation time +0018 % Tint : relaxation times [log10(tmin) log10(tmax) Ndec] +0019 % regMethod: 'manual', 'gcv_tikh', 'gcv_trunc', +0020 % 'gcv_damp', 'discrep' +0021 % Lorder : smoothness constraint (derivative matrix) +0022 % lambda : regularization parameter (for 'manual') +0023 % noise : noise level needed for 'discrep' discrepancy +0024 % principle +0025 % W : error weighting matrix (optional) +0026 % solver : LSQ solver ('lsqlin' or 'lsqnonneg') +0027 % bounds : predefined lower and upper bounds and start +0028 % model (optional and only for 'lsqlin') +0029 % +0030 % Outputs: +0031 % fitdata - struct that holds the inversion results: +0032 % fit_t : time vector for plotting +0033 % fit_s : signal vector for plotting +0034 % T1T2me : relaxation time values +0035 % T1T2f : relaxation time spectrum +0036 % Tlgm : T log-mean +0037 % E0 : initial amplitude at t=0 (T2) or t=inf (T1) +0038 % resnorm : residual norm +0039 % residual : vector of residuals +0040 % chi2 : chi square error +0041 % rms : RMS error +0042 % lambda_out : regularization parameter lambda determined +0043 % by the different options from the 'regu' +0044 % toolbox +0045 % KK : Kernel matrix +0046 % L : derivative matrix +0047 % xn : model norm |L*x|_2 +0048 % rn : residual norm |A*x-b|_2 0049 % -0050 % Other m-files required: -0051 % Optimization Toolbox from Mathworks (optional) -0052 % Regularization Toolbox -0053 % applyRegularization -0054 % createKernelMatrix -0055 % getFitErrors -0056 % getTLogMean -0057 % lsqnonneg -0058 % lsqlin (optional) -0059 % -0060 % Subfunctions: -0061 % none +0050 % Example: +0051 % [fitdata] = fitDataLSQ(t,s,parameter) +0052 % +0053 % Other m-files required: +0054 % Optimization Toolbox from Mathworks (optional) +0055 % Regularization Toolbox +0056 % applyRegularization +0057 % createKernelMatrix +0058 % getFitErrors +0059 % getTLogMean +0060 % lsqnonneg +0061 % lsqlin (optional) 0062 % -0063 % MAT-files required: +0063 % Subfunctions: 0064 % none 0065 % -0066 % See also: -0067 % Author: Thomas Hiller -0068 % email: thomas.hiller[at]leibniz-liag.de -0069 % License: MIT License (at end) -0070 -0071 %------------- BEGIN CODE -------------- -0072 -0073 % make input column vectors -0074 time = time(:); -0075 signal = signal(:); -0076 -0077 % get the maximum value of the signal to scale the signal for the inversion -0078 % to 1 -0079 maxS = max(signal); -0080 -0081 % temporary variables -0082 t = time; -0083 g = signal./maxS; -0084 -0085 % get the input parameters -0086 flag = parameter.T1T2; % T1/T2 switch -0087 T1IRfac = parameter.T1IRfac; % T1 Sat/Inv Recovery factor -0088 Tb = parameter.Tb; % bulk relaxation time -0089 tstart = parameter.Tint(1); % log10 value -0090 tend = parameter.Tint(2); % log10 value -0091 N = parameter.Tint(3); % N per decade -0092 regMethod = parameter.regMethod; % regularization method -0093 order = parameter.Lorder; % smoothness constraint -0094 lambda = parameter.lambda; % regularization parameter -0095 noise = parameter.noise; % noise -0096 -0097 % create the relaxation time vector -0098 T1T2me = logspace(tstart,tend,(tend-tstart)*N); -0099 -0100 % create the Kernel matrix for inversion -0101 K = createKernelMatrix(t,T1T2me,Tb,flag,T1IRfac); -0102 -0103 if strcmp(parameter.solver,'lsqlin') -0104 % initial T2 amplitudes -0105 f0 = zeros(size(T1T2me)); -0106 f0_lb = f0; -0107 f0_ub = 1.5*max(g)*ones(size(T1T2me)); -0108 end -0109 -0110 % derivative matrix -0111 L = get_l(length(T1T2me),order); -0112 -0113 % scale the noise and error matrix W accordingly -0114 noise = noise./maxS; -0115 if isfield(parameter,'W') -0116 e = diag(parameter.W); -0117 e = e./maxS; -0118 W = diag(e); -0119 end -0120 -0121 % apply error weight matrix -0122 if isfield(parameter,'W') -0123 g = W*g; -0124 K = W*K; -0125 end +0066 % MAT-files required: +0067 % none +0068 % +0069 % See also: +0070 % Author: see AUTHORS.md +0071 % email: see AUTHORS.md +0072 % License: MIT License (at end) +0073 +0074 %------------- BEGIN CODE -------------- +0075 +0076 % make input column vectors +0077 time = time(:); +0078 signal = signal(:); +0079 +0080 % get the maximum value of the signal to scale the signal for the inversion +0081 % to 1 +0082 maxS = max(signal); +0083 +0084 % temporary variables +0085 t = time; +0086 g = signal./maxS; +0087 +0088 % get the input parameters +0089 flag = parameter.T1T2; % T1/T2 switch +0090 T1IRfac = parameter.T1IRfac; % T1 Sat/Inv Recovery factor +0091 Tb = parameter.Tb; % bulk relaxation time +0092 Td = parameter.Td; % diffusion relaxation time +0093 tstart = parameter.Tint(1); % log10 value +0094 tend = parameter.Tint(2); % log10 value +0095 N = parameter.Tint(3); % N per decade +0096 regMethod = parameter.regMethod; % regularization method +0097 order = parameter.Lorder; % smoothness constraint +0098 lambda = parameter.lambda; % regularization parameter +0099 noise = parameter.noise; % noise +0100 +0101 % create the relaxation time vector +0102 T1T2me = logspace(tstart,tend,(tend-tstart)*N); +0103 +0104 % create the Kernel matrix for inversion +0105 K = createKernelMatrix(t,T1T2me,Tb,Td,flag,T1IRfac); +0106 +0107 if strcmp(parameter.solver,'lsqlin') +0108 if isfield(parameter,'bounds') +0109 f0 = parameter.bounds.f0; +0110 f0_lb = parameter.bounds.lb; +0111 f0_ub = parameter.bounds.ub; +0112 else +0113 % initial T2 amplitudes +0114 f0 = zeros(size(T1T2me)); +0115 f0_lb = f0; +0116 f0_ub = 1.5*max(g)*ones(size(T1T2me)); +0117 % T2 measurements: cut everything < first considered echo to zero +0118 f0_ub(T1T2me < time(1)/5) = 0; +0119 % T1 measurements: cut everything > 5*time of last point in SR-curve +0120 % f0_ub(T1T2me > time(end)) = 0; +0121 end +0122 end +0123 +0124 % derivative matrix +0125 L = get_l(length(T1T2me),order); 0126 -0127 % extend K and apply regularization -0128 % 'manual' | 'gcv_tikh' | 'gcv_trunc' | 'gcv_damp' | 'discrep' -0129 [KK,lambda_out] = applyRegularization(K,g,L,lambda,regMethod,order,noise); -0130 -0131 % extend g accordingly -0132 gg = g; -0133 gg(length(g)+1:length(g)+size(L,1),1) = 0; +0127 % scale the noise and error matrix W accordingly +0128 noise = noise./maxS; +0129 if isfield(parameter,'W') +0130 e = diag(parameter.W); +0131 e = e./maxS; +0132 W = diag(e); +0133 end 0134 -0135 switch parameter.solver -0136 case 'lsqlin' -0137 options = optimoptions('lsqlin'); -0138 options.Display = parameter.info; -0139 options.OptimalityTolerance = 1e-18; -0140 options.StepTolerance = 1e-18; -0141 [f,~,~,~,~,~] = lsqlin(KK,gg,[],[],[],[],... -0142 f0_lb,f0_ub,[],options); -0143 case 'lsqnonneg' -0144 options = optimset('Display',parameter.info,'TolX',1e-12); -0145 [f,~,~,~,~,~] = lsqnonneg(KK,gg,options); -0146 end -0147 -0148 % rescale f so that the sum(f)= unscaled E0 -0149 f = (f.*maxS); -0150 -0151 % the 'inverted' signal -0152 gg_fit = KK*f; -0153 % cut off the end which was needed for regularization -0154 s_fit = gg_fit(1:length(t),1); -0155 -0156 % get residuals and error measures -0157 if isfield(parameter,'W') -0158 % normalize the fit because the signal was error weighted for the -0159 % inversion -0160 e = diag(W); -0161 einv = 1./e; -0162 Winv = diag(einv); -0163 s_fit = Winv * s_fit; -0164 -0165 % because signal and s_fit are unscaled the initial values for noise -0166 % and W are used to get the error estimates -0167 out = getFitErrors(signal,s_fit,parameter.noise,parameter.W); -0168 else -0169 out = getFitErrors(signal,s_fit,parameter.noise); -0170 end -0171 -0172 % L-curve parameter -0173 % model norm |L*x|_2 -0174 xn = norm(L*f,2); -0175 % residual norm |A*x-b|_2 -0176 rn = norm(out.residual,2); -0177 -0178 % get "initial" value E0 -0179 if strcmp(flag,'T1') -0180 t2 = 10*time(end); -0181 K2 = createKernelMatrix(t2,T1T2me,Tb,flag,T1IRfac); -0182 elseif strcmp(flag,'T2') -0183 t2 = 0; -0184 K2 = createKernelMatrix(t2,T1T2me,Tb,flag,T1IRfac); -0185 end -0186 E0 = K2*f; -0187 -0188 % output struct -0189 fitdata.fit_t = time(:); -0190 fitdata.fit_s = s_fit(:); -0191 fitdata.T1T2me = T1T2me(:); -0192 fitdata.T1T2f = f(:); -0193 fitdata.Tlgm = getTLogMean(T1T2me,f); -0194 fitdata.E0 = E0; -0195 fitdata.resnorm = out.resnorm; -0196 fitdata.residual = out.residual; -0197 fitdata.chi2 = out.chi2; -0198 fitdata.rms = out.rms; -0199 fitdata.lambda_out = lambda_out; -0200 fitdata.KK = KK; -0201 fitdata.L = L; -0202 fitdata.xn = xn; -0203 fitdata.rn = rn; +0135 % apply error weight matrix +0136 if isfield(parameter,'W') +0137 g = W*g; +0138 K = W*K; +0139 end +0140 +0141 % extend K and apply regularization +0142 % 'manual' | 'gcv_tikh' | 'gcv_trunc' | 'gcv_damp' | 'discrep' +0143 [KK,lambda_out] = applyRegularization(K,g,L,lambda,regMethod,order,noise); +0144 +0145 % extend g accordingly +0146 gg = g; +0147 gg(length(g)+1:length(g)+size(L,1),1) = 0; +0148 +0149 switch parameter.solver +0150 case 'lsqlin' +0151 options = optimoptions('lsqlin'); +0152 options.Display = parameter.info; +0153 options.OptimalityTolerance = 1e-18; +0154 options.StepTolerance = 1e-18; +0155 if isfield(parameter,'bounds') +0156 [f,~,~,~,~,~] = lsqlin(KK,gg,[],[],[],[],... +0157 f0_lb,f0_ub,f0,options); +0158 else +0159 [f,~,~,~,~,~] = lsqlin(KK,gg,[],[],[],[],... +0160 f0_lb,f0_ub,[],options); +0161 end +0162 case 'lsqnonneg' +0163 options = optimset('Display',parameter.info,'TolX',1e-12); +0164 [f,~,~,~,~,~] = lsqnonneg(KK,gg,options); +0165 end +0166 +0167 % rescale f so that the sum(f) = unscaled E0 +0168 f = (f.*maxS); +0169 +0170 % the 'inverted' signal +0171 gg_fit = KK*f; +0172 % cut off the end which was needed for regularization +0173 s_fit = gg_fit(1:length(t),1); +0174 +0175 % get residuals and error measures +0176 if isfield(parameter,'W') +0177 % normalize the fit because the signal was error weighted for the +0178 % inversion +0179 e = diag(W); +0180 einv = 1./e; +0181 Winv = diag(einv); +0182 s_fit = Winv * s_fit; +0183 +0184 % because signal and s_fit are unscaled the initial values for noise +0185 % and W are used to get the error estimates +0186 out = getFitErrors(signal,s_fit,parameter.noise,parameter.W); +0187 else +0188 out = getFitErrors(signal,s_fit,parameter.noise); +0189 end +0190 +0191 % L-curve parameter +0192 % model norm |L*x|_2 +0193 xn = norm(L*f,2); +0194 % residual norm |A*x-b|_2 +0195 rn = norm(out.residual,2); +0196 +0197 % get "initial" value E0 +0198 if strcmp(flag,'T1') +0199 K0 = createKernelMatrix(10*time(end),T1T2me,Tb,Td,flag,T1IRfac); +0200 elseif strcmp(flag,'T2') +0201 K0 = createKernelMatrix(0,T1T2me,Tb,Td,flag,T1IRfac); +0202 end +0203 E0 = K0*f; 0204 -0205 return -0206 -0207 %------------- END OF CODE -------------- -0208 -0209 %% License: -0210 % MIT License -0211 % -0212 % Copyright (c) 2018 Thomas Hiller -0213 % -0214 % Permission is hereby granted, free of charge, to any person obtaining a copy -0215 % of this software and associated documentation files (the "Software"), to deal -0216 % in the Software without restriction, including without limitation the rights -0217 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0218 % copies of the Software, and to permit persons to whom the Software is -0219 % furnished to do so, subject to the following conditions: -0220 % -0221 % The above copyright notice and this permission notice shall be included in all -0222 % copies or substantial portions of the Software. -0223 % -0224 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0225 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0226 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0227 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0228 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0229 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0230 % SOFTWARE. +0205 % output struct +0206 fitdata.fit_t = time(:); +0207 fitdata.fit_s = s_fit(:); +0208 fitdata.T1T2me = T1T2me(:); +0209 fitdata.T1T2f = f(:); +0210 fitdata.Tlgm = getTLogMean(T1T2me,f); +0211 fitdata.E0 = E0; +0212 fitdata.ciE0 = NaN; +0213 fitdata.resnorm = out.resnorm; +0214 fitdata.residual = out.residual; +0215 fitdata.chi2 = out.chi2; +0216 fitdata.rms = out.rms; +0217 fitdata.lambda_out = lambda_out; +0218 fitdata.KK = KK; +0219 fitdata.L = L; +0220 fitdata.xn = xn; +0221 fitdata.rn = rn; +0222 +0223 return +0224 +0225 %------------- END OF CODE -------------- +0226 +0227 %% License: +0228 % MIT License +0229 % +0230 % Copyright (c) 2018 Thomas Hiller +0231 % +0232 % Permission is hereby granted, free of charge, to any person obtaining a copy +0233 % of this software and associated documentation files (the "Software"), to deal +0234 % in the Software without restriction, including without limitation the rights +0235 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0236 % copies of the Software, and to permit persons to whom the Software is +0237 % furnished to do so, subject to the following conditions: +0238 % +0239 % The above copyright notice and this permission notice shall be included in all +0240 % copies or substantial portions of the Software. +0241 % +0242 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0243 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0244 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0245 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0246 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0247 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0248 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/fitDataLUdecomp.html b/doc/nucleus/functions/inversion/fitDataLUdecomp.html index 38f6098..e19f71b 100644 --- a/doc/nucleus/functions/inversion/fitDataLUdecomp.html +++ b/doc/nucleus/functions/inversion/fitDataLUdecomp.html @@ -39,6 +39,7 @@

    DESCRIPTION ^DESCRIPTION ^DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    This function calls:
      -
    • createKernelMatrix creates a Kernel matrix from signal time vector "t"
    • getFitErrors calculates all relevant fitting errors for the NMR inversion
    • getTLogMean calculates the T logmean value out of a relaxation time
    +
  • createKernelMatrix creates a Kernel matrix from signal time vector "t"
  • getFitErrors calculates all relevant fitting errors for the NMR inversion
  • getTLogMean calculates the T logmean value out of a relaxation time
  • This function is called by: @@ -113,185 +114,187 @@

    SOURCE CODE ^% T1T2 : flag between 'T1' or 'T2' inversion 0013 % T1IRfac : either '1' or '2' depending on T1 method 0014 % Tb : bulk relaxation time -0015 % Tint : relaxation times [log10(tmin) log10(tmax) Ndec] -0016 % Lorder : smoothness constraint (derivative matrix) -0017 % lambda : regularization parameter (if -1 automatic -0018 % regularization) -0019 % noise : noise level -0020 % -0021 % Outputs: -0022 % fitdata - struct that holds the inversion results: -0023 % fit_t : time vector for plotting -0024 % fit_s : signal vector for plotting -0025 % T1T2me : relaxation time values -0026 % T1T2f : relaxation time spectrum -0027 % Tlgm : T logmean -0028 % E0 : initial amplitude at t=0 (T2) or t=max (T1) -0029 % resnorm : residual norm -0030 % residual : vector of residuals -0031 % chi2 : chi square error -0032 % rms : RMS error -0033 % lambda_out : regularization parameter lambda determined -0034 % by the different options from the 'regu' -0035 % toolbox -0036 % KK : Kernel matrix -0037 % L : derivative matrix -0038 % xn : model norm |L*x|_2 -0039 % rn : residual norm |A*x-b|_2 -0040 % -0041 % Example: -0042 % [fitdata] = fitDataLUdecomp(t,s,parameter) -0043 % -0044 % Other m-files required: -0045 % createKernelMatrix -0046 % getFitErrors -0047 % getTLogMean -0048 % get_l (from 'Regularization Toolbox') -0049 % -0050 % Subfunctions: -0051 % none -0052 % -0053 % MAT-files required: -0054 % none -0055 % -0056 % See also: -0057 % Author: Thomas Hiller -0058 % email: thomas.hiller[at]leibniz-liag.de -0059 % NOTE: I harvested this routine partly from the Internet but forgot where -0060 % I found the routines ... so there is no warranty at all -0061 -0062 %------------- BEGIN CODE -------------- -0063 -0064 % make input column vectors -0065 time = time(:); -0066 signal = signal(:); -0067 -0068 % get the maximum value of the signal to scale the signal for the inversion -0069 % to 1 -0070 maxS = max(signal); -0071 -0072 % temporary variables -0073 t = time; -0074 g = signal./maxS; -0075 -0076 % get the input parameters -0077 flag = parameter.T1T2; % T1/T2 switch -0078 T1IRfac = parameter.T1IRfac; % T1 Sat/Inv Recovery factor -0079 Tb = parameter.Tb; % bulk relaxation time -0080 tstart = parameter.Tint(1); % log10 value -0081 tend = parameter.Tint(2); % log10 value -0082 N = parameter.Tint(3); % N per decade -0083 order = parameter.Lorder; % smoothness constraint -0084 lambda = parameter.lambda; % regularization parameter -0085 noise = parameter.noise; % noise -0086 -0087 % create the relaxation time vector -0088 T1T2me = logspace(tstart,tend,(tend-tstart)*N); -0089 -0090 % create the Kernel matrix -0091 K = createKernelMatrix(t,T1T2me,Tb,flag,T1IRfac); -0092 -0093 % calculate reg matrix H -0094 m = length(T1T2me); -0095 B = get_l(m,order); -0096 H = B'*B; -0097 -0098 % scale the noise and error matrix W accordingly -0099 noise = noise./maxS; -0100 if isfield(parameter,'W') -0101 e = diag(parameter.W); -0102 e = e./maxS; -0103 W = diag(e); -0104 end -0105 -0106 % apply error weight matrix -0107 if isfield(parameter,'W') -0108 g = W*g; -0109 K = W*K; -0110 end -0111 -0112 % automatic regularization -0113 if lambda == -1 -0114 lambda = trace(K'*K)/trace(H); -0115 end -0116 -0117 % calculate A = K'*K + lambda*H -0118 A = K'*K + lambda*H; -0119 % calculate y = K'*g -0120 y = K'*g; -0121 % calculate f by LU decomposition -0122 [L,U] = lu(A); -0123 f = U\(L\y); -0124 -0125 % now iterate, mapping negative values to zero. -0126 e = 2/max(eig(A)); -0127 A = K'*K; % no regularization now -0128 for i = 1:1000 -0129 f = (f>0).*f; % map neg to zero -0130 f =(eye(m)-e*A)*f+e*y; -0131 end -0132 f = (f>0).*f; % map neg to zero again -0133 -0134 % rescale f so that the sum(f)= unscaled E0 -0135 f = (f.*maxS); -0136 -0137 % the inverted signal -0138 s_fit = K*f; -0139 s_fit = s_fit(1:length(t),1); -0140 -0141 % get residuals and error measures -0142 if isfield(parameter,'W') -0143 % normalize the fit because the signal was error weighted for the -0144 % inversion -0145 e = diag(W); -0146 einv = 1./e; -0147 Winv = diag(einv); -0148 s_fit = Winv * s_fit; -0149 -0150 % because signal and s_fit are unscaled the initial values for noise -0151 % and W are used to get the error estimates -0152 out = getFitErrors(signal,s_fit,parameter.noise,parameter.W); -0153 else -0154 out = getFitErrors(signal,s_fit,parameter.noise); -0155 end -0156 -0157 % derivative matrix -0158 L = get_l(length(T1T2me),order); -0159 % L-curve parameter -0160 % model norm |L*x|_2 -0161 xn = norm(L*f,2); -0162 % residual norm |A*x-b|_2 -0163 rn = norm(out.residual,2); -0164 -0165 % get "initial" value E0 -0166 if strcmp(flag,'T1') -0167 t2 = 10*time(end); -0168 K2 = createKernelMatrix(t2,T1T2me,Tb,flag,T1IRfac); -0169 elseif strcmp(flag,'T2') -0170 t2 = 0; -0171 K2 = createKernelMatrix(t2,T1T2me,Tb,flag,T1IRfac); -0172 end -0173 E0 = K2*f; -0174 -0175 % output struct -0176 fitdata.fit_t = time(:); -0177 fitdata.fit_s = s_fit(:); -0178 fitdata.T1T2me = T1T2me(:); -0179 fitdata.T1T2f = f(:); -0180 fitdata.Tlgm = getTLogMean(T1T2me,f); -0181 fitdata.E0 = E0; -0182 fitdata.residual = out.residual; -0183 fitdata.chi2 = out.chi2; -0184 fitdata.rms = out.rms; -0185 fitdata.lambda_out = lambda; -0186 fitdata.KK = K; -0187 fitdata.L = L; -0188 fitdata.xn = xn; -0189 fitdata.rn = rn; -0190 -0191 return +0015 % Td : diffusion relaxation time +0016 % Tint : relaxation times [log10(tmin) log10(tmax) Ndec] +0017 % Lorder : smoothness constraint (derivative matrix) +0018 % lambda : regularization parameter (if -1 automatic +0019 % regularization) +0020 % noise : noise level +0021 % +0022 % Outputs: +0023 % fitdata - struct that holds the inversion results: +0024 % fit_t : time vector for plotting +0025 % fit_s : signal vector for plotting +0026 % T1T2me : relaxation time values +0027 % T1T2f : relaxation time spectrum +0028 % Tlgm : T logmean +0029 % E0 : initial amplitude at t=0 (T2) or t=max (T1) +0030 % resnorm : residual norm +0031 % residual : vector of residuals +0032 % chi2 : chi square error +0033 % rms : RMS error +0034 % lambda_out : regularization parameter lambda determined +0035 % by the different options from the 'regu' +0036 % toolbox +0037 % KK : Kernel matrix +0038 % L : derivative matrix +0039 % xn : model norm |L*x|_2 +0040 % rn : residual norm |A*x-b|_2 +0041 % +0042 % Example: +0043 % [fitdata] = fitDataLUdecomp(t,s,parameter) +0044 % +0045 % Other m-files required: +0046 % createKernelMatrix +0047 % getFitErrors +0048 % getTLogMean +0049 % get_l (from 'Regularization Toolbox') +0050 % +0051 % Subfunctions: +0052 % none +0053 % +0054 % MAT-files required: +0055 % none +0056 % +0057 % See also: +0058 % Author: see AUTHORS.md +0059 % email: see AUTHORS.md +0060 % NOTE: I harvested this routine partly from the Internet but forgot where +0061 % I found the routines ... so there is no warranty at all +0062 +0063 %------------- BEGIN CODE -------------- +0064 +0065 % make input column vectors +0066 time = time(:); +0067 signal = signal(:); +0068 +0069 % get the maximum value of the signal to scale the signal for the inversion +0070 % to 1 +0071 maxS = max(signal); +0072 +0073 % temporary variables +0074 t = time; +0075 g = signal./maxS; +0076 +0077 % get the input parameters +0078 flag = parameter.T1T2; % T1/T2 switch +0079 T1IRfac = parameter.T1IRfac; % T1 Sat/Inv Recovery factor +0080 Tb = parameter.Tb; % bulk relaxation time +0081 Td = parameter.Td; % diffusion relaxation time +0082 tstart = parameter.Tint(1); % log10 value +0083 tend = parameter.Tint(2); % log10 value +0084 N = parameter.Tint(3); % N per decade +0085 order = parameter.Lorder; % smoothness constraint +0086 lambda = parameter.lambda; % regularization parameter +0087 noise = parameter.noise; % noise +0088 +0089 % create the relaxation time vector +0090 T1T2me = logspace(tstart,tend,(tend-tstart)*N); +0091 +0092 % create the Kernel matrix +0093 K = createKernelMatrix(t,T1T2me,Tb,Td,flag,T1IRfac); +0094 +0095 % calculate reg matrix H +0096 m = length(T1T2me); +0097 B = get_l(m,order); +0098 H = B'*B; +0099 +0100 % scale the noise and error matrix W accordingly +0101 noise = noise./maxS; +0102 if isfield(parameter,'W') +0103 e = diag(parameter.W); +0104 e = e./maxS; +0105 W = diag(e); +0106 end +0107 +0108 % apply error weight matrix +0109 if isfield(parameter,'W') +0110 g = W*g; +0111 K = W*K; +0112 end +0113 +0114 % automatic regularization +0115 if lambda == -1 +0116 lambda = trace(K'*K)/trace(H); +0117 end +0118 +0119 % calculate A = K'*K + lambda*H +0120 A = K'*K + lambda*H; +0121 % calculate y = K'*g +0122 y = K'*g; +0123 % calculate f by LU decomposition +0124 [L,U] = lu(A); +0125 f = U\(L\y); +0126 +0127 % now iterate, mapping negative values to zero. +0128 e = 2/max(eig(A)); +0129 A = K'*K; % no regularization now +0130 for i = 1:1000 +0131 f = (f>0).*f; % map neg to zero +0132 f =(eye(m)-e*A)*f+e*y; +0133 end +0134 f = (f>0).*f; % map neg to zero again +0135 +0136 % rescale f so that the sum(f)= unscaled E0 +0137 f = (f.*maxS); +0138 +0139 % the inverted signal +0140 s_fit = K*f; +0141 s_fit = s_fit(1:length(t),1); +0142 +0143 % get residuals and error measures +0144 if isfield(parameter,'W') +0145 % normalize the fit because the signal was error weighted for the +0146 % inversion +0147 e = diag(W); +0148 einv = 1./e; +0149 Winv = diag(einv); +0150 s_fit = Winv * s_fit; +0151 +0152 % because signal and s_fit are unscaled the initial values for noise +0153 % and W are used to get the error estimates +0154 out = getFitErrors(signal,s_fit,parameter.noise,parameter.W); +0155 else +0156 out = getFitErrors(signal,s_fit,parameter.noise); +0157 end +0158 +0159 % derivative matrix +0160 L = get_l(length(T1T2me),order); +0161 % L-curve parameter +0162 % model norm |L*x|_2 +0163 xn = norm(L*f,2); +0164 % residual norm |A*x-b|_2 +0165 rn = norm(out.residual,2); +0166 +0167 % get "initial" value E0 +0168 if strcmp(flag,'T1') +0169 t2 = 10*time(end); +0170 K2 = createKernelMatrix(t2,T1T2me,Tb,Td,flag,T1IRfac); +0171 elseif strcmp(flag,'T2') +0172 t2 = 0; +0173 K2 = createKernelMatrix(t2,T1T2me,Tb,Td,flag,T1IRfac); +0174 end +0175 E0 = K2*f; +0176 +0177 % output struct +0178 fitdata.fit_t = time(:); +0179 fitdata.fit_s = s_fit(:); +0180 fitdata.T1T2me = T1T2me(:); +0181 fitdata.T1T2f = f(:); +0182 fitdata.Tlgm = getTLogMean(T1T2me,f); +0183 fitdata.E0 = E0; +0184 fitdata.residual = out.residual; +0185 fitdata.chi2 = out.chi2; +0186 fitdata.rms = out.rms; +0187 fitdata.lambda_out = lambda; +0188 fitdata.KK = K; +0189 fitdata.L = L; +0190 fitdata.xn = xn; +0191 fitdata.rn = rn; 0192 -0193 %------------- END OF CODE -------------- +0193 return +0194 +0195 %------------- END OF CODE --------------
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/fitDataMultiModal.html b/doc/nucleus/functions/inversion/fitDataMultiModal.html new file mode 100644 index 0000000..bd0ae6e --- /dev/null +++ b/doc/nucleus/functions/inversion/fitDataMultiModal.html @@ -0,0 +1,415 @@ + + + + Description of fitDataMultiModal + + + + + + + + + + + +

    fitDataMultiModal +

    + +

    PURPOSE ^

    +
    is a control routine that uses either 'lsqnonlin' or
    + +

    SYNOPSIS ^

    +
    function [fitdata] = fitDataMultiModal(time,signal,parameter,nModes)
    + +

    DESCRIPTION ^

    +
    fitDataMultiModal is a control routine that uses either 'lsqnonlin' or
    +'fminsearchbnd' to fit NMR data with 'nModes' multi modal relaxation time
    +distributions (T1 or T2)
    +
    + Syntax:
    +       fitDataMultiModal(time,signal,flag,parameter,nExp)
    +
    + InputsR:
    +       time - time vector
    +       signal - NMR signal vector (no complex data allowed!)
    +       parameter - struct that holds additional settings:
    +                   T1T2     : flag between 'T1' or 'T2' inversion
    +                   T1IRfac  : either '1' or '2' depending on T1 method
    +                   Tb       : bulk relaxation time
    +                   Td       : diffusion relaxation time
    +                   Tint     : relaxation times [log10(tmin) log10(tmax) Ndec]
    +                   noise    : noise level needed for 'discrep' discrepancy
    +                              principle
    +                   optim    : 'on' or 'off' (Optimization Toolbox)
    +                   W        : error weighting matrix (optional)
    +       nModes - No. of free distributions
    +
    + Outputs:
    +       fitdata - struct that holds the inversion results:
    +                   fit_t   : time vector for plotting
    +                   fit_s   : signal vector for plotting
    +                   T1T2me  : relaxation time values
    +                   T1T2f   : relaxation time spectrum
    +                   Tlgm    : T log-mean
    +                   E0      : initial amplitude at t=0 (T2) or t=max (T1)
    +                   ciE     : E0 confidence interval (NaN as placeholder)
    +                   resnorm : residual norm
    +                   residual: vector of residuals
    +                   errnorm : error norm
    +                   lambda_out : dummy 0
    +                   rms     : RMS error
    +                   chi2    : chi square error
    +                   ci      : confidence interval
    +                   T       : relaxation times per mode
    +                   S       : width per mode
    +                   E       : amplitude per mode;
    +                   x       : all parameters combined
    +                   lb      : lower bounds
    +                   ub      : upper bounds
    +                   output  : output struct (output from 'lsqnonlin' or
    +                             'fminsearchbnd')
    +
    + Example:
    +       [fitdata] = fitDataMultiModal(t,s,parameter,2)
    +
    + Other m-files required:
    +       createKernelMatrix
    +       estimateJacobian
    +       fcn_fitMultiModal
    +       fitDataFree
    +       fminsearchbnd
    +       getFitErrors
    +       getFitFreeJacobian
    +       getConfInterval
    +       lsqnonlin (Optimization Toolbox)
    +
    + Subfunctions:
    +       none
    +
    + MAT-files required:
    +       none
    +
    + See also:
    + Author: see AUTHORS.md
    + email: see AUTHORS.md
    + License: MIT License (at end)
    + + +

    CROSS-REFERENCE INFORMATION ^

    +This function calls: + +This function is called by: + + + + + +

    SOURCE CODE ^

    +
    0001 function [fitdata] = fitDataMultiModal(time,signal,parameter,nModes)
    +0002 %fitDataMultiModal is a control routine that uses either 'lsqnonlin' or
    +0003 %'fminsearchbnd' to fit NMR data with 'nModes' multi modal relaxation time
    +0004 %distributions (T1 or T2)
    +0005 %
    +0006 % Syntax:
    +0007 %       fitDataMultiModal(time,signal,flag,parameter,nExp)
    +0008 %
    +0009 % InputsR:
    +0010 %       time - time vector
    +0011 %       signal - NMR signal vector (no complex data allowed!)
    +0012 %       parameter - struct that holds additional settings:
    +0013 %                   T1T2     : flag between 'T1' or 'T2' inversion
    +0014 %                   T1IRfac  : either '1' or '2' depending on T1 method
    +0015 %                   Tb       : bulk relaxation time
    +0016 %                   Td       : diffusion relaxation time
    +0017 %                   Tint     : relaxation times [log10(tmin) log10(tmax) Ndec]
    +0018 %                   noise    : noise level needed for 'discrep' discrepancy
    +0019 %                              principle
    +0020 %                   optim    : 'on' or 'off' (Optimization Toolbox)
    +0021 %                   W        : error weighting matrix (optional)
    +0022 %       nModes - No. of free distributions
    +0023 %
    +0024 % Outputs:
    +0025 %       fitdata - struct that holds the inversion results:
    +0026 %                   fit_t   : time vector for plotting
    +0027 %                   fit_s   : signal vector for plotting
    +0028 %                   T1T2me  : relaxation time values
    +0029 %                   T1T2f   : relaxation time spectrum
    +0030 %                   Tlgm    : T log-mean
    +0031 %                   E0      : initial amplitude at t=0 (T2) or t=max (T1)
    +0032 %                   ciE     : E0 confidence interval (NaN as placeholder)
    +0033 %                   resnorm : residual norm
    +0034 %                   residual: vector of residuals
    +0035 %                   errnorm : error norm
    +0036 %                   lambda_out : dummy 0
    +0037 %                   rms     : RMS error
    +0038 %                   chi2    : chi square error
    +0039 %                   ci      : confidence interval
    +0040 %                   T       : relaxation times per mode
    +0041 %                   S       : width per mode
    +0042 %                   E       : amplitude per mode;
    +0043 %                   x       : all parameters combined
    +0044 %                   lb      : lower bounds
    +0045 %                   ub      : upper bounds
    +0046 %                   output  : output struct (output from 'lsqnonlin' or
    +0047 %                             'fminsearchbnd')
    +0048 %
    +0049 % Example:
    +0050 %       [fitdata] = fitDataMultiModal(t,s,parameter,2)
    +0051 %
    +0052 % Other m-files required:
    +0053 %       createKernelMatrix
    +0054 %       estimateJacobian
    +0055 %       fcn_fitMultiModal
    +0056 %       fitDataFree
    +0057 %       fminsearchbnd
    +0058 %       getFitErrors
    +0059 %       getFitFreeJacobian
    +0060 %       getConfInterval
    +0061 %       lsqnonlin (Optimization Toolbox)
    +0062 %
    +0063 % Subfunctions:
    +0064 %       none
    +0065 %
    +0066 % MAT-files required:
    +0067 %       none
    +0068 %
    +0069 % See also:
    +0070 % Author: see AUTHORS.md
    +0071 % email: see AUTHORS.md
    +0072 % License: MIT License (at end)
    +0073 
    +0074 %------------- BEGIN CODE --------------
    +0075 
    +0076 % make column vector
    +0077 t = time(:);
    +0078 s = signal(:);
    +0079 
    +0080 % error weights after gating
    +0081 if isfield(parameter,'W')
    +0082     e = diag(parameter.W);
    +0083     iparam.e = sqrt(e);
    +0084 end
    +0085 
    +0086 % get the input parameters
    +0087 % T1/T2 switch
    +0088 flag = parameter.T1T2;
    +0089 % T1 Sat/Inv Recovery factor
    +0090 T1IRfac = parameter.T1IRfac;
    +0091 % bulk relaxation time
    +0092 Tb = parameter.Tb;
    +0093 % diffusion relaxation time
    +0094 Td = parameter.Td;
    +0095 % smallest value in RTD (log10 value)
    +0096 tstart = parameter.Tint(1);
    +0097 % largest value in RTD (log10 value)
    +0098 tend = parameter.Tint(2);
    +0099 % N per decade in RTD
    +0100 N = parameter.Tint(3);
    +0101 
    +0102 % get boundary values for mu, sigma and amp by first applying a free
    +0103 % exponential fit
    +0104 param0.T1IRfac = T1IRfac;
    +0105 param0.noise = parameter.noise;
    +0106 param0.optim = parameter.optim;
    +0107 if isfield(parameter,'W')
    +0108     param0.W = parameter.W;
    +0109 end
    +0110 % free exponential fit to get some reasonable start values
    +0111 invstd0 = fitDataFree(t,s,flag,param0,nModes);
    +0112 
    +0113 % start values for E and T
    +0114 x0 = zeros(1,3*nModes);
    +0115 lb = zeros(1,3*nModes);
    +0116 ub = zeros(1,3*nModes);
    +0117 for i = 1:nModes
    +0118     % initial values for T, sigma and E
    +0119     x0(3*i-2) = log(invstd0.x(2*i));
    +0120     x0(3*i-1) = 1;
    +0121     x0(3*i) = invstd0.x(2*i-1);
    +0122     
    +0123     % lower bounds for T, sigma and E
    +0124     lb(3*i-2) = log(1e-6);%log(invstd0.x(2*i)*0.8);%log(invstd0.x(2*i) - 10*invstd0.ci(2*i));
    +0125     lb(3*i-1) = 0.01;
    +0126     lb(3*i) = invstd0.x(2*i-1)*0.8;%invstd0.x(2*i-1) - 10*invstd0.ci(2*i-1);
    +0127     
    +0128     % upper bounds for T, sigma and E
    +0129     ub(3*i-2) = log(10);%log(invstd0.x(2*i) + 50*invstd0.ci(2*i));
    +0130     ub(3*i-1) = 3.5;
    +0131     ub(3*i) = max(invstd0.E0)*1.1;%invstd0.x(2*i-1) + 50*invstd0.ci(2*i-1);
    +0132 end
    +0133 
    +0134 % switch off output if no option is given via 'parameter'
    +0135 if ~isfield(parameter,'info')
    +0136     parameter.info = 'off';
    +0137 end
    +0138 
    +0139 % create the relaxation time vector
    +0140 T1T2me = logspace(tstart,tend,(tend-tstart)*N);
    +0141 
    +0142 % just needed for debugging the Optimization Toolbox availability
    +0143 % parameter.optim = 'off';
    +0144 
    +0145 switch parameter.optim
    +0146     case 'on'
    +0147         % solver options
    +0148         options = optimoptions('lsqnonlin');
    +0149         options.Algorithm = 'levenberg-marquardt';
    +0150         options.Display = parameter.info;
    +0151         options.OptimalityTolerance = 1e-12;
    +0152         options.StepTolerance = 1e-12;
    +0153         
    +0154         iparam.optim = parameter.optim;
    +0155         iparam.flag = flag;
    +0156         iparam.T1IRfac = T1IRfac;
    +0157         iparam.nModes = nModes;
    +0158         iparam.t = t;
    +0159         iparam.s = s;
    +0160         iparam.T = T1T2me;
    +0161         iparam.Tb = Tb;
    +0162         iparam.Td = Td;
    +0163         [x,~,~,~,output,~,jacobian] = lsqnonlin(@(x)fcn_fitMultiModal(x,iparam),...
    +0164             x0,lb,ub,options);
    +0165         
    +0166     case 'off'
    +0167         % solver options
    +0168         options = optimset('Display',parameter.info,'MaxFunEvals',10^6,...
    +0169             'MaxIter',5000,'TolFun',1e-12,'TolX',1e-12);
    +0170         
    +0171         iparam.optim = parameter.optim;
    +0172         iparam.flag = flag;
    +0173         iparam.T1IRfac = T1IRfac;
    +0174         iparam.nModes = nModes;
    +0175         iparam.t = t;
    +0176         iparam.s = s;
    +0177         iparam.T = T1T2me;
    +0178         iparam.Tb = Tb;
    +0179         iparam.Td = Td;
    +0180         [x,~,~,output] = fminsearchbnd(@(x) fcn_fitMultiModal(x,iparam),...
    +0181             x0,lb,ub,options);
    +0182         
    +0183         % get Jacobian
    +0184         % therefore we need to switch the 'optim' on to get the correct
    +0185         % output of 'fcn_fitMultiModal'
    +0186         iparam.optim = 'on';
    +0187         jacobian = estimateJacobian(@(x)fcn_fitMultiModal(x,iparam),x);
    +0188 end
    +0189 
    +0190 % assemble the final RTD
    +0191 Tdist = 0;
    +0192 for i = 1:length(x)/3
    +0193     mu = exp(x(3*i-2)); % T
    +0194     sigma = x(3*i-1); % S
    +0195     amp = x(3*i); % E
    +0196     
    +0197     tmp = 1./( sigma*sqrt(2*pi)).*exp(-((log(T1T2me) - log(mu))/ sqrt(2)/sigma).^2);
    +0198     
    +0199     % scale to amplitude
    +0200     tmp = (tmp/sum(tmp)) * amp;
    +0201     % add the tmp per mu to Tdist
    +0202     Tdist = Tdist + tmp;
    +0203 end
    +0204 f = Tdist;
    +0205 % the fitted signal
    +0206 K = createKernelMatrix(t,T1T2me,Tb,Td,flag,1);
    +0207 si = K*f';
    +0208 
    +0209 % get the fit
    +0210 fit_t = t;
    +0211 fit_s = si;
    +0212 
    +0213 % get residuals and error measures
    +0214 if isfield(parameter,'W')
    +0215     % when signal gating was used the error estimates need to be adjusted
    +0216     out = getFitErrors(signal,fit_s,parameter.noise,parameter.W);
    +0217 else
    +0218     out = getFitErrors(signal,fit_s,parameter.noise);
    +0219 end
    +0220 
    +0221 % confidence interval
    +0222 ci = getConfInterval(out.resnorm,jacobian,0.05);
    +0223 
    +0224 % sort the relaxation times in ascending order and adjust the confidence
    +0225 % interval accordingly
    +0226 T = exp(x(1:3:end));
    +0227 S = x(2:3:end);
    +0228 E = x(3:3:end);
    +0229 [T,idx] = sort(T);
    +0230 S  = S(idx);
    +0231 E  = E(idx);
    +0232 ciT = ci(1:3:end);
    +0233 ciS = ci(2:3:end);
    +0234 ciE = ci(3:3:end);
    +0235 ciT = ciT(idx);
    +0236 ciS = ciS(idx);
    +0237 ciE = ciE(idx);
    +0238 ci(1:3:end) = ciT;
    +0239 ci(2:3:end) = ciS;
    +0240 ci(3:3:end) = ciE;
    +0241 
    +0242 % get "initial" value E0
    +0243 switch flag
    +0244     case 'T1'
    +0245         K0 = createKernelMatrix(10*time(end),T1T2me,Tb,Td,flag,T1IRfac);
    +0246     case 'T2'
    +0247         K0 = createKernelMatrix(0,T1T2me,Tb,Td,flag,T1IRfac);
    +0248 end
    +0249 E0 = K0*f';
    +0250 
    +0251 % output struct
    +0252 fitdata.fit_t = fit_t;
    +0253 fitdata.fit_s = fit_s;
    +0254 fitdata.T1T2me = T1T2me(:);
    +0255 fitdata.T1T2f = f(:);
    +0256 fitdata.Tlgm = getTLogMean(T1T2me,f);
    +0257 fitdata.E0 = E0;
    +0258 fitdata.ciE0 = NaN;
    +0259 fitdata.resnorm = out.resnorm;
    +0260 fitdata.residual = out.residual;
    +0261 fitdata.errornorm = out.errnorm1;
    +0262 fitdata.lambda_out = 0;
    +0263 fitdata.rms = out.rms;
    +0264 fitdata.chi2 = out.chi2;
    +0265 fitdata.ci = ci;
    +0266 fitdata.T = T;
    +0267 fitdata.S = S;
    +0268 fitdata.E = E;
    +0269 fitdata.x = x;
    +0270 fitdata.lb = lb;
    +0271 fitdata.ub = ub;
    +0272 fitdata.output = output;
    +0273 
    +0274 return
    +0275 
    +0276 %------------- END OF CODE --------------
    +0277 
    +0278 %% License:
    +0279 % MIT License
    +0280 %
    +0281 % Copyright (c) 2022 Thomas Hiller
    +0282 %
    +0283 % Permission is hereby granted, free of charge, to any person obtaining a copy
    +0284 % of this software and associated documentation files (the "Software"), to deal
    +0285 % in the Software without restriction, including without limitation the rights
    +0286 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +0287 % copies of the Software, and to permit persons to whom the Software is
    +0288 % furnished to do so, subject to the following conditions:
    +0289 %
    +0290 % The above copyright notice and this permission notice shall be included in all
    +0291 % copies or substantial portions of the Software.
    +0292 %
    +0293 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +0294 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +0295 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +0296 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +0297 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +0298 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +0299 % SOFTWARE.
    +
    Generated by m2html © 2005
    + + \ No newline at end of file diff --git a/doc/nucleus/functions/inversion/getChi2.html b/doc/nucleus/functions/inversion/getChi2.html index b1dbac0..c76f596 100644 --- a/doc/nucleus/functions/inversion/getChi2.html +++ b/doc/nucleus/functions/inversion/getChi2.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/getConfInterval.html b/doc/nucleus/functions/inversion/getConfInterval.html index ecf0574..100e87d 100644 --- a/doc/nucleus/functions/inversion/getConfInterval.html +++ b/doc/nucleus/functions/inversion/getConfInterval.html @@ -58,8 +58,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=getStudentInvCDF calculates the inverse of Student's t CDF using the This function is called by:
      -
    • fitDataFree is a control routine that uses 'lsqcurvefit' to fit NMR data
    +
  • fitDataFree is a control routine that uses 'lsqcurvefit' to fit NMR data
  • fitDataMultiModal is a control routine that uses either 'lsqnonlin' or
  • @@ -108,8 +108,8 @@

    SOURCE CODE ^% 0032 % See also: "Parameter Estimation and Inverse Problems", 2nd Ed. 0033 % by Aster et. al p.32 ff -0034 % Author: Thomas Hiller -0035 % email: thomas.hiller[at]leibniz-liag.de +0034 % Author: see AUTHORS.md +0035 % email: see AUTHORS.md 0036 % License: MIT License (at end) 0037 0038 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/getFitErrors.html b/doc/nucleus/functions/inversion/getFitErrors.html index 9ae2332..864b29b 100644 --- a/doc/nucleus/functions/inversion/getFitErrors.html +++ b/doc/nucleus/functions/inversion/getFitErrors.html @@ -61,8 +61,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 <li><a href=getChi2 the chi2 of a NMR fit (noise weighted error quality) This function is called by:
      -
    • fitDataFree is a control routine that uses 'lsqcurvefit' to fit NMR data
    • fitDataLSQ is a control routine that fits NMR data multi-exponentially;
    • fitDataLUdecomp is a control routine that uses a LU decomposition and the
    +
  • estimateUncertainty calculates pseudo uncertainty estimates for multi
  • fitDataFree is a control routine that uses 'lsqcurvefit' to fit NMR data
  • fitDataLSQ is a control routine that fits NMR data multi-exponentially;
  • fitDataLUdecomp is a control routine that uses a LU decomposition and the
  • fitDataMultiModal is a control routine that uses either 'lsqnonlin' or
  • @@ -114,8 +114,8 @@

    SOURCE CODE ^% none 0035 % 0036 % See also: -0037 % Author: Thomas Hiller -0038 % email: thomas.hiller[at]leibniz-liag.de +0037 % Author: see AUTHORS.md +0038 % email: see AUTHORS.md 0039 % License: MIT License (at end) 0040 0041 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/getFitFreeJacobian.html b/doc/nucleus/functions/inversion/getFitFreeJacobian.html index 51e01a2..c833e42 100644 --- a/doc/nucleus/functions/inversion/getFitFreeJacobian.html +++ b/doc/nucleus/functions/inversion/getFitFreeJacobian.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/getLambdaFromLCurve.html b/doc/nucleus/functions/inversion/getLambdaFromLCurve.html index ab43996..70dc25d 100644 --- a/doc/nucleus/functions/inversion/getLambdaFromLCurve.html +++ b/doc/nucleus/functions/inversion/getLambdaFromLCurve.html @@ -53,8 +53,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0027 % 0028 % See also: -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/getLambdaFromRMS.html b/doc/nucleus/functions/inversion/getLambdaFromRMS.html index dd0d526..88e1e48 100644 --- a/doc/nucleus/functions/inversion/getLambdaFromRMS.html +++ b/doc/nucleus/functions/inversion/getLambdaFromRMS.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/getStudentInvCDF.html b/doc/nucleus/functions/inversion/getStudentInvCDF.html index 8b336d8..dde9125 100644 --- a/doc/nucleus/functions/inversion/getStudentInvCDF.html +++ b/doc/nucleus/functions/inversion/getStudentInvCDF.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/getTLogMean.html b/doc/nucleus/functions/inversion/getTLogMean.html index 53c6a20..1c1783d 100644 --- a/doc/nucleus/functions/inversion/getTLogMean.html +++ b/doc/nucleus/functions/inversion/getTLogMean.html @@ -53,8 +53,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 </ul>
 This function is called by:
 <ul style= -
  • fitDataLSQ is a control routine that fits NMR data multi-exponentially;
  • fitDataLUdecomp is a control routine that uses a LU decomposition and the
  • +
  • fitDataLSQ is a control routine that fits NMR data multi-exponentially;
  • fitDataLUdecomp is a control routine that uses a LU decomposition and the
  • fitDataMultiModal is a control routine that uses either 'lsqnonlin' or
  • @@ -98,8 +98,8 @@

    SOURCE CODE ^% none 0027 % 0028 % See also: -0029 % Author: Thomas Hiller -0030 % email: thomas.hiller[at]leibniz-liag.de +0029 % Author: see AUTHORS.md +0030 % email: see AUTHORS.md 0031 % License: MIT License (at end) 0032 0033 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/inversion/menu.html b/doc/nucleus/functions/inversion/menu.html index 3d7aa17..da2396f 100644 --- a/doc/nucleus/functions/inversion/menu.html +++ b/doc/nucleus/functions/inversion/menu.html @@ -18,7 +18,7 @@

    Index for nucleus\functions\inversion

    Matlab files in this directory:

    +
  • applyGatesToSignal
  • applyRegularization
  • createKernelMatrix
  • estimateJacobian
  • estimateUncertainty
  • fcn_JointInvfixed
  • fcn_JointInvfree
  • fcn_JointInvshape
  • fcn_fitFreeT1
  • fcn_fitFreeT1_fmin
  • fcn_fitFreeT2
  • fcn_fitFreeT2_fmin
  • fcn_fitFreeT2w
  • fcn_fitMultiModal
  • fitDataFree
  • fitDataLSQ
  • fitDataLUdecomp
  • fitDataMultiModal
  • getChi2
  • getConfInterval
  • getFitErrors
  • getFitFreeJacobian
  • getLambdaFromLCurve
  • getLambdaFromRMS
  • getStudentInvCDF
  • getTLogMean
  • diff --git a/doc/nucleus/functions/modeling/addNoiseToSignal.html b/doc/nucleus/functions/modeling/addNoiseToSignal.html index 7ff6cea..533d50b 100644 --- a/doc/nucleus/functions/modeling/addNoiseToSignal.html +++ b/doc/nucleus/functions/modeling/addNoiseToSignal.html @@ -54,8 +54,8 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 </ul>
 This function is called by:
 <ul style= -
  • updateNMRsignals adds noise to the forward NMR signals and scales the
  • +
  • updateNMRsignals adds noise to the forward NMR signals and scales the
  • estimateUncertainty calculates pseudo uncertainty estimates for multi
  • @@ -100,8 +100,8 @@

    SOURCE CODE ^% none 0028 % 0029 % See also: -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/createPSD.html b/doc/nucleus/functions/modeling/createPSD.html index bb7227b..e31aea9 100644 --- a/doc/nucleus/functions/modeling/createPSD.html +++ b/doc/nucleus/functions/modeling/createPSD.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getAngularityFactor.html b/doc/nucleus/functions/modeling/getAngularityFactor.html index b3ab41a..d9fc04a 100644 --- a/doc/nucleus/functions/modeling/getAngularityFactor.html +++ b/doc/nucleus/functions/modeling/getAngularityFactor.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getAreaFactor.html b/doc/nucleus/functions/modeling/getAreaFactor.html index b42707b..02c67fd 100644 --- a/doc/nucleus/functions/modeling/getAreaFactor.html +++ b/doc/nucleus/functions/modeling/getAreaFactor.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% 0026 % See also: 0027 % Tuller & Or, 2001, WRR, Vol. 37(5), 1257-1276 -0028 % Author: Stepahn Costabel -0029 % email: stephan.costabel[at]bgr.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getConduct.html b/doc/nucleus/functions/modeling/getConduct.html index 2e4f5d1..03d82c7 100644 --- a/doc/nucleus/functions/modeling/getConduct.html +++ b/doc/nucleus/functions/modeling/getConduct.html @@ -59,8 +59,8 @@

    DESCRIPTION ^SOURCE CODE ^% See also: 0033 % Tuller & Or, 2001, WRR, Vol. 37(5), 1257-1276 0034 % Patzek & Silin, 2001, JColIntSci, Vol. 236(2), 295-304 -0035 % Author: Stepahn Costabel -0036 % email: stephan.costabel[at]bgr.de +0035 % Author: see AUTHORS.md +0036 % email: see AUTHORS.md 0037 % License: MIT License (at end) 0038 0039 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getConstants.html b/doc/nucleus/functions/modeling/getConstants.html index d7e2623..120e1e7 100644 --- a/doc/nucleus/functions/modeling/getConstants.html +++ b/doc/nucleus/functions/modeling/getConstants.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getCornerNMRparameter.html b/doc/nucleus/functions/modeling/getCornerNMRparameter.html index d441dc2..58e1c5e 100644 --- a/doc/nucleus/functions/modeling/getCornerNMRparameter.html +++ b/doc/nucleus/functions/modeling/getCornerNMRparameter.html @@ -59,8 +59,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0033 % 0034 % See also: -0035 % Author: Thomas Hiller -0036 % email: thomas.hiller[at]leibniz-liag.de +0035 % Author: see AUTHORS.md +0036 % email: see AUTHORS.md 0037 % License: MIT License (at end) 0038 0039 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getCornerSaturation.html b/doc/nucleus/functions/modeling/getCornerSaturation.html index 0141d60..8018ff8 100644 --- a/doc/nucleus/functions/modeling/getCornerSaturation.html +++ b/doc/nucleus/functions/modeling/getCornerSaturation.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getCriticalPressure.html b/doc/nucleus/functions/modeling/getCriticalPressure.html index feede2f..91fa56e 100644 --- a/doc/nucleus/functions/modeling/getCriticalPressure.html +++ b/doc/nucleus/functions/modeling/getCriticalPressure.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getGeometryParameter.html b/doc/nucleus/functions/modeling/getGeometryParameter.html index 067af3f..cca189d 100644 --- a/doc/nucleus/functions/modeling/getGeometryParameter.html +++ b/doc/nucleus/functions/modeling/getGeometryParameter.html @@ -65,8 +65,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0039 % 0040 % See also: -0041 % Author: Thomas Hiller -0042 % email: thomas.hiller[at]leibniz-liag.de +0041 % Author: see AUTHORS.md +0042 % email: see AUTHORS.md 0043 % License: MIT License (at end) 0044 0045 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getNMRSignal.html b/doc/nucleus/functions/modeling/getNMRSignal.html index 664b827..e3534ae 100644 --- a/doc/nucleus/functions/modeling/getNMRSignal.html +++ b/doc/nucleus/functions/modeling/getNMRSignal.html @@ -36,6 +36,7 @@

    DESCRIPTION ^DESCRIPTION ^SOURCE CODE ^% nmr - structure containing fields: 0010 % t : time vector [s] 0011 % Tb : bulk relaxation time [s] -0012 % rho : surface relaxivity [m/s] -0013 % type - either 'cyl', 'ang' and 'poly' -0014 % SatData - structure (output from 'getSaturationfromPressure') -0015 % psdData - structure containing fields: -0016 % psd : amplitudes of the distribution -0017 % r : sample points of the distribution -0018 % if psd = 1 and r is a scalar value then a single pore -0019 % is assumed -0020 % wbopts - show a wait-bar -0021 % -0022 % Outputs: -0023 % nmr - structure containing new fields: -0024 % EiT1 : T1 NMR signal for imbibition -0025 % EiT2 : T2 NMR signal for imbibition -0026 % EdT1 : T1 NMR signal for drainage -0027 % EdT2 : T2 NMR signal for drainage -0028 % with NMR signals for each available pressure / saturation step -0029 % -0030 % Example: -0031 % nmr = getNMRSignal(nmr,type,SatData,psdData,wbopts) -0032 % -0033 % Other m-files required: -0034 % none -0035 % -0036 % Subfunctions: -0037 % none -0038 % -0039 % MAT-files required: -0040 % none -0041 % -0042 % See also: -0043 % Author: Thomas Hiller -0044 % email: thomas.hiller[at]leibniz-liag.de -0045 % License: MIT License (at end) -0046 -0047 %------------- BEGIN CODE -------------- -0048 -0049 %% allocate the output NMR signals: -0050 % T1 and T2 for imbibition / drainage -0051 EiT1 = zeros(size(SatData.Sifull,1),numel(nmr.t)); -0052 EiT2 = zeros(size(SatData.Sifull,1),numel(nmr.t)); -0053 EdT1 = zeros(size(SatData.Sdfull,1),numel(nmr.t)); -0054 EdT2 = zeros(size(SatData.Sdfull,1),numel(nmr.t)); -0055 -0056 % get general parameters -0057 t = nmr.t; -0058 Tb = nmr.Tb; -0059 rho = nmr.rho; -0060 -0061 %% some informative wait-bar ;-) -0062 if wbopts.show -0063 hwb = waitbar(0,'processing ...','Name','Calculate NMR','Visible','off'); -0064 steps = numel(SatData.pressure); -0065 % position the wait-bar to the NMRMOD GUI if it is present (assuming the call came -0066 % from the GUI) -0067 fig = findobj('Tag',wbopts.tag); -0068 if ~isempty(fig) -0069 posf = get(fig,'Position'); -0070 set(hwb,'Units','Pixel') -0071 posw = get(hwb,'Position'); -0072 set(hwb,'Position',[posf(1)+posf(3)/2-posw(3)/2 posf(2)+posf(4)/2-posw(4)/2 posw(3:4)]); -0073 end -0074 set(hwb,'Visible','on'); -0075 end -0076 -0077 %% NMR signals depending on geometry type -0078 switch type -0079 case 'cyl' -0080 % surface to volume ratio (2/radius) -0081 SVi = SatData.Pai./SatData.Aai; -0082 SVd = SatData.Pad./SatData.Aad; -0083 SVi(isnan(SVi)) = 0; % get rid of NaNs -0084 SVd(isnan(SVd)) = 0; % get rid of NaNs -0085 -0086 % for all pressure steps -0087 for p = 1:numel(SatData.pressure) -0088 % for all time steps -0089 for j = 1:length(t) -0090 EiT1(p,j) = sum(SatData.Si(p,:) .* psdData.psd .* ... -0091 (1-exp(-t(j) .* (1./Tb+rho.*SVi(p,:)) ))); -0092 EiT2(p,j) = sum(SatData.Si(p,:) .* psdData.psd .* ... -0093 exp(-t(j) .* (1./Tb+rho.*SVi(p,:)) ) ); -0094 EdT1(p,j) = sum(SatData.Sd(p,:) .* psdData.psd .* ... -0095 (1-exp(-t(j) .* (1./Tb+rho.*SVd(p,:)) ))); -0096 EdT2(p,j) = sum(SatData.Sd(p,:) .* psdData.psd .* ... -0097 exp(-t(j) .* (1./Tb+rho.*SVd(p,:)) ) ); -0098 end -0099 if wbopts.show -0100 waitbar(p / steps,hwb,['processing ... ',num2str(p),' / ',... -0101 num2str(steps),' pressure steps']); -0102 end -0103 end -0104 -0105 % NMR signals for triangular and polygon capillaries -0106 case {'ang','poly'} -0107 % No of water-filled corners -0108 Ncorners = size(SatData.Aai,ndims(SatData.Aai)); -0109 -0110 % for all pressure steps -0111 for p = 1:numel(SatData.pressure) -0112 % area of water-filled corners is later used for NMR amplitude -0113 % calculation -0114 Aai = squeeze(SatData.Aai(p,:,:)); -0115 Aad = squeeze(SatData.Aad(p,:,:)); -0116 -0117 % surface to volume ratio (S/V) for imbibition / drainage -0118 SVi = squeeze(SatData.Pai(p,:,:)./SatData.Aai(p,:,:)); -0119 SVd = squeeze(SatData.Pad(p,:,:)./SatData.Aad(p,:,:)); -0120 -0121 % temporary NMR signals -0122 sigiT1 = zeros(size(SVi,1),numel(t)); -0123 sigiT2 = zeros(size(SVi,1),numel(t)); -0124 sigdT1 = zeros(size(SVd,1),numel(t)); -0125 sigdT2 = zeros(size(SVd,1),numel(t)); -0126 -0127 % for all pore sizes -0128 for j = 1:numel(psdData.r) -0129 % --- imbibition --- -0130 if SatData.isfullsati(p,j) == 1 % if fully saturated -> Ampl = 1 -0131 sigiT1(j,:) = (1-exp(-t .* (1./Tb + rho.*SVi(j,1)) )); -0132 sigiT2(j,:) = exp(-t .* (1./Tb + rho.*SVi(j,1)) ); -0133 else -0134 % partially saturated pore -> account for corners -0135 for jj = 1:Ncorners -0136 Ampl = Aai(j,jj) / SatData.A0(j); -0137 sigiT1(j,:) = sigiT1(j,:) + (Ampl * (1-exp(-t .* ... -0138 (1./Tb + rho.*SVi(j,jj)))) ); -0139 sigiT2(j,:) = sigiT2(j,:) + (Ampl * exp(-t .* ... -0140 (1./Tb + rho.*SVi(j,jj))) ); -0141 end -0142 end -0143 -0144 % --- drainage --- -0145 if SatData.isfullsatd(p,j) == 1 % if fully saturated -> Ampl = 1 -0146 sigdT1(j,:) = (1-exp(-t .* (1./Tb + rho.*SVd(j,1)) )); -0147 sigdT2(j,:) = exp(-t .* (1./Tb + rho.*SVd(j,1)) ); -0148 else -0149 % partially saturated pore -> account for corners -0150 for jj = 1:Ncorners -0151 Ampl = Aad(j,jj) / SatData.A0(j); -0152 sigdT1(j,:) = sigdT1(j,:) + (Ampl * (1-exp(-t .* ... -0153 (1./Tb + rho.*SVd(j,jj)))) ); -0154 sigdT2(j,:) = sigdT2(j,:) + (Ampl * exp(-t .* ... -0155 (1./Tb + rho.*SVd(j,jj))) ); -0156 end -0157 end -0158 -0159 % account for pore size distribution -0160 sigiT1(j,:) = sigiT1(j,:) * psdData.psd(j); -0161 sigiT2(j,:) = sigiT2(j,:) * psdData.psd(j); -0162 sigdT1(j,:) = sigdT1(j,:) * psdData.psd(j); -0163 sigdT2(j,:) = sigdT2(j,:) * psdData.psd(j); -0164 end -0165 -0166 % sum up all pores into one NMR signal for the current pressure / -0167 % saturation step -0168 if numel(psdData.psd) > 1 -0169 EiT1(p,:) = sum(sigiT1); -0170 EiT2(p,:) = sum(sigiT2); -0171 EdT1(p,:) = sum(sigdT1); -0172 EdT2(p,:) = sum(sigdT2); -0173 else -0174 % single pore case -0175 EiT1(p,:) = sigiT1; -0176 EiT2(p,:) = sigiT2; -0177 EdT1(p,:) = sigdT1; -0178 EdT2(p,:) = sigdT2; -0179 end -0180 -0181 % update wait-bar -0182 if wbopts.show -0183 waitbar(p / steps,hwb,['processing ... ',num2str(p),' / ',num2str(steps),' pressure steps']); -0184 end -0185 end -0186 end -0187 %% delete wait-bar -0188 if wbopts.show -0189 delete(hwb); -0190 end -0191 -0192 %% output data -0193 nmr.EiT1 = EiT1; -0194 nmr.EiT2 = EiT2; -0195 nmr.EdT1 = EdT1; -0196 nmr.EdT2 = EdT2; -0197 -0198 return +0012 % Td : diffusion relaxation time [s] +0013 % rho : surface relaxivity [m/s] +0014 % type - either 'cyl', 'ang' and 'poly' +0015 % SatData - structure (output from 'getSaturationfromPressure') +0016 % psdData - structure containing fields: +0017 % psd : amplitudes of the distribution +0018 % r : sample points of the distribution +0019 % if psd = 1 and r is a scalar value then a single pore +0020 % is assumed +0021 % wbopts - show a wait-bar +0022 % +0023 % Outputs: +0024 % nmr - structure containing new fields: +0025 % EiT1 : T1 NMR signal for imbibition +0026 % EiT2 : T2 NMR signal for imbibition +0027 % EdT1 : T1 NMR signal for drainage +0028 % EdT2 : T2 NMR signal for drainage +0029 % with NMR signals for each available pressure / saturation step +0030 % +0031 % Example: +0032 % nmr = getNMRSignal(nmr,type,SatData,psdData,wbopts) +0033 % +0034 % Other m-files required: +0035 % none +0036 % +0037 % Subfunctions: +0038 % none +0039 % +0040 % MAT-files required: +0041 % none +0042 % +0043 % See also: +0044 % Author: see AUTHORS.md +0045 % email: see AUTHORS.md +0046 % License: MIT License (at end) +0047 +0048 %------------- BEGIN CODE -------------- +0049 +0050 %% allocate the output NMR signals: +0051 % T1 and T2 for imbibition / drainage +0052 EiT1 = zeros(size(SatData.Sifull,1),numel(nmr.t)); +0053 EiT2 = zeros(size(SatData.Sifull,1),numel(nmr.t)); +0054 EdT1 = zeros(size(SatData.Sdfull,1),numel(nmr.t)); +0055 EdT2 = zeros(size(SatData.Sdfull,1),numel(nmr.t)); +0056 +0057 % get general parameters +0058 t = nmr.t; +0059 Tb = nmr.Tb; +0060 Td = nmr.Td; +0061 rho = nmr.rho; +0062 +0063 %% some informative wait-bar ;-) +0064 if wbopts.show +0065 hwb = waitbar(0,'processing ...','Name','Calculate NMR','Visible','off'); +0066 steps = numel(SatData.pressure); +0067 % position the wait-bar to the NMRMOD GUI if it is present (assuming the call came +0068 % from the GUI) +0069 fig = findobj('Tag',wbopts.tag); +0070 if ~isempty(fig) +0071 posf = get(fig,'Position'); +0072 set(hwb,'Units','Pixel') +0073 posw = get(hwb,'Position'); +0074 set(hwb,'Position',[posf(1)+posf(3)/2-posw(3)/2 posf(2)+posf(4)/2-posw(4)/2 posw(3:4)]); +0075 end +0076 set(hwb,'Visible','on'); +0077 end +0078 +0079 %% NMR signals depending on geometry type +0080 switch type +0081 case 'cyl' +0082 % surface to volume ratio (2/radius) +0083 SVi = SatData.Pai./SatData.Aai; +0084 SVd = SatData.Pad./SatData.Aad; +0085 SVi(isnan(SVi)) = 0; % get rid of NaNs +0086 SVd(isnan(SVd)) = 0; % get rid of NaNs +0087 +0088 % for all pressure steps +0089 for p = 1:numel(SatData.pressure) +0090 % for all time steps +0091 for j = 1:length(t) +0092 EiT1(p,j) = sum(SatData.Si(p,:) .* psdData.psd .* ... +0093 (1-exp(-t(j) .* (1./Td+1./Tb+rho.*SVi(p,:)) ))); +0094 EiT2(p,j) = sum(SatData.Si(p,:) .* psdData.psd .* ... +0095 exp(-t(j) .* (1./Td+1./Tb+rho.*SVi(p,:)) ) ); +0096 EdT1(p,j) = sum(SatData.Sd(p,:) .* psdData.psd .* ... +0097 (1-exp(-t(j) .* (1./Td+1./Tb+rho.*SVd(p,:)) ))); +0098 EdT2(p,j) = sum(SatData.Sd(p,:) .* psdData.psd .* ... +0099 exp(-t(j) .* (1./Td+1./Tb+rho.*SVd(p,:)) ) ); +0100 end +0101 if wbopts.show +0102 waitbar(p / steps,hwb,['processing ... ',num2str(p),' / ',... +0103 num2str(steps),' pressure steps']); +0104 end +0105 end +0106 +0107 % NMR signals for triangular and polygon capillaries +0108 case {'ang','poly'} +0109 % No of water-filled corners +0110 Ncorners = size(SatData.Aai,ndims(SatData.Aai)); +0111 +0112 % for all pressure steps +0113 for p = 1:numel(SatData.pressure) +0114 % area of water-filled corners is later used for NMR amplitude +0115 % calculation +0116 Aai = squeeze(SatData.Aai(p,:,:)); +0117 Aad = squeeze(SatData.Aad(p,:,:)); +0118 +0119 % surface to volume ratio (S/V) for imbibition / drainage +0120 SVi = squeeze(SatData.Pai(p,:,:)./SatData.Aai(p,:,:)); +0121 SVd = squeeze(SatData.Pad(p,:,:)./SatData.Aad(p,:,:)); +0122 +0123 % temporary NMR signals +0124 sigiT1 = zeros(size(SVi,1),numel(t)); +0125 sigiT2 = zeros(size(SVi,1),numel(t)); +0126 sigdT1 = zeros(size(SVd,1),numel(t)); +0127 sigdT2 = zeros(size(SVd,1),numel(t)); +0128 +0129 % for all pore sizes +0130 for j = 1:numel(psdData.r) +0131 % --- imbibition --- +0132 if SatData.isfullsati(p,j) == 1 % if fully saturated -> Ampl = 1 +0133 sigiT1(j,:) = (1-exp(-t .* (1./Td + 1./Tb + rho.*SVi(j,1)) )); +0134 sigiT2(j,:) = exp(-t .* (1./Td + 1./Tb + rho.*SVi(j,1)) ); +0135 else +0136 % partially saturated pore -> account for corners +0137 for jj = 1:Ncorners +0138 Ampl = Aai(j,jj) / SatData.A0(j); +0139 sigiT1(j,:) = sigiT1(j,:) + (Ampl * (1-exp(-t .* ... +0140 (1./Td + 1./Tb + rho.*SVi(j,jj)))) ); +0141 sigiT2(j,:) = sigiT2(j,:) + (Ampl * exp(-t .* ... +0142 (1./Td + 1./Tb + rho.*SVi(j,jj))) ); +0143 end +0144 end +0145 +0146 % --- drainage --- +0147 if SatData.isfullsatd(p,j) == 1 % if fully saturated -> Ampl = 1 +0148 sigdT1(j,:) = (1-exp(-t .* (1./Td + 1./Tb + rho.*SVd(j,1)) )); +0149 sigdT2(j,:) = exp(-t .* (1./Td + 1./Tb + rho.*SVd(j,1)) ); +0150 else +0151 % partially saturated pore -> account for corners +0152 for jj = 1:Ncorners +0153 Ampl = Aad(j,jj) / SatData.A0(j); +0154 sigdT1(j,:) = sigdT1(j,:) + (Ampl * (1-exp(-t .* ... +0155 (1./Td + 1./Tb + rho.*SVd(j,jj)))) ); +0156 sigdT2(j,:) = sigdT2(j,:) + (Ampl * exp(-t .* ... +0157 (1./Td + 1./Tb + rho.*SVd(j,jj))) ); +0158 end +0159 end +0160 +0161 % account for pore size distribution +0162 sigiT1(j,:) = sigiT1(j,:) * psdData.psd(j); +0163 sigiT2(j,:) = sigiT2(j,:) * psdData.psd(j); +0164 sigdT1(j,:) = sigdT1(j,:) * psdData.psd(j); +0165 sigdT2(j,:) = sigdT2(j,:) * psdData.psd(j); +0166 end +0167 +0168 % sum up all pores into one NMR signal for the current pressure / +0169 % saturation step +0170 if numel(psdData.psd) > 1 +0171 EiT1(p,:) = sum(sigiT1); +0172 EiT2(p,:) = sum(sigiT2); +0173 EdT1(p,:) = sum(sigdT1); +0174 EdT2(p,:) = sum(sigdT2); +0175 else +0176 % single pore case +0177 EiT1(p,:) = sigiT1; +0178 EiT2(p,:) = sigiT2; +0179 EdT1(p,:) = sigdT1; +0180 EdT2(p,:) = sigdT2; +0181 end +0182 +0183 % update wait-bar +0184 if wbopts.show +0185 waitbar(p / steps,hwb,['processing ... ',num2str(p),' / ',num2str(steps),' pressure steps']); +0186 end +0187 end +0188 end +0189 %% delete wait-bar +0190 if wbopts.show +0191 delete(hwb); +0192 end +0193 +0194 %% output data +0195 nmr.EiT1 = EiT1; +0196 nmr.EiT2 = EiT2; +0197 nmr.EdT1 = EdT1; +0198 nmr.EdT2 = EdT2; 0199 -0200 %------------- END OF CODE -------------- +0200 return 0201 -0202 %% License: -0203 % MIT License -0204 % -0205 % Copyright (c) 2018 Thomas Hiller +0202 %------------- END OF CODE -------------- +0203 +0204 %% License: +0205 % MIT License 0206 % -0207 % Permission is hereby granted, free of charge, to any person obtaining a copy -0208 % of this software and associated documentation files (the "Software"), to deal -0209 % in the Software without restriction, including without limitation the rights -0210 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -0211 % copies of the Software, and to permit persons to whom the Software is -0212 % furnished to do so, subject to the following conditions: -0213 % -0214 % The above copyright notice and this permission notice shall be included in all -0215 % copies or substantial portions of the Software. -0216 % -0217 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -0218 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -0219 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -0220 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -0221 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -0222 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -0223 % SOFTWARE. +0207 % Copyright (c) 2018 Thomas Hiller +0208 % +0209 % Permission is hereby granted, free of charge, to any person obtaining a copy +0210 % of this software and associated documentation files (the "Software"), to deal +0211 % in the Software without restriction, including without limitation the rights +0212 % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +0213 % copies of the Software, and to permit persons to whom the Software is +0214 % furnished to do so, subject to the following conditions: +0215 % +0216 % The above copyright notice and this permission notice shall be included in all +0217 % copies or substantial portions of the Software. +0218 % +0219 % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +0220 % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +0221 % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +0222 % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +0223 % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +0224 % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +0225 % SOFTWARE.
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/nucleus/functions/modeling/getNMRTimeVector.html b/doc/nucleus/functions/modeling/getNMRTimeVector.html index 0527457..255ca08 100644 --- a/doc/nucleus/functions/modeling/getNMRTimeVector.html +++ b/doc/nucleus/functions/modeling/getNMRTimeVector.html @@ -62,8 +62,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0036 % 0037 % See also: -0038 % Author: Thomas Hiller -0039 % email: thomas.hiller[at]leibniz-liag.de +0038 % Author: see AUTHORS.md +0039 % email: see AUTHORS.md 0040 % License: MIT License (at end) 0041 0042 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getPartialSaturationMatrix.html b/doc/nucleus/functions/modeling/getPartialSaturationMatrix.html index 24c8ce9..e04ff99 100644 --- a/doc/nucleus/functions/modeling/getPartialSaturationMatrix.html +++ b/doc/nucleus/functions/modeling/getPartialSaturationMatrix.html @@ -55,8 +55,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0029 % 0030 % See also: -0031 % Author: Thomas Hiller -0032 % email: thomas.hiller[at]leibniz-liag.de +0031 % Author: see AUTHORS.md +0032 % email: see AUTHORS.md 0033 % License: MIT License (at end) 0034 0035 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getPointCoordinates.html b/doc/nucleus/functions/modeling/getPointCoordinates.html index cd91c0e..e40a897 100644 --- a/doc/nucleus/functions/modeling/getPointCoordinates.html +++ b/doc/nucleus/functions/modeling/getPointCoordinates.html @@ -52,8 +52,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0026 % 0027 % See also: -0028 % Author: Thomas Hiller -0029 % email: thomas.hiller[at]leibniz-liag.de +0028 % Author: see AUTHORS.md +0029 % email: see AUTHORS.md 0030 % License: MIT License (at end) 0031 0032 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getPressureRangeFromPSD.html b/doc/nucleus/functions/modeling/getPressureRangeFromPSD.html index 34903f4..b6ad04a 100644 --- a/doc/nucleus/functions/modeling/getPressureRangeFromPSD.html +++ b/doc/nucleus/functions/modeling/getPressureRangeFromPSD.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0028 % 0029 % See also: -0030 % Author: Thomas Hiller -0031 % email: thomas.hiller[at]leibniz-liag.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getRaRaEps.html b/doc/nucleus/functions/modeling/getRaRaEps.html index 5039df6..0ab2403 100644 --- a/doc/nucleus/functions/modeling/getRaRaEps.html +++ b/doc/nucleus/functions/modeling/getRaRaEps.html @@ -54,8 +54,8 @@

    DESCRIPTION ^SOURCE CODE ^% 0028 % See also: 0029 % Ransohoff & Radke, 1988, JColIntSci, Vol. 121(2), 392-401 -0030 % Author: Stepahn Costabel -0031 % email: stephan.costabel[at]bgr.de +0030 % Author: see AUTHORS.md +0031 % email: see AUTHORS.md 0032 % License: MIT License (at end) 0033 0034 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getSaturationFromPressure.html b/doc/nucleus/functions/modeling/getSaturationFromPressure.html index 917d06b..64c37af 100644 --- a/doc/nucleus/functions/modeling/getSaturationFromPressure.html +++ b/doc/nucleus/functions/modeling/getSaturationFromPressure.html @@ -65,8 +65,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0039 % 0040 % See also: -0041 % Author: Thomas Hiller, Stephan Costabel -0042 % email: thomas.hiller[at]leibniz-liag.de +0041 % Author: see AUTHORS.md +0042 % email: see AUTHORS.md 0043 % License: MIT License (at end) 0044 0045 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getSaturationFromPressureBatch.html b/doc/nucleus/functions/modeling/getSaturationFromPressureBatch.html index 687204a..1678648 100644 --- a/doc/nucleus/functions/modeling/getSaturationFromPressureBatch.html +++ b/doc/nucleus/functions/modeling/getSaturationFromPressureBatch.html @@ -73,8 +73,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0047 % 0048 % See also: -0049 % Author: Thomas Hiller, Stephan Costabel -0050 % email: thomas.hiller[at]leibniz-liag.de +0049 % Author: see AUTHORS.md +0050 % email: see AUTHORS.md 0051 % License: MIT License (at end) 0052 0053 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getSaturationLevelData.html b/doc/nucleus/functions/modeling/getSaturationLevelData.html index 2736c54..4fac7c2 100644 --- a/doc/nucleus/functions/modeling/getSaturationLevelData.html +++ b/doc/nucleus/functions/modeling/getSaturationLevelData.html @@ -56,8 +56,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0030 % 0031 % See also: -0032 % Author: Thomas Hiller -0033 % email: thomas.hiller[at]leibniz-liag.de +0032 % Author: see AUTHORS.md +0033 % email: see AUTHORS.md 0034 % License: MIT License (at end) 0035 0036 %------------- BEGIN CODE -------------- diff --git a/doc/nucleus/functions/modeling/getShapeFactor.html b/doc/nucleus/functions/modeling/getShapeFactor.html index 8e7323b..c9b4e31 100644 --- a/doc/nucleus/functions/modeling/getShapeFactor.html +++ b/doc/nucleus/functions/modeling/getShapeFactor.html @@ -51,8 +51,8 @@

    DESCRIPTION ^SOURCE CODE ^% none 0025 % 0026 % See also: -0027 % Author: Thomas Hiller -0028 % email: thomas.hiller[at]leibniz-liag.de +0027 % Author: see AUTHORS.md +0028 % email: see AUTHORS.md 0029 % License: MIT License (at end) 0030 0031 %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_bamtom.m b/functions/import/LoadNMRData_bamtom.m index f1d396a..b375602 100644 --- a/functions/import/LoadNMRData_bamtom.m +++ b/functions/import/LoadNMRData_bamtom.m @@ -29,8 +29,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_bgr.m b/functions/import/LoadNMRData_bgr.m index 1855978..108a728 100644 --- a/functions/import/LoadNMRData_bgr.m +++ b/functions/import/LoadNMRData_bgr.m @@ -29,8 +29,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_bgrmat.m b/functions/import/LoadNMRData_bgrmat.m index b72e248..ecc85f9 100644 --- a/functions/import/LoadNMRData_bgrmat.m +++ b/functions/import/LoadNMRData_bgrmat.m @@ -29,8 +29,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_corelab.m b/functions/import/LoadNMRData_corelab.m index 9041219..d4a333a 100644 --- a/functions/import/LoadNMRData_corelab.m +++ b/functions/import/LoadNMRData_corelab.m @@ -29,8 +29,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_dart.m b/functions/import/LoadNMRData_dart.m index 1d0b305..bbf6c97 100644 --- a/functions/import/LoadNMRData_dart.m +++ b/functions/import/LoadNMRData_dart.m @@ -31,8 +31,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_driver.m b/functions/import/LoadNMRData_driver.m index b1f4a69..6faab9f 100644 --- a/functions/import/LoadNMRData_driver.m +++ b/functions/import/LoadNMRData_driver.m @@ -27,8 +27,9 @@ % LoadNMRData_mouse % LoadNMRData_liag % LoadNMRData_bgr -% LoadNMRData_bgr2 +% LoadNMRData_mousecpmg % LoadNMRData_bgrmat +% LoadNMRData_helios % LoadNMRData_bamtom % % Subfunctions: @@ -38,8 +39,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -50,10 +51,14 @@ out = LoadNMRData_bamtom(in); case 'bgr' out = LoadNMRData_bgr(in); - case 'bgr2' - out = LoadNMRData_bgr2(in); + case 'MouseCPMG' + out = LoadNMRData_mousecpmg(in); case 'bgrmat' out = LoadNMRData_bgrmat(in); + case {'MouseLiftSingle','MouseLiftAll'} + out = LoadNMRData_mouselift(in); + case 'helios' + out = LoadNMRData_helios(in); case 'corelab' out = LoadNMRData_corelab(in); case 'dart' @@ -75,16 +80,18 @@ % if an imported T2 signal has no imaginary part, the noise is estimated % from an exponential fit -for i = 1:numel(out.nmrData) - if strcmp(out.nmrData{i}.flag,'T2') && isreal(out.nmrData{i}.signal) - disp('NUCLUESinv import: Estimating noise from exponential fit ...'); - param.T1IRfac = out.nmrData{i}.T1IRfac; - param.noise = 0; - param.optim = 'off'; - invstd = fitDataFree(out.nmrData{i}.time,out.nmrData{i}.signal,... - 'T2',param,5); - out.nmrData{i}.noise = invstd.rms; - disp('NUCLUESinv import: done.') +if ~strcmp(in.fileformat,'helios') + for i = 1:numel(out.nmrData) + if isreal(out.nmrData{i}.signal) + disp('NUCLUESinv import: Estimating noise from exponential fit ...'); + param.T1IRfac = out.nmrData{i}.T1IRfac; + param.noise = 0; + param.optim = 'off'; + invstd = fitDataFree(out.nmrData{i}.time,out.nmrData{i}.signal,... + out.nmrData{i}.flag,param,5); + out.nmrData{i}.noise = invstd.rms; + disp('NUCLUESinv import: done.') + end end end diff --git a/functions/import/LoadNMRData_field.m b/functions/import/LoadNMRData_field.m index e8da616..b11e8cc 100644 --- a/functions/import/LoadNMRData_field.m +++ b/functions/import/LoadNMRData_field.m @@ -30,8 +30,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_helios.m b/functions/import/LoadNMRData_helios.m new file mode 100644 index 0000000..96bb02c --- /dev/null +++ b/functions/import/LoadNMRData_helios.m @@ -0,0 +1,115 @@ +function out = LoadNMRData_helios(in) +%LoadNMRData_helios loads BGR NMR data from a typical folder structure +%produced by the Helios NMR Scanner +% +% Syntax: +% out = LoadNMRData_helios(in) +% +% Inputs: +% in - input structure +% in.path - data path +% in.T1T2 - T1 / T2 flag +% in.fileformat - 'helios' +% +% Outputs: +% out - output structure +% out.parData - parameter file data +% out.nmrData - NMR data +% +% Example: +% out = LoadNMRData_helios(in) +% +% Other m-files required: +% fixParameterString +% +% Subfunctions: +% LoadDataFile +% +% MAT-files required: +% none +% +% See also: NUCLEUSinv +% Author: see AUTHORS.md +% email: see AUTHORS.md +% License: MIT License (at end) + +%------------- BEGIN CODE -------------- + +%% start processing the files + +% read the data file +datafile = dir(fullfile(in.path,in.name)); +[data,parData] = LoadDataFile(in.path,in.name,in.T1T2); + +% get file statistics +nmrData.datfile = datafile.name; +nmrData.date = datafile.date; +nmrData.datenum = datafile.datenum; +nmrData.bytes = datafile.bytes; + +% save the NMR data +nmrData.flag = data.flag; +nmrData.T1IRfac = 1; +nmrData.time = data.time; +nmrData.signal = data.signal; +nmrData.raw = data.raw; +if strcmp(in.T1T2,'T2') + nmrData.phase = data.phase; +end + +% save data to output struct +out.parData = parData; +out.nmrData = nmrData; + +end + +%% load NMR data file +function [data,pardata] = LoadDataFile(datapath,fname,flag) + +A = importdata(fullfile(datapath,fname),'\t'); +t_echo = A(1,2); +n_echo = A(1,3); + +time = t_echo:t_echo:t_echo*n_echo; +time = time(:); +re = -A(2,1:length(time)); +im = -A(3,1:length(time)); +re = re(:); +im = im(:); + +data.flag = flag; +data.time = time; +data.signal = complex(re,im); +[data.signal,data.phase] = rotateT2phase(data.signal); + +data.raw.time = data.time; +data.raw.signal = data.signal; + +pardata.t_echo = t_echo; +pardata.n_echo = n_echo; + +end +%------------- END OF CODE -------------- + +%% License: +% MIT License +% +% Copyright (c) 2021 Stephan Costabel +% +% Permission is hereby granted, free of charge, to any person obtaining a copy +% of this software and associated documentation files (the "Software"), to deal +% in the Software without restriction, including without limitation the rights +% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the Software is +% furnished to do so, subject to the following conditions: +% +% The above copyright notice and this permission notice shall be included in all +% copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +% SOFTWARE. diff --git a/functions/import/LoadNMRData_ibac.m b/functions/import/LoadNMRData_ibac.m index e94bb08..2e6bfb8 100644 --- a/functions/import/LoadNMRData_ibac.m +++ b/functions/import/LoadNMRData_ibac.m @@ -32,8 +32,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_liag.m b/functions/import/LoadNMRData_liag.m index 9465fe5..bfb981f 100644 --- a/functions/import/LoadNMRData_liag.m +++ b/functions/import/LoadNMRData_liag.m @@ -28,8 +28,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/LoadNMRData_mouse.m b/functions/import/LoadNMRData_mouse.m index 0ea04e4..22ff06c 100644 --- a/functions/import/LoadNMRData_mouse.m +++ b/functions/import/LoadNMRData_mouse.m @@ -28,8 +28,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -134,7 +134,7 @@ %% License: % MIT License % -% Copyright (c) 2018 Thomas Hiller +% Copyright (c) 2021 Stephan Costabel % % Permission is hereby granted, free of charge, to any person obtaining a copy % of this software and associated documentation files (the "Software"), to deal diff --git a/functions/import/LoadNMRData_mouselift.m b/functions/import/LoadNMRData_mouselift.m new file mode 100644 index 0000000..b7e12fd --- /dev/null +++ b/functions/import/LoadNMRData_mouselift.m @@ -0,0 +1,151 @@ +function out = LoadNMRData_mouselift(in) +%LoadNMRData_mouselift loads NMR Mouse data from an original folder structure as +%generated by the NMR MOUSE when using it wogether with the lift +% +% Syntax: +% out = LoadNMRData_mouselift(in) +% +% Inputs: +% in - input structure +% in.path - data path +% in.T1T2 - T1 / T2 flag +% in.fileformat - 'mouse' +% +% Outputs: +% out - output structure +% out.parData - parameter file data +% out.nmrData - NMR data +% +% Example: +% out = LoadNMRData_mouselift(in) +% +% Other m-files required: +% fixParameterString +% +% Subfunctions: +% LoadDataFile +% LoadParameterFile +% +% MAT-files required: +% none +% +% See also: NUCLEUSinv +% Author: see AUTHORS.md +% email: see AUTHORS.md +% License: MIT License (at end) + +%------------- BEGIN CODE -------------- + +%% start processing the files +% load Parameter file +[parData] = LoadParameterFile(in.path,'acq.par'); + +% find all data files +files = dir(fullfile(in.path,'*.dat')); + +% remove not needed dat-files +switch in.T1T2 + case 'T1' + files = files(~ismember({files.name},... + {'data2D.dat','T1Axis.dat'})); + case 'T2' + files = files(~ismember({files.name},... + {'data2D.dat','T2Axis.dat'})); +end + +nmrData = cell(1,size(files,1)); +for i = 1:size(files,1) + % read the data file + data = LoadDataFile(in.path,files(i).name,in.T1T2); + + % get file statistics + nmrData{i}.datfile = files(i).name; + nmrData{i}.date = files(i).date; + nmrData{i}.datenum = files(i).datenum; + nmrData{i}.bytes = files(i).bytes; + + % save the NMR data + nmrData{i}.flag = data.flag; + nmrData{i}.T1IRfac = 1; + nmrData{i}.time = data.time; + nmrData{i}.signal = data.signal; + nmrData{i}.raw = data.raw; + if strcmp(in.T1T2,'T2') + nmrData{i}.phase = data.phase; + end + clear data +end + +% save data to output struct +out.parData = parData; +out.nmrData = nmrData; + +end + +%% load NMR data file +function [data] = LoadDataFile(datapath,fname,flag) + +d = load(fullfile(datapath,fname)); + +if size(d,2) == 3 + data.flag = flag; + data.time = d(:,1); + switch flag + case 'T1' + data.signal = d(:,2); + case 'T2' + data.signal = complex(d(:,2),d(:,3)); + [data.signal,data.phase] = rotateT2phase(data.signal); + end +else + data.flag = '0'; + data.time = 0; + data.signal = 0; + data.phase = 0; +end + +data.raw.time = data.time; +data.raw.signal = data.signal; + +end + +%% load parameter file +function [data] = LoadParameterFile(datapath,fname) + +fid = fopen(fullfile(datapath,fname)); +d = textscan(fid,'%s','Delimiter','\n'); +fclose(fid); + +for i = 1:size(d{1},1) + str = char(d{1}(i)); + str = fixParameterString(str); + eval(['data.',str,';']); +end +data.all = d; + +end + +%------------- END OF CODE -------------- + +%% License: +% MIT License +% +% Copyright (c) 2021 Stephan Costabel +% +% Permission is hereby granted, free of charge, to any person obtaining a copy +% of this software and associated documentation files (the "Software"), to deal +% in the Software without restriction, including without limitation the rights +% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the Software is +% furnished to do so, subject to the following conditions: +% +% The above copyright notice and this permission notice shall be included in all +% copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +% SOFTWARE. diff --git a/functions/import/LoadNMRData_rwth.m b/functions/import/LoadNMRData_rwth.m index 2450979..31f182f 100644 --- a/functions/import/LoadNMRData_rwth.m +++ b/functions/import/LoadNMRData_rwth.m @@ -30,8 +30,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/fixParameterString.m b/functions/import/fixParameterString.m index d463800..05b4a07 100644 --- a/functions/import/fixParameterString.m +++ b/functions/import/fixParameterString.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/import/rotateT2phase.m b/functions/import/rotateT2phase.m index 49b3a04..b88a0e5 100644 --- a/functions/import/rotateT2phase.m +++ b/functions/import/rotateT2phase.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/ConductView.m b/functions/interface/ConductView.m index 1767c02..372e6b5 100644 --- a/functions/interface/ConductView.m +++ b/functions/interface/ConductView.m @@ -27,8 +27,8 @@ function ConductView(src,~) % none % % See also: NUCLEUSmod, NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/PhaseView.m b/functions/interface/PhaseView.m index 371d116..e12c1c3 100644 --- a/functions/interface/PhaseView.m +++ b/functions/interface/PhaseView.m @@ -28,8 +28,8 @@ function PhaseView(src,~) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/beautifyAxes.m b/functions/interface/beautifyAxes.m index b3a3b73..815f0b0 100644 --- a/functions/interface/beautifyAxes.m +++ b/functions/interface/beautifyAxes.m @@ -23,8 +23,8 @@ function beautifyAxes(figh) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/calculateGeometry.m b/functions/interface/calculateGeometry.m index a9e72be..e854dd9 100644 --- a/functions/interface/calculateGeometry.m +++ b/functions/interface/calculateGeometry.m @@ -29,8 +29,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/calculateGuiOnMonitorPosition.m b/functions/interface/calculateGuiOnMonitorPosition.m index 3fc49d9..d8a6cd1 100644 --- a/functions/interface/calculateGuiOnMonitorPosition.m +++ b/functions/interface/calculateGuiOnMonitorPosition.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -33,6 +33,7 @@ %% get the monitor layout scr = get(0,'MonitorPosition'); if size(scr,1) > 1 + % find main screen ind = find(scr(:,1)==1 & scr(:,2)==1); sw = scr(ind,3); % width sh = scr(ind,4); % height @@ -41,31 +42,16 @@ sh = scr(4); % height end -%% positioning of the GUI -if numel(scr) > 4 - % dual screen mode - % GUI on second screen - gh = 730; % reference height - gw = ceil(gh*aspect_ratio); % reference width (1152) - if any(scr(:,1)<0) - pos = [-sw+(sw-gw)/2 (sh-gh)/3 gw gh]; - else - pos = [sw+(sw-gw)/2 (sh-gh)/3 gw gh]; - end - % if any screen is smaller than 800 - if any(scr(:,4)<800) - pos = [(sw-gw)/2 (sh-gh)/3 gw gh]; - end +%% GUI positioning +if any(sh<800) + gh = 600; % reference height for small screens else - % single screen mode - if any(scr(:,4)<800) - gh = 600; % reference height for small screens - else - gh = 730; % reference height - end - gw = ceil(gh*aspect_ratio); % reference width (960) - pos = [(sw-gw)/2 (sh-gh)/2 gw gh]; + gh = 730; % reference height end +% reference width +gw = ceil(gh*aspect_ratio); % 960 or 1152 +% GUI position +pos = round([(sw-gw)/2 (sh-gh)/3 gw gh]); return diff --git a/functions/interface/calculateNMR.m b/functions/interface/calculateNMR.m index b139c58..b93af8c 100644 --- a/functions/interface/calculateNMR.m +++ b/functions/interface/calculateNMR.m @@ -28,8 +28,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -45,6 +45,7 @@ % generate a time vector from the echo time 'TE' and number of echoes 'echosN' nmr.t = getNMRTimeVector(data.nmr.TE,'µs','N',data.nmr.echosN); nmr.Tb = data.nmr.Tbulk; + nmr.Td = data.nmr.Tdiff; nmr.rho = data.nmr.rho/1e6; % µm/s to m/s % wait-bar option diff --git a/functions/interface/calibratePorosity.m b/functions/interface/calibratePorosity.m index 8bd66f6..4f4dfdb 100644 --- a/functions/interface/calibratePorosity.m +++ b/functions/interface/calibratePorosity.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/caluclatePressureSaturation.m b/functions/interface/caluclatePressureSaturation.m index 69f7ec0..cd05dce 100644 --- a/functions/interface/caluclatePressureSaturation.m +++ b/functions/interface/caluclatePressureSaturation.m @@ -29,8 +29,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -87,8 +87,11 @@ %% reset NMR plots clearSingleAxis(gui.axes_handles.nmr); displayStatusText(gui,'Calculating saturation ... done'); -% enable the RUN button again +% enable the pressure RUN button again set(gui.push_handles.press_RUN,'String','RUN','Enable','on'); +% reset the NMR RUN button +set(gui.push_handles.nmr_RUN,'String','RUN','Enable','on',... + 'BackgroundColor','g','Callback',@onPushRun); % enable hydraulic conductivity GUI menu only for PSD data if data.geometry.ispsd set(gui.menu.view_conduct,'Enable','on'); diff --git a/functions/interface/changeColorTheme.m b/functions/interface/changeColorTheme.m index 1661a55..01dd0e8 100644 --- a/functions/interface/changeColorTheme.m +++ b/functions/interface/changeColorTheme.m @@ -31,8 +31,8 @@ function changeColorTheme(fig_tag,th) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/checkIfInversionExists.m b/functions/interface/checkIfInversionExists.m index 9565f3e..043dccc 100644 --- a/functions/interface/checkIfInversionExists.m +++ b/functions/interface/checkIfInversionExists.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/cleanupGUIData.m b/functions/interface/cleanupGUIData.m index dc6ae58..6d17cf7 100644 --- a/functions/interface/cleanupGUIData.m +++ b/functions/interface/cleanupGUIData.m @@ -28,8 +28,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/clearAllAxes.m b/functions/interface/clearAllAxes.m index 09fa837..d4d3158 100644 --- a/functions/interface/clearAllAxes.m +++ b/functions/interface/clearAllAxes.m @@ -23,8 +23,8 @@ function clearAllAxes(figh) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/clearInversion.m b/functions/interface/clearInversion.m index a1a242c..68ff173 100644 --- a/functions/interface/clearInversion.m +++ b/functions/interface/clearInversion.m @@ -28,8 +28,8 @@ function clearInversion(id) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/clearSingleAxis.m b/functions/interface/clearSingleAxis.m index c9c7d0b..e49489e 100644 --- a/functions/interface/clearSingleAxis.m +++ b/functions/interface/clearSingleAxis.m @@ -23,8 +23,8 @@ function clearSingleAxis(axh) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/displayStatusText.m b/functions/interface/displayStatusText.m index 82fb912..60ac746 100644 --- a/functions/interface/displayStatusText.m +++ b/functions/interface/displayStatusText.m @@ -1,5 +1,6 @@ function displayStatusText(gui,string) -%displayStatusText clears all axes of a given figure +%displayStatusText shows status information either in the GUI or on the +%commandline % % Syntax: % displayStatusText(gui,string) @@ -24,15 +25,19 @@ function displayStatusText(gui,string) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- %% display status / info text -set(gui.textStatus,'String',string); -pause(0.001); +if isstruct(gui) + set(gui.textStatus,'String',string); + pause(0.001); +else + disp(string); +end end diff --git a/functions/interface/enableGUIelements.m b/functions/interface/enableGUIelements.m index 42244c1..f588368 100644 --- a/functions/interface/enableGUIelements.m +++ b/functions/interface/enableGUIelements.m @@ -24,8 +24,8 @@ function enableGUIelements(importtype) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -54,7 +54,7 @@ function enableGUIelements(importtype) % process panel data.process.end = 0; switch data.import.fileformat - case {'field','dart'} + case {'dart','field','helios'} data.process.gatetype = 'raw'; otherwise data.process.gatetype = 'log'; diff --git a/functions/interface/exportData.m b/functions/interface/exportData.m index 41e6ba6..3f26a79 100644 --- a/functions/interface/exportData.m +++ b/functions/interface/exportData.m @@ -29,8 +29,8 @@ function exportData(fig_tag,format) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -149,7 +149,7 @@ function exportData(fig_tag,format) idata.NUCLEUSinv_GUI = rmfield(idata.NUCLEUSinv_GUI,'results'); % save to file - save(fullfile(spath,sfile),'idata'); + save(fullfile(spath,sfile),'idata','-v7.3'); % display info text displayStatusText(gui,... @@ -183,7 +183,7 @@ function exportData(fig_tag,format) idata.NUCLEUSinv_GUI = rmfield(idata.NUCLEUSinv_GUI,'results'); % save to file - save(fullfile(spath,sfile),'idata'); + save(fullfile(spath,sfile),'idata','-v7.3'); % display info text displayStatusText(gui,... @@ -330,7 +330,7 @@ function exportData(fig_tag,format) if ~isequal(FileName,0) || ~isequal(PathName,0) clear data data = out; %#ok - save(fullfile(PathName,FileName),'data'); + save(fullfile(PathName,FileName),'data','-v7.3'); displayStatusText(gui,'Saving to MAT-file ... done.'); else displayStatusText(gui,'Saving to MAT-file ... canceled.'); @@ -424,7 +424,7 @@ function exportINV_EXCEL(gui,INVdata,id,sfile,spath) header4 = {['T2 [',unit,']'],'amplitude [a.u.]'}; end - case {'LU','NNLS'} + case {'LU','NNLS','MUMO'} tmp4 = [INVdata{id}.results.invstd.T1T2me(:)... INVdata{id}.results.invstd.T1T2f(:)]; header4 = {['relaxation times [',unit,']'],'amplitudes [a.u.]'}; diff --git a/functions/interface/exportGraphics.m b/functions/interface/exportGraphics.m index 69c19c6..f9a654e 100644 --- a/functions/interface/exportGraphics.m +++ b/functions/interface/exportGraphics.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -303,9 +303,19 @@ switch fig_tag case 'INV' + % which NMR signal + id = get(gui.listbox_handles.signal,'Value'); + % get the new file name + sfilename = data.import.NMR.filesShort{id}; + ind1 = strfind(sfilename,'.'); + if isempty(ind1) + sfilename = [sfilename,'_INV']; + else + sfilename = [sfilename(1:ind1-1),'_INV']; + end [FileName,PathName,~] = uiputfile({putext,put1},... ['NUCLEUSinv: Save ',statstr,' Graphics'],... - fullfile(pwd,'NUCLEUSinv_inversion')); + fullfile(data.import.path,sfilename)); case 'MOD' [FileName,PathName,~] = uiputfile({putext,put1},... ['NUCLEUSmod: Save ',statstr,' Graphics'],... diff --git a/functions/interface/exportINV.m b/functions/interface/exportINV.m index 7568505..d17c113 100644 --- a/functions/interface/exportINV.m +++ b/functions/interface/exportINV.m @@ -30,8 +30,8 @@ function exportINV(format,varargin) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -63,7 +63,7 @@ function exportINV(format,varargin) savedata.filesShort = data.import.NMR.filesShort; % save to default file at local data path - save(fullfile(data.import.path,'NUCLEUSinv_raw.mat'),'savedata'); + save(fullfile(data.import.path,'NUCLEUSinv_raw.mat'),'savedata','-v7.3'); clear savedata; % display info text @@ -90,7 +90,7 @@ function exportINV(format,varargin) if dosilent - save(fullfile(sfile),'savedata'); + save(fullfile(sfile),'savedata','-v7.3'); clear savedata; else % session file name @@ -109,7 +109,7 @@ function exportINV(format,varargin) % if user didn't cancel save session if sum([sfile spath]) > 0 - save(fullfile(spath,sfile),'savedata'); + save(fullfile(spath,sfile),'savedata','-v7.3'); clear savedata; % display info text diff --git a/functions/interface/findParentOfType.m b/functions/interface/findParentOfType.m index e56b249..368fea3 100644 --- a/functions/interface/findParentOfType.m +++ b/functions/interface/findParentOfType.m @@ -28,8 +28,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/fixAxes.m b/functions/interface/fixAxes.m index d195712..b2ed2ef 100644 --- a/functions/interface/fixAxes.m +++ b/functions/interface/fixAxes.m @@ -27,8 +27,8 @@ function fixAxes(src,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/getColorIndex.m b/functions/interface/getColorIndex.m index a7f9a99..866c48f 100644 --- a/functions/interface/getColorIndex.m +++ b/functions/interface/getColorIndex.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/getColorTheme.m b/functions/interface/getColorTheme.m index c9630a1..cdba4d7 100644 --- a/functions/interface/getColorTheme.m +++ b/functions/interface/getColorTheme.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/getVersionNoFromString.m b/functions/interface/getVersionNoFromString.m index c8ed450..17933a3 100644 --- a/functions/interface/getVersionNoFromString.m +++ b/functions/interface/getVersionNoFromString.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/importASCIIdata.m b/functions/interface/importASCIIdata.m index dd36042..1a9e05b 100644 --- a/functions/interface/importASCIIdata.m +++ b/functions/interface/importASCIIdata.m @@ -26,8 +26,8 @@ function importASCIIdata(src) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -129,11 +129,19 @@ function importASCIIdata(src) data.import.NMR.data{c}.phase = tmp_phase; else data.import.NMR.data{c}.signal = tmp_data(:,2); + data.import.NMR.data{c}.phase = 0; + + param.T1IRfac = 1; + param.noise = 0; + param.optim = 'off'; + invstd = fitDataFree(data.import.NMR.data{c}.time,data.import.NMR.data{c}.signal,... + 'T2',param,5); + data.import.NMR.data{c}.noise = invstd.rms; end data.import.NMR.data{c}.T1IRfac = 1; data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; data.import.NMR.data{c}.raw.signal = data.import.NMR.data{c}.signal; - + % dummy parameter data data.import.NMR.para{c} = 0; end diff --git a/functions/interface/importCPSdata.m b/functions/interface/importCPSdata.m index 26b07a6..99e474f 100644 --- a/functions/interface/importCPSdata.m +++ b/functions/interface/importCPSdata.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/importEXCELdata.m b/functions/interface/importEXCELdata.m index f56bc62..b9d09ec 100644 --- a/functions/interface/importEXCELdata.m +++ b/functions/interface/importEXCELdata.m @@ -27,8 +27,8 @@ function importEXCELdata(src) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/importINV2INV.m b/functions/interface/importINV2INV.m index 7b041c0..fc1710a 100644 --- a/functions/interface/importINV2INV.m +++ b/functions/interface/importINV2INV.m @@ -27,8 +27,8 @@ function importINV2INV(src) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -55,7 +55,10 @@ function importINV2INV(src) end % only continue if user didn't cancel -if sum(Sessionpath) > 0 +if sum(Sessionpath) > 0 + % display info text + displayStatusText(gui,'Importing GUI session from mat-file ...'); + % check if it is a valid session file tmp = load(fullfile(Sessionpath,Sessionfile),'savedata'); if isfield(tmp,'savedata') && isfield(tmp.savedata,'data') && ... @@ -65,65 +68,43 @@ function importINV2INV(src) % check import uimenu set(src,'Checked','on'); - % adjust menu entry for expert mode - switch savedata.data.info.ExpertMode - case 'on' - set(gui.menu.extra_expert,'Checked','off'); - case 'off' - set(gui.menu.extra_expert,'Checked','on'); - end - onMenuExpert(gui.menu.extra_expert); - - % adjust menu entry for joint inversion - switch savedata.data.info.JointInv - case 'on' - set(gui.menu.extra_joint,'Checked','off'); - case 'off' - set(gui.menu.extra_joint,'Checked','on'); - end - onMenuJointInversion(gui.menu.extra_joint); - enableGUIelements('NMR'); - - % adjust menu entry for comand line inversion info - switch savedata.data.info.InvInfo - case 'on' - set(gui.menu.view_invinfo,'Checked','off'); - case 'off' - set(gui.menu.view_invinfo,'Checked','on'); - end - onMenuView(gui.menu.view_invinfo); - - % adjust menu entry for tool tips - switch savedata.data.info.ToolTips - case 'on' - set(gui.menu.view_tooltips,'Checked','off'); - case 'off' - set(gui.menu.view_tooltips,'Checked','on'); - end - onMenuView(gui.menu.view_tooltips); - - % update GUI data from session mat-file - data = savedata.data; - INVdata = savedata.INVdata; - % backward compatibility with older versions + % display info text + displayStatusText(gui,'Importing GUI session from mat-file ... backward compatibility.'); % current GUI version version = getVersionNoFromString(gui.myui.version); % import GUI version version_in = getVersionNoFromString(savedata.myui.version); if version_in < version if version_in < 19 % changes introduced with v.0.1.9 + % rename 'ILA' to 'LU' in savedata if strcmp(savedata.data.invstd.invtype,'ILA') - data.invstd.invtype = 'LU'; + savedata.data.invstd.invtype = 'LU'; + end + for i = 1:numel(savedata.INVdata) + if isstruct(savedata.INVdata{i}) && ... + strcmp(savedata.INVdata{i}.invstd.invtype,'ILA') + savedata.INVdata{i}.invstd.invtype = 'LU'; + end end + end + if version_in < 112 % changes introduced with v.0.1.12 + % add 'Tdiff' field to savedata + savedata.data.invstd.Tdiff = data.invstd.Tdiff; for i = 1:numel(savedata.INVdata) - if strcmp(savedata.INVdata{i}.invstd.invtype,'ILA') - INVdata{i}.invstd.invtype = 'LU'; + if isstruct(savedata.INVdata{i}) + savedata.INVdata{i}.invstd.Tdiff = data.invstd.Tdiff; end end end - end + end + % update GUI data from session mat-file + data = savedata.data; + INVdata = savedata.INVdata; + + % display info text + displayStatusText(gui,'Importing GUI session from mat-file ... update GUI data.'); % check if the import path exists on this machine isdir_import = dir(data.import.path); % if not replace it with the path the session-file was loaded from @@ -159,6 +140,8 @@ function importINV2INV(src) set(gui.listbox_handles.signal,'String',data.import.NMR.filesShort); set(gui.listbox_handles.signal,'Value',[],'Max',2,'Min',0); + % display info text + displayStatusText(gui,'Importing GUI session from mat-file ... update GUI interface.'); % update GUI interface NUCLEUSinv_updateInterface; @@ -174,32 +157,63 @@ function importINV2INV(src) set(gui.listbox_handles.signal,'String',strL); end end - + + % display info text + displayStatusText(gui,'Importing GUI session from mat-file ... update GUI menus.'); + % adjust menu entry for expert mode + switch savedata.data.info.ExpertMode + case 'on' + set(gui.menu.extra_expert,'Checked','off'); + case 'off' + set(gui.menu.extra_expert,'Checked','on'); + end + onMenuExpert(gui.menu.extra_expert); + + % adjust menu entry for joint inversion + switch savedata.data.info.JointInv + case 'on' + set(gui.menu.extra_joint,'Checked','off'); + case 'off' + set(gui.menu.extra_joint,'Checked','on'); + end + onMenuJointInversion(gui.menu.extra_joint); + enableGUIelements('NMR'); + + % adjust menu entry for comand line inversion info + switch savedata.data.info.InvInfo + case 'on' + set(gui.menu.view_invinfo,'Checked','off'); + case 'off' + set(gui.menu.view_invinfo,'Checked','on'); + end + onMenuView(gui.menu.view_invinfo); + + % adjust menu entry for tool tips + switch savedata.data.info.ToolTips + case 'on' + set(gui.menu.view_tooltips,'Checked','off'); + case 'off' + set(gui.menu.view_tooltips,'Checked','on'); + end + onMenuView(gui.menu.view_tooltips); + + % display info text + displayStatusText(gui,'Importing GUI session from mat-file ... show last file.'); % set focus on last file used in previous session set(gui.listbox_handles.signal,'Value',savedata.id); + % and simulate click to update all relevant GUI elements + onListboxData(gui.listbox_handles.signal); - % show corresponding file data - updatePlotsSignal; - if isstruct(INVdata{savedata.id}) - if isfield(data,'results') - if isfield(data.results,'invstd') - updatePlotsDistribution; - updateInfo(gui.plots.SignalPanel); - end - if isfield(data.results,'invjoint') - updatePlotsJointInversion; - end - if isfield(data.results,'lcurve') - updatePlotsLcurve; - end - end - end + % display info text + displayStatusText(gui,'Importing GUI session from mat-file ... done.'); else + % display info text + displayStatusText(gui,'Importing GUI session from mat-file ... cancelled.'); + helpdlg({'importINV2INV:';... 'This seems to be not a valid NUCLEUSinv session file'},... 'No session data found'); end - end %------------- END OF CODE -------------- diff --git a/functions/interface/importMOD2INV.m b/functions/interface/importMOD2INV.m index 8106862..32adf72 100644 --- a/functions/interface/importMOD2INV.m +++ b/functions/interface/importMOD2INV.m @@ -26,8 +26,8 @@ function importMOD2INV(src) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -173,8 +173,10 @@ function importMOD2INV(src) switch T1T2 case 'T1' data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EdT1(dL(i),:)'; + data.import.NMR.data{c}.noise = data.import.NMRMOD.nmr.noise(dL(i),2); case 'T2' data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EdT2(dL(i),:)'; + data.import.NMR.data{c}.noise = data.import.NMRMOD.nmr.noise(dL(i),4); end data.import.NMR.data{c}.phase = 0; data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; @@ -182,6 +184,11 @@ function importMOD2INV(src) data.import.NMR.para{c}.geom = data.import.NMRMOD.geom.type; data.import.NMR.para{c}.Tbulk = data.import.NMRMOD.nmr.Tb; + if isfield(data.import.NMRMOD.nmr,'Td') + data.import.NMR.para{c}.Tdiff = data.import.NMRMOD.nmr.Td; + else + data.import.NMR.para{c}.Tdiff = 1e6; + end data.import.NMR.para{c}.rho = data.import.NMRMOD.nmr.rho; data.import.NMR.para{c}.porosity = data.import.NMRMOD.nmr.porosity; @@ -213,8 +220,10 @@ function importMOD2INV(src) switch T1T2 case 'T1' data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EiT1(iL(i),:)'; + data.import.NMR.data{c}.noise = data.import.NMRMOD.nmr.noise(iL(i),1); case 'T2' data.import.NMR.data{c}.signal = data.import.NMRMOD.nmr.EiT2(iL(i),:)'; + data.import.NMR.data{c}.noise = data.import.NMRMOD.nmr.noise(iL(i),3); end data.import.NMR.data{c}.phase = 0; data.import.NMR.data{c}.raw.time = data.import.NMR.data{c}.time; @@ -222,6 +231,11 @@ function importMOD2INV(src) data.import.NMR.para{c}.geom = data.import.NMRMOD.geom.type; data.import.NMR.para{c}.Tbulk = data.import.NMRMOD.nmr.Tb; + if isfield(data.import.NMRMOD.nmr,'Td') + data.import.NMR.para{c}.Tdiff = data.import.NMRMOD.nmr.Td; + else + data.import.NMR.para{c}.Tdiff = 1e6; + end data.import.NMR.para{c}.rho = data.import.NMRMOD.nmr.rho; data.import.NMR.para{c}.porosity = data.import.NMRMOD.nmr.porosity; diff --git a/functions/interface/importMOD2MOD.m b/functions/interface/importMOD2MOD.m index 122c4ee..46f1de3 100644 --- a/functions/interface/importMOD2MOD.m +++ b/functions/interface/importMOD2MOD.m @@ -26,8 +26,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -51,6 +51,9 @@ data.geometry = guidata.NMRMOD_GUI.geometry; data.pressure = guidata.NMRMOD_GUI.pressure; data.nmr = guidata.NMRMOD_GUI.nmr; + if ~isfield(guidata.NMRMOD_GUI.nmr,'Td') + data.nmr.Td = 1e6; + end data.results.constants = guidata.constants; data.results.GEOM = guidata.GEOM; data.results.NMR = guidata.NMR; diff --git a/functions/interface/importNMRdata.m b/functions/interface/importNMRdata.m index 956c766..3b2bb0f 100644 --- a/functions/interface/importNMRdata.m +++ b/functions/interface/importNMRdata.m @@ -30,6 +30,7 @@ function importNMRdata(src) % importDataLIAG % importDataLIAGproject % importDataMouse +% importDataHelios % loadGUIParameters % loadGUIrawdata % @@ -37,8 +38,8 @@ function importNMRdata(src) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -73,10 +74,16 @@ function importNMRdata(src) data.import.fileformat = 'liag'; elseif strcmp(label,'BGR std') data.import.fileformat = 'bgr'; - elseif strcmp(label,'BGR org') - data.import.fileformat = 'bgr2'; + elseif strcmp(label,'MouseCPMG') + data.import.fileformat = 'MouseCPMG'; elseif strcmp(label,'BGR mat') data.import.fileformat = 'bgrmat'; + elseif strcmp(label,'MouseLiftSingle') + data.import.fileformat = 'MouseLiftSingle'; + elseif strcmp(label,'MouseLiftAll') + data.import.fileformat = 'MouseLiftAll'; + elseif strcmp(label,'Helios') + data.import.fileformat = 'helios'; elseif strcmp(label,'BAM TOM') data.import.fileformat = 'bamtom'; elseif strcmp(label,'PM5') @@ -102,7 +109,7 @@ function importNMRdata(src) % check for mat-file with GUI rawdata and import data isfile = dir(fullfile(NMRpath,'NUCLEUSinv_raw.mat')); - % if there is nor raw-file import from folder/file + % if there is no raw-file import from folder/file if isempty(isfile) % import data data.import.path = NMRpath; @@ -129,11 +136,18 @@ function importNMRdata(src) tmp_h(5) = gui.myui.heights(1,3); set(gui.panels.main,'Heights',tmp_h); set(gui.panels.petro.main,'Minimized',false); - case 'BGR org' - [data,gui] = importDataBGR(data,gui); case 'BGR mat' data.import.file = NMRfile; [data,gui] = importDataBGRmat(data,gui); + case 'MouseCPMG' + [data,gui] = importDataMouseCPMG(data,gui); + case 'MouseLiftSingle' + [data,gui] = importDataBGRliftSingle(data,gui); + case 'MouseLiftAll' + [data,gui] = importDataBGRliftAll(data,gui); + case 'Helios' + data.import.file = NMRfile; + [data,gui] = importDataHelios(data,gui); case {'PM5','PM25'} data.import.file = NMRfile; [data,gui] = importDataIBAC(data,gui); @@ -232,7 +246,7 @@ function importNMRdata(src) % for almost all import cases we load a folder ... but not for all switch label case {'GGE ascii','GGE field','CoreLab ascii','MOUSE','LIAG single',... - 'BGR std','BGR org','BAM TOM','PM25'} + 'BGR std','MouseCPMG','MouseLiftSingle','MouseLiftAll','Helios','BAM TOM','PM25'} % if there is already a data folder present we start from here if isfield(import,'path') NMRpath = uigetdir(import.path,'Choose Data Path'); @@ -302,14 +316,10 @@ function importNMRdata(src) end %% -function [data,gui] = importDataBGR(data,gui) +function [data,gui] = importDataMouseCPMG(data,gui) -% first check the subpaths -% there should be 'cpmgfastauto' and 't1test' -t1path = dir(fullfile(data.import.path,'t1test')); -t1path = t1path(~ismember({t1path.name},{'.','..'})); -t2path = dir(fullfile(data.import.path,'cpmgfastauto')); -t2path = t2path(~ismember({t2path.name},{'.','..'})); +csv_t2path = dir(fullfile(data.import.path,'CPMG')); +csv_t2path = csv_t2path(~ismember({csv_t2path.name},{'.','..'})); fnames = struct; % shownames is just a dummy to hold all data file names that @@ -317,48 +327,21 @@ function importNMRdata(src) shownames = cell(1,1); c = 0; -if ~isempty(t1path) - for i = 1:size(t1path,1) - in.T1T2 = 'T1'; - in.path = fullfile(data.import.path,'t1test',t1path(i).name); - in.fileformat = data.import.fileformat; - out = LoadNMRData_driver(in); - - for j = 1:size(out.nmrData,2) - % the individual file names - c = c + 1; - fnames(c).parfile = 'acq.par'; - fnames(c).datafile = out.nmrData{j}.datfile; - - shownames{c} = ['T1_',t1path(i).name,'_',fnames(c).datafile]; - - % the NMR data - % here we fix the time scale from [ms] to [s] - if max(out.nmrData{j}.time) > 100 - out.nmrData{j}.time = out.nmrData{j}.time/1000; - out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; - end - data.import.NMR.data{c} = out.nmrData{j}; - data.import.NMR.para{c} = out.parData; - end - end -end - -if ~isempty(t2path) - for i = 1:size(t2path,1) +if ~isempty(csv_t2path) + for i = 1:size(csv_t2path,1) in.T1T2 = 'T2'; - in.path = fullfile(data.import.path,'cpmgfastauto',t2path(i).name); + in.path = fullfile(data.import.path,'CPMG',csv_t2path(i).name); in.fileformat = data.import.fileformat; out = LoadNMRData_driver(in); for j = 1:size(out.nmrData,2) % the individual file names c = c + 1; - fnames(c).parfile = 'acq.par'; + fnames(c).parfile = 'acqu.par'; fnames(c).datafile = out.nmrData{j}.datfile; fnames(c).T2specfile = ''; - shownames{c} = ['T2_',t2path(i).name,'_',fnames(c).datafile]; + shownames{c} = ['T2_',csv_t2path(i).name,'_',fnames(c).datafile]; % the NMR data % here we fix the time scale from [ms] to [s] @@ -372,7 +355,7 @@ function importNMRdata(src) end end -if isempty(t1path) && isempty(t2path) +if isempty(csv_t2path) helpdlg('No data folders in the given directory.','onMenuImport: No data.'); else % update the global data structure @@ -435,6 +418,174 @@ function importNMRdata(src) end +%% +function [data,gui] = importDataBGRliftSingle(data,gui) + +% first check whether T1 or T2 was measured... +% by analyzing the name of data folder +indiz = find(data.import.path == filesep); +checkT1T2 = data.import.path(indiz(end-1)+1:indiz(end)-1); +if strcmp(checkT1T2,'t1test') + in.T1T2 = 'T1'; +elseif strcmp(checkT1T2,'cpmgfastautotest') + in.T1T2 = 'T2'; +elseif strcmp(checkT1T2,'cpmgfastauto') + in.T1T2 = 'T2'; +else + disp('Please chose an original Prospa folder for Mouse Lift data!'); +end + +% % there should be folders with integer values in their names +% t1t2path = data.import.path; + +fnames = struct; +% shownames is just a dummy to hold all data file names that +% will be shown in the listbox +shownames = cell(1,1); + +c = 0; +if ~isempty(data.import.path) +% for i = 1:size(t1t2path,1) + in.path = data.import.path; + in.fileformat = data.import.fileformat; + out = LoadNMRData_driver(in); + + for j = 1:size(out.nmrData,2) + % the individual file names + c = c + 1; + fnames(c).parfile = 'acq.par'; + fnames(c).datafile = out.nmrData{j}.datfile; + + shownames{c} = [in.T1T2,'_',fnames(c).datafile]; + + % the NMR data + % here we fix the time scale from [ms] to [s] + if max(out.nmrData{j}.time) > 100 + out.nmrData{j}.time = out.nmrData{j}.time/1000; + out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; + end + data.import.NMR.data{c} = out.nmrData{j}; + data.import.NMR.para{c} = out.parData; + end +else + helpdlg('No data folders in the given directory.','onMenuImport: No data.'); +end + + + % update the global data structure + data.import.NMR.files = fnames; + data.import.NMR.filesShort = shownames; + +end +%% +function [data,gui] = importDataBGRliftAll(data,gui) + +% first check whether T1 or T2 was measured +indiz = find(data.import.path == filesep); +checkT1T2 = data.import.path(indiz(end)+1:end); +if strcmp(checkT1T2,'t1test') + in.T1T2 = 'T1'; +elseif strcmp(checkT1T2,'cpmgfastautotest') + in.T1T2 = 'T2'; +elseif strcmp(checkT1T2,'cpmgfastauto') + in.T1T2 = 'T2'; +else + helpdlg('No original data folder','onMenuImport: No data.'); +end + +% there should be folders with integer values in their names +t1t2path = dir(data.import.path); +t1t2path = t1t2path(~ismember({t1t2path.name},{'.','..'})); + +fnames = struct; +% shownames is just a dummy to hold all data file names that +% will be shown in the listbox +shownames = cell(1,1); + +c = 0; +if ~isempty(t1t2path) + for i = 1:size(t1t2path,1) + in.path = fullfile(data.import.path,t1t2path(i).name); + in.fileformat = data.import.fileformat; + out = LoadNMRData_driver(in); + + for j = 1:size(out.nmrData,2) + % the individual file names + c = c + 1; + fnames(c).parfile = 'acq.par'; + fnames(c).datafile = out.nmrData{j}.datfile; + + shownames{c} = [in.T1T2,'_',t1t2path(i).name,'_',fnames(c).datafile]; + + % the NMR data + % here we fix the time scale from [ms] to [s] + if max(out.nmrData{j}.time) > 100 + out.nmrData{j}.time = out.nmrData{j}.time/1000; + out.nmrData{j}.raw.time = out.nmrData{j}.raw.time/1000; + end + data.import.NMR.data{c} = out.nmrData{j}; + data.import.NMR.para{c} = out.parData; + end + end +else + helpdlg('No data folders in the given directory.','onMenuImport: No data.'); +end + % update the global data structure + data.import.NMR.files = fnames; + data.import.NMR.filesShort = shownames; + +end + +%% +function [data,gui] = importDataHelios(data,gui) + +% first check the subpaths +% there should be some folders with names ... +% ... similar to the data filenames inside them +datpath = dir(data.import.path); +datpath = datpath(~ismember({datpath.name},{'.','..'})); + +fnames = struct; +% shownames is just a dummy to hold all data file names that +% will be shown in the listbox +shownames = cell(1,1); + +c = 0; +if ~isempty(datpath) + for i = 1:size(datpath,1) + % does datpath.name points to a folder? + if datpath(i).isdir + % check if datpath.name includes regular Helios data files + content = dir([data.import.path,filesep,datpath(i).name]); + content = content(~ismember({content.name},{'.','..'})); + for j = 1:size(content,1) + if strcmp(content(j).name,[datpath(i).name,'_1.hrd']) + in.T1T2 = 'T2'; + in.name = content(j).name; + in.path = fullfile(data.import.path,filesep,datpath(i).name); + in.fileformat = data.import.fileformat; + out = LoadNMRData_driver(in); + + % the individual file names + c = c + 1; + fnames(c).parfile = ''; + fnames(c).datafile = out.nmrData.datfile; + fnames(c).T2specfile = ''; + shownames{c} = ['T2_',datpath(i).name]; + + data.import.NMR.data{c} = out.nmrData; + data.import.NMR.para{c} = out.parData; + end + end + end + end +end + +data.import.NMR.files = fnames; +data.import.NMR.filesShort = shownames; + +end + %% function [data,gui] = importDataDart(data,gui) diff --git a/functions/interface/makeINIfile.m b/functions/interface/makeINIfile.m index 238361c..734de69 100644 --- a/functions/interface/makeINIfile.m +++ b/functions/interface/makeINIfile.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/minimizePanel.m b/functions/interface/minimizePanel.m index 03fade9..d594f96 100644 --- a/functions/interface/minimizePanel.m +++ b/functions/interface/minimizePanel.m @@ -24,8 +24,8 @@ function minimizePanel(src,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/moveEntryInList.m b/functions/interface/moveEntryInList.m index 8a64bd9..eb8a14b 100644 --- a/functions/interface/moveEntryInList.m +++ b/functions/interface/moveEntryInList.m @@ -23,8 +23,8 @@ function moveEntryInList(inc) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/onFigureSizeChange.m b/functions/interface/onFigureSizeChange.m index 06a8382..ad68f6e 100644 --- a/functions/interface/onFigureSizeChange.m +++ b/functions/interface/onFigureSizeChange.m @@ -27,8 +27,8 @@ function onFigureSizeChange(fig,~) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -40,34 +40,32 @@ function onFigureSizeChange(fig,~) switch fig_tag case 'INV' % proceed if there is data - if ~isempty(gui) - if isfield(gui,'panels') - heights = get(gui.panels.main,'Heights'); - set(gui.left,'Heights',-1,'MinimumHeights',sum(heights(2:end))+250); - % check if CPS settings panel is activated - if heights(end) > 100 - % check if there is a vertical scrollbar - hpos = get(gui.top,'InnerPosition'); - if get(gui.left,'MinimumHeights') > hpos(4) - % if yes shift the table slightly to the right to avoid - % horizontal resizing - set(gui.panels.invjoint.TabCPS,'Widths',[180 -1]); - else - % if not use the default layout - set(gui.panels.invjoint.TabCPS,'Widths',[200 -1]); - end + if ~isempty(gui) && isfield(gui,'panels') + heights = get(gui.panels.main,'Heights'); + set(gui.left,'Heights',-1,'MinimumHeights',sum(heights(2:end))+250); + % check if CPS settings panel is activated + if heights(end) > 100 + % check if there is a vertical scrollbar + hpos = get(gui.top,'InnerPosition'); + if get(gui.left,'MinimumHeights') > hpos(4) + % if yes shift the table slightly to the right to avoid + % horizontal resizing + set(gui.panels.invjoint.TabCPS,'Widths',[180 -1]); + else + % if not use the default layout + set(gui.panels.invjoint.TabCPS,'Widths',[200 -1]); end - % check if process panel is activated - if heights(2) > 100 - % check if there is a vertical scrollbar - hpos = get(gui.top,'InnerPosition'); - if get(gui.left,'MinimumHeights') > hpos(4) - % if yes shift the hbox2 slightly to the right - set(gui.panels.process.HBox2,'Widths',[180 -1 -1 -1.5 50]); - else - % if not use the default layout - set(gui.panels.process.HBox2,'Widths',[200 -1 -1 -1.5 50]); - end + end + % check if process panel is activated + if heights(2) > 100 + % check if there is a vertical scrollbar + hpos = get(gui.top,'InnerPosition'); + if get(gui.left,'MinimumHeights') > hpos(4) + % if yes shift the hbox2 slightly to the right + set(gui.panels.process.HBox2,'Widths',[180 -1 -1 -1.5 50]); + else + % if not use the default layout + set(gui.panels.process.HBox2,'Widths',[200 -1 -1 -1.5 50]); end end end @@ -78,7 +76,7 @@ function onFigureSizeChange(fig,~) case 'MOD' % proceed if there is data - if ~isempty(gui) + if ~isempty(gui) && isfield(gui,'panels') heights = get(gui.panels.main,'Heights'); if heights(2) == -1 set(gui.left,'Heights',-1,'MinimumHeights',sum(heights(1:end))+250); diff --git a/functions/interface/processNMRData.m b/functions/interface/processNMRData.m index fafd41c..0d9583e 100644 --- a/functions/interface/processNMRData.m +++ b/functions/interface/processNMRData.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -68,8 +68,9 @@ if isreal(nmrraw.s) s = nmrraw.s; % check if noise was calculated / estimated during import + % and normalize if necessary if isfield(nmrraw,'noise') - noise = nmrraw.noise; + noise = nmrraw.noise./nmrproc.normfac; else noise = 0; end diff --git a/functions/interface/processNMRDataControl.m b/functions/interface/processNMRDataControl.m index bd58640..cd18a8a 100644 --- a/functions/interface/processNMRDataControl.m +++ b/functions/interface/processNMRDataControl.m @@ -25,8 +25,8 @@ function processNMRDataControl(fig,id) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -65,24 +65,6 @@ function processNMRDataControl(fig,id) data.results.nmrproc = nmrproc; data.process.normfac = nmrproc.normfac; -% some special treatment of NUCLEUSmod data -if isfield(data.import,'NMRMOD') - noise = data.import.NMRMOD.nmr.noise; - data.results.nmrproc.noise = noise; - if noise ~=0 && ~strcmp(nmrproc.gatetype,'raw') - e = noise ./ sqrt(nmrproc.N); - W = diag(e) * eye(size(e,1)); - data.results.nmrproc.e = e; - data.results.nmrproc.W = W; - else - e = noise*ones(size(nmrproc.s)); - data.results.nmrproc.e = e; - if isfield(data.results.nmrproc,'W') - data.results.nmrproc = rmfield(data.results.nmrproc,'W'); - end - end -end - % update GUI data setappdata(fig,'data',data); diff --git a/functions/interface/readINIfile.m b/functions/interface/readINIfile.m index 946b67f..5898461 100644 --- a/functions/interface/readINIfile.m +++ b/functions/interface/readINIfile.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/removeCalculationFields.m b/functions/interface/removeCalculationFields.m index 7cbeb34..8f5eb1e 100644 --- a/functions/interface/removeCalculationFields.m +++ b/functions/interface/removeCalculationFields.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/removeInversionFields.m b/functions/interface/removeInversionFields.m index e173b3f..2e7e3f9 100644 --- a/functions/interface/removeInversionFields.m +++ b/functions/interface/removeInversionFields.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/removeSignalFromList.m b/functions/interface/removeSignalFromList.m index b10ed8b..b0e169e 100644 --- a/functions/interface/removeSignalFromList.m +++ b/functions/interface/removeSignalFromList.m @@ -24,8 +24,8 @@ function removeSignalFromList(id) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/resortDataList.m b/functions/interface/resortDataList.m index df1be55..bdf6e47 100644 --- a/functions/interface/resortDataList.m +++ b/functions/interface/resortDataList.m @@ -23,8 +23,8 @@ function resortDataList(label) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/runInversionBatch.m b/functions/interface/runInversionBatch.m index 96bff81..34853b5 100644 --- a/functions/interface/runInversionBatch.m +++ b/functions/interface/runInversionBatch.m @@ -32,8 +32,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -127,10 +127,24 @@ invstd = fitDataFree(data.results.nmrproc.t,... data.results.nmrproc.s,flag,param,data.invstd.freeDT); + case 'LU' + param.T1T2 = data.results.nmrproc.T1T2; + param.T1IRfac = data.results.nmrproc.T1IRfac; + param.Tb = data.invstd.Tbulk; + param.Td = data.invstd.Tdiff; + param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; + param.Lorder = data.invstd.Lorder; + param.lambda = data.invstd.lambda; + param.noise = data.results.nmrproc.noise; + + invstd = fitDataLUdecomp(data.results.nmrproc.t,... + data.results.nmrproc.s,param); + case 'NNLS' param.T1T2 = data.results.nmrproc.T1T2; param.T1IRfac = data.results.nmrproc.T1IRfac; param.Tb = data.invstd.Tbulk; + param.Td = data.invstd.Tdiff; param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; param.regMethod = data.invstd.regtype; param.Lorder = data.invstd.Lorder; @@ -144,17 +158,45 @@ invstd = fitDataLSQ(data.results.nmrproc.t,... data.results.nmrproc.s,param); - case 'LU' + case 'MUMO' % N free distribution inversion param.T1T2 = data.results.nmrproc.T1T2; param.T1IRfac = data.results.nmrproc.T1IRfac; param.Tb = data.invstd.Tbulk; + param.Td = data.invstd.Tdiff; param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; - param.Lorder = data.invstd.Lorder; - param.lambda = data.invstd.lambda; + param.regMethod = data.invstd.regtype; param.noise = data.results.nmrproc.noise; + param.solver = data.info.solver; + param.optim = data.info.has_optim; + if isfield(data.results.nmrproc,'W') + param.W = data.results.nmrproc.W; + end - invstd = fitDataLUdecomp(data.results.nmrproc.t,... - data.results.nmrproc.s,param); + % status bar information + switch data.info.solver + case 'lsqlin' + infostring = 'Inversion using ''Optimization Toolbox'' ... '; + case 'lsqnonneg' + infostring = 'Inversion using ''fminsearchbnd'' ... '; + end + displayStatusText(gui,infostring); + invstd = fitDataMultiModal(data.results.nmrproc.t,... + data.results.nmrproc.s,param,data.invstd.freeDT); + + % estimate uncertainty + if data.invstd.useUncert + % original fit parameter + iparam = param; + % uncertainty parameter + uparam.time = data.results.nmrproc.t; + uparam.signal = data.results.nmrproc.s; + uparam.uncertMethod = data.invstd.uncertMethod; + uparam.uncertThresh = data.invstd.uncertThresh; + uparam.uncertChi2 = data.invstd.uncertChi2; + uparam.uncertN = data.invstd.uncertN; + uparam.uncertMax = data.invstd.uncertMax; + invstd = estimateUncertainty(data.invstd.invtype,invstd,iparam,uparam); + end end % save inversion results diff --git a/functions/interface/runInversionJoint.m b/functions/interface/runInversionJoint.m index f8367b0..40659d1 100644 --- a/functions/interface/runInversionJoint.m +++ b/functions/interface/runInversionJoint.m @@ -44,8 +44,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -276,6 +276,7 @@ iparam.W = W; end iparam.Tb = data.invstd.Tbulk; + iparam.Td = data.invstd.Tdiff; iparam.T1T2 = T1T2flag; iparam.T1IRfac = T1IRfac; iparam.L = L; @@ -370,8 +371,8 @@ case 'manual' % disable the RUN button to indicate a running inversion set(gui.push_handles.invjoint_run,'String','RUNNING ...',... - 'Enable','inactive'); - + 'Enable','inactive'); + % inversion parameter iparam.t = t; iparam.g = g; @@ -379,6 +380,7 @@ iparam.W = W; end iparam.Tb = data.invstd.Tbulk; + iparam.Td = data.invstd.Tdiff; iparam.T1T2 = T1T2flag; iparam.T1IRfac = T1IRfac; iparam.L = L; @@ -405,6 +407,7 @@ 'Algorithm','levenberg-marquardt',... 'MaxIter',1000); [X,~,~,exitflag] = lsqnonlin(@(X)fcn_JointInvfree(X,iparam),x0,lb,ub,options); + % status bar information displayStatusText(gui,[infostring,'done']); % get the final fit @@ -496,6 +499,7 @@ end iparam.indt = indt; iparam.Tb = data.invstd.Tbulk; + iparam.Td = data.invstd.Tdiff; iparam.T1T2 = T1T2flag; iparam.T1IRfac = T1IRfac; iparam.SatImbDrain = SatImbDrain; @@ -604,6 +608,7 @@ end iparam.indt = indt; iparam.Tb = data.invstd.Tbulk; + iparam.Td = data.invstd.Tdiff; iparam.T1T2 = T1T2flag; iparam.T1IRfac = T1IRfac; iparam.SatImbDrain = SatImbDrain; diff --git a/functions/interface/runInversionStd.m b/functions/interface/runInversionStd.m index 7477a8c..784955f 100644 --- a/functions/interface/runInversionStd.m +++ b/functions/interface/runInversionStd.m @@ -42,8 +42,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -101,6 +101,7 @@ param.T1T2 = data.results.nmrproc.T1T2; param.T1IRfac = data.results.nmrproc.T1IRfac; param.Tb = data.invstd.Tbulk; + param.Td = data.invstd.Tdiff; param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; param.regMethod = 'manual'; param.Lorder = data.invstd.Lorder; @@ -211,7 +212,7 @@ invstd = fitDataFree(data.results.nmrproc.t,... data.results.nmrproc.s,flag,param,1); - case 'free' % bi-exponential inversion + case 'free' % N free single-exponential inversion flag = data.results.nmrproc.T1T2; param.T1IRfac = data.results.nmrproc.T1IRfac; param.noise = data.results.nmrproc.noise; @@ -235,6 +236,7 @@ param.T1T2 = data.results.nmrproc.T1T2; param.T1IRfac = data.results.nmrproc.T1IRfac; param.Tb = data.invstd.Tbulk; + param.Td = data.invstd.Tdiff; param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; param.Lorder = data.invstd.Lorder; param.lambda = data.invstd.lambda; @@ -253,6 +255,7 @@ param.T1T2 = data.results.nmrproc.T1T2; param.T1IRfac = data.results.nmrproc.T1IRfac; param.Tb = data.invstd.Tbulk; + param.Td = data.invstd.Tdiff; param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; param.regMethod = data.invstd.regtype; param.Lorder = data.invstd.Lorder; @@ -273,17 +276,57 @@ displayStatusText(gui,infostring); invstd = fitDataLSQ(data.results.nmrproc.t,... data.results.nmrproc.s,param); + + case 'MUMO' % N free distribution inversion + param.T1T2 = data.results.nmrproc.T1T2; + param.T1IRfac = data.results.nmrproc.T1IRfac; + param.Tb = data.invstd.Tbulk; + param.Td = data.invstd.Tdiff; + param.Tint = [log10(data.invstd.time) data.invstd.Ntime]; + param.noise = data.results.nmrproc.noise; + param.optim = data.info.has_optim; + if isfield(data.results.nmrproc,'W') + param.W = data.results.nmrproc.W; + end + + % status bar information + switch data.info.solver + case 'lsqlin' + infostring = 'Inversion using ''Optimization Toolbox'' ... '; + case 'lsqnonneg' + infostring = 'Inversion using ''fminsearchbnd'' ... '; + end + displayStatusText(gui,infostring); + invstd = fitDataMultiModal(data.results.nmrproc.t,... + data.results.nmrproc.s,param,data.invstd.freeDT); + + % estimate uncertainty + if data.invstd.useUncert + % original fit parameter + iparam = param; + % uncertainty parameter + uparam.time = data.results.nmrproc.t; + uparam.signal = data.results.nmrproc.s; + uparam.uncertMethod = data.invstd.uncertMethod; + uparam.uncertThresh = data.invstd.uncertThresh; + uparam.uncertChi2 = data.invstd.uncertChi2; + uparam.uncertN = data.invstd.uncertN; + uparam.uncertMax = data.invstd.uncertMax; + invstd = estimateUncertainty(data.invstd.invtype,invstd,iparam,uparam); + end end % normalize to 1 if data.process.norm == 1 switch data.invstd.invtype - case {'LU','NNLS'} - % normalization with sum(f*dt) -> area~=1 - % dt = log10(invstd.T1T2me(2))-log10(invstd.T1T2me(1)); - % invstd.T1T2f = invstd.T1T2f/sum(invstd.T1T2f*dt); + case {'LU','NNLS','MUMO'} % normalization with sum() -> sum(f)=1 + % this is the standard way of doing it invstd.T1T2f = invstd.T1T2f./sum(invstd.T1T2f); - % normalization with trapz() -> area=1 but sum(f)>1 + % alternatives depending on the objective: + % 1.) normalization with sum(f*dt) -> area~=1 + % dt = log10(invstd.T1T2me(2))-log10(invstd.T1T2me(1)); + % invstd.T1T2f = invstd.T1T2f/sum(invstd.T1T2f*dt); + % 2.) normalization with trapz() -> area=1 but sum(f)>1 % invstd.T1T2f = invstd.T1T2f./trapz(invstd.T1T2me,invstd.T1T2f); otherwise % nothing to do diff --git a/functions/interface/showExtraGraphics.m b/functions/interface/showExtraGraphics.m index ffaa21e..3a64831 100644 --- a/functions/interface/showExtraGraphics.m +++ b/functions/interface/showExtraGraphics.m @@ -24,8 +24,8 @@ function showExtraGraphics(method) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/showFitStatistics.m b/functions/interface/showFitStatistics.m index 91151f5..3024c0a 100644 --- a/functions/interface/showFitStatistics.m +++ b/functions/interface/showFitStatistics.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/showParameterInfo.m b/functions/interface/showParameterInfo.m index b5efe50..5b37cfe 100644 --- a/functions/interface/showParameterInfo.m +++ b/functions/interface/showParameterInfo.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/switchToolTips.m b/functions/interface/switchToolTips.m index a157b9c..25f4ef9 100644 --- a/functions/interface/switchToolTips.m +++ b/functions/interface/switchToolTips.m @@ -24,8 +24,8 @@ function switchToolTips(gui,onoff) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/uncheckImportMenus.m b/functions/interface/uncheckImportMenus.m index 1c72693..cd541f0 100644 --- a/functions/interface/uncheckImportMenus.m +++ b/functions/interface/uncheckImportMenus.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -45,8 +45,11 @@ set(gui.menu.file_import_lab_liag_single,'Checked','off'); set(gui.menu.file_import_lab_liag_project,'Checked','off'); set(gui.menu.file_import_lab_bgr_std,'Checked','off'); -set(gui.menu.file_import_lab_bgr_org,'Checked','off'); set(gui.menu.file_import_lab_bgr_mat,'Checked','off'); +set(gui.menu.file_import_lab_bgr_mouse_cpmg,'Checked','off'); +set(gui.menu.file_import_lab_bgr_mouse_liftsingle,'Checked','off'); +set(gui.menu.file_import_lab_bgr_mouse_liftall,'Checked','off'); +set(gui.menu.file_import_lab_bgr_helios,'Checked','off'); set(gui.menu.file_import_lab_bam_tom,'Checked','off'); set(gui.menu.file_import_lab_ascii_T1,'Checked','off'); set(gui.menu.file_import_lab_ascii_T2,'Checked','off'); diff --git a/functions/interface/updateCPSTable.m b/functions/interface/updateCPSTable.m index 97c493e..2395526 100644 --- a/functions/interface/updateCPSTable.m +++ b/functions/interface/updateCPSTable.m @@ -23,8 +23,8 @@ function updateCPSTable(method) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updateCPSTableSize.m b/functions/interface/updateCPSTableSize.m index 6fc0045..8e0329f 100644 --- a/functions/interface/updateCPSTableSize.m +++ b/functions/interface/updateCPSTableSize.m @@ -23,8 +23,8 @@ function updateCPSTableSize(inc) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updateInfo.m b/functions/interface/updateInfo.m index 63dfc29..344bc19 100644 --- a/functions/interface/updateInfo.m +++ b/functions/interface/updateInfo.m @@ -23,8 +23,8 @@ function updateInfo(src,~) %#ok % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -65,11 +65,11 @@ function updateInfo(src,~) %#ok case 'T2' switch data.process.gatetype case 'raw' - info{end+1,1} = ['Echos  = ',... + info{end+1,1} = ['Echos = ',... sprintf('%d',length(nmrproc.t)),... ' (',data.process.gatetype,')','']; otherwise - info{end+1,1} = ['Gates  = ',... + info{end+1,1} = ['Gates = ',... sprintf('%d',length(nmrproc.t)),... ' (',data.process.gatetype,')','']; end @@ -78,12 +78,12 @@ function updateInfo(src,~) %#ok switch data.process.norm case 0 if max(nmrproc.s) < 1e-3 - info{end+1,1} = ['A_max  = ',... - sprintf('%5.4e',max(nmrproc.s)),... + info{end+1,1} = ['A_max = ',... + sprintf('%5.3e',max(nmrproc.s)),... '']; else - info{end+1,1} = ['A_max  = ',... - sprintf('%5.4f',max(nmrproc.s)),... + info{end+1,1} = ['A_max = ',... + sprintf('%5.3f',max(nmrproc.s)),... '']; end case 1 @@ -93,12 +93,12 @@ function updateInfo(src,~) %#ok '']; else info{end+1,1} = ['Normfac = ',... - sprintf('%5.4f',max(data.process.normfac)),... + sprintf('%5.3f',max(data.process.normfac)),... '']; end end - info{end+1,1} = ['noise  = ',sprintf('%4.3e',nmrproc.noise),'']; + info{end+1,1} = ['noise = ',sprintf('%4.2e',nmrproc.noise),'']; info{end+1,1} = ' '; % possible inversion results/statistics @@ -112,12 +112,12 @@ function updateInfo(src,~) %#ok switch nmrproc.T1T2 case 'T1' info{end+1,1} = ['E&infin = ',... - sprintf('%4.3e',sum(invstd.E0)),... - ' ∓ (',sprintf('%4.3e',ciE0),')','']; + sprintf('%4.2e',sum(invstd.E0)),... + ' ∓ (',sprintf('%4.2e',ciE0),')','']; case 'T2' info{end+1,1} = ['E0 = ',... - sprintf('%4.3e',sum(invstd.E0)),... - ' ∓ (',sprintf('%4.3e',ciE0),')','']; + sprintf('%4.2e',sum(invstd.E0)),... + ' ∓ (',sprintf('%4.2e',ciE0),')','']; end info{end+1,1} = ' '; if isfield(invstd,'chi2') @@ -126,9 +126,10 @@ function updateInfo(src,~) %#ok info{end+1,1} = ['',str,'']; end end - str = ['RMS = ',sprintf('%4.3e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; + str = ['RMS = ',sprintf('%4.2e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; info{end+1,1} = ['',str,'']; - if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 +% if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 + if nmrproc.noise ~= 0 info{end+1,1} = ['S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'']; end @@ -138,12 +139,12 @@ function updateInfo(src,~) %#ok switch nmrproc.T1T2 case 'T1' info{end+1,1} = ['E&infin = ',... - sprintf('%4.3e',sum(E0)),... - ' ∓ (',sprintf('%4.3e',ciE0s),')','']; + sprintf('%4.2e',sum(E0)),... + ' ∓ (',sprintf('%4.2e',ciE0s),')','']; case 'T2' info{end+1,1} = ['E0 = ',... - sprintf('%4.3e',sum(E0)),... - ' ∓ (',sprintf('%4.3e',ciE0s),')','']; + sprintf('%4.2e',sum(E0)),... + ' ∓ (',sprintf('%4.2e',ciE0s),')','']; end info{end+1,1} = ' '; if isfield(invstd,'chi2') @@ -152,10 +153,11 @@ function updateInfo(src,~) %#ok info{end+1,1} = ['',str,'']; end end - str = ['RMS = ',sprintf('%4.3e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; + str = ['RMS = ',sprintf('%4.2e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; info{end+1,1} = ['',str,'']; - if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 +% if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 + if nmrproc.noise ~= 0 info{end+1,1} = ['S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'']; end @@ -163,10 +165,10 @@ function updateInfo(src,~) %#ok switch nmrproc.T1T2 case 'T1' info{end+1,1} = ['E&infin = ',... - sprintf('%4.3e',sum(invstd.E0)),'']; + sprintf('%4.2e',sum(invstd.E0)),'']; case 'T2' info{end+1,1} = ['E0 = ',... - sprintf('%4.3e',sum(invstd.E0)),'']; + sprintf('%4.2e',sum(invstd.E0)),'']; end info{end+1,1} = ' '; if isfield(invstd,'chi2') @@ -175,15 +177,43 @@ function updateInfo(src,~) %#ok info{end+1,1} = ['',str,'']; end end - str = ['RMS = ',sprintf('%4.3e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; + str = ['RMS = ',sprintf('%4.2e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; info{end+1,1} = ['',str,'']; - if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 + % if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 + if nmrproc.noise ~= 0 info{end+1,1} = ['S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'']; end info{end+1,1} = ['&lambda = ',sprintf('%6.5f',invstd.lambda_out),'']; info{end+1,1} = ' '; + case {'MUMO'} + switch nmrproc.T1T2 + case 'T1' + info{end+1,1} = ['E&infin = ',... + sprintf('%4.2e',sum(invstd.E0)),... + ' ∓ (',sprintf('%4.2e',invstd.ciE0),')','']; + case 'T2' + info{end+1,1} = ['E0 = ',... + sprintf('%4.2e',sum(invstd.E0)),... + ' ∓ (',sprintf('%4.2e',invstd.ciE0),')','']; + end + info{end+1,1} = ' '; + + if isfield(invstd,'chi2') + if ~isnan(invstd.chi2) + str = ['&Chi2 = ',sprintf('%4.2f',invstd.chi2)]; + info{end+1,1} = ['',str,'']; + end + end + str = ['RMS = ',sprintf('%4.2e',invstd.rms),' (',sprintf('%4.2f',invstd.rms*100./sum(invstd.E0)),'%)']; + info{end+1,1} = ['',str,'']; + + % if strcmp(nmrproc.T1T2,'T2') && nmrproc.noise ~= 0 + if nmrproc.noise ~= 0 + info{end+1,1} = ['S/N = ',sprintf('%4d',floor(sum(invstd.E0)/nmrproc.noise)),'']; + end + info{end+1,1} = ' '; end end end @@ -232,9 +262,11 @@ function updateInfo(src,~) %#ok sprintf('%5.2f',rad2deg(a)),... '°']; end - info{end+1,1} = ['phase fit = ',... + if isfield(data.results.nmrraw,'phase') + info{end+1,1} = ['phase fit = ',... sprintf('%5.2f',rad2deg(data.results.nmrraw.phase)),... '°']; + end info{end+1,1} = ' '; end @@ -317,8 +349,8 @@ function updateInfo(src,~) %#ok ' ∓ (',sprintf('%5.4f',ciT(i)),')','']; %#ok<*AGROW> info{end+1,1} = ['E(',num2str(i),') = ',sprintf('%5.4f',E0(i)),... ' ∓ (',sprintf('%5.4f',ciE0(i)),')','']; + info{end+1,1} = ' '; end - info{end+1,1} = ' '; case {'LU','NNLS'} % info is a cell array @@ -352,6 +384,57 @@ function updateInfo(src,~) %#ok ') = ',sprintf('%5.2f',por*BVI*100),' [vol. %]']; info{end+1,1} = ['BVM = ',sprintf('%5.2f',por*BVM*100),' [vol. %]']; + case {'MUMO'} + + % info is a cell array + str = [invtype,' ',num2str(data.invstd.freeDT)]; + info{end+1,1} = str; + info{end+1,1} = ' '; + + % TLGM + info{end+1,1} = ['TLGM = ',sprintf('%5.4f',invstd.Tlgm),'']; + info{end+1,1} = ' '; + + % clay-bound water CBW < tcut ms + % irreducible water / capillary water BVI ccut - tcut ms + % movable water BVM > tcut ms + switch data.process.timescale + case 's' + ccut = data.param.CBWcutoff/1000; + tcut = data.param.BVIcutoff/1000; + case 'ms' + ccut = data.param.CBWcutoff; + tcut = data.param.BVIcutoff; + end + por = data.invstd.porosity; + CBW = abs(sum(invstd.T1T2f(invstd.T1T2me<=ccut))/sum(invstd.T1T2f)); + BVI = abs(sum(invstd.T1T2f(invstd.T1T2me>ccut & invstd.T1T2me<=tcut))/sum(invstd.T1T2f)); + BVM = abs(sum(invstd.T1T2f(invstd.T1T2me>tcut))/sum(invstd.T1T2f)); + info{end+1,1} = ['CBW(',sprintf('%2d',data.param.CBWcutoff),... + ') = ',sprintf('%5.2f',por*CBW*100),' [vol. %]']; + + info{end+1,1} = ['BVI(',sprintf('%2d',data.param.BVIcutoff),... + ') = ',sprintf('%5.2f',por*BVI*100),' [vol. %]']; + info{end+1,1} = ['BVM = ',sprintf('%5.2f',por*BVM*100),' [vol. %]']; + info{end+1,1} = ' '; + + % values for T, sigma and amplitude + T = invstd.T; ciT = invstd.ci(1:3:end); + S = invstd.S; ciS = invstd.ci(2:3:end); + E = invstd.E; ciE = invstd.ci(3:3:end); + % transform ciT because it is in log scale + tmpT = log(T)-ciT'; + ciT = T - exp(tmpT); + + for i = 1:length(T) + info{end+1,1} = ['T(',num2str(i),') = ',sprintf('%5.4f',T(i)),... + ' ∓ (',sprintf('%5.4f',ciT(i)),')','']; %#ok<*AGROW> + info{end+1,1} = ['S(',num2str(i),') = ',sprintf('%5.4f',S(i)),... + ' ∓ (',sprintf('%5.4f',ciS(i)),')','']; + info{end+1,1} = ['E(',num2str(i),') = ',sprintf('%5.4f',E(i)),... + ' ∓ (',sprintf('%5.4f',ciE(i)),')','']; + info{end+1,1} = ' '; + end end end end diff --git a/functions/interface/updateNMRsignals.m b/functions/interface/updateNMRsignals.m index e44dccb..c663ecd 100644 --- a/functions/interface/updateNMRsignals.m +++ b/functions/interface/updateNMRsignals.m @@ -16,6 +16,7 @@ % % Other m-files required: % addNoiseToSignal +% updatePlotsNMR % % Subfunctions: % none @@ -24,8 +25,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -34,21 +35,46 @@ fig = findobj('Tag','MOD'); data = getappdata(fig,'data'); +%% first check what is the noise type + +switch data.nmr.noisetype + case 'level' + noise = data.nmr.noise; + case 'SNR' + SNR = data.nmr.noise; + noise = 1./SNR; +end + %% only proceed if the noise is larger than 0 -if data.nmr.noise > 0 - % scale noise by porosity - noise = data.nmr.noise/data.nmr.porosity; - % add noise to NMR signals - [data.results.NMR.EiT1,~] = addNoiseToSignal(data.results.NMR.raw.EiT1,0,noise); - [data.results.NMR.EdT1,~] = addNoiseToSignal(data.results.NMR.raw.EdT1,0,noise); - [data.results.NMR.EiT2,~] = addNoiseToSignal(data.results.NMR.raw.EiT2,0,noise); - [data.results.NMR.EdT2,~] = addNoiseToSignal(data.results.NMR.raw.EdT2,0,noise); +if noise > 0 + switch data.nmr.noisetype + case 'level' + % scale noise by porosity + noise = noise/data.nmr.porosity; + % add noise to NMR signals + [data.results.NMR.EiT1,~] = addNoiseToSignal(data.results.NMR.raw.EiT1,0,noise); + [data.results.NMR.EdT1,~] = addNoiseToSignal(data.results.NMR.raw.EdT1,0,noise); + [data.results.NMR.EiT2,~] = addNoiseToSignal(data.results.NMR.raw.EiT2,0,noise); + [data.results.NMR.EdT2,~] = addNoiseToSignal(data.results.NMR.raw.EdT2,0,noise); + noiseM = noise*ones(size(data.results.NMR.EiT1,2),4); + case 'SNR' + SNR = data.nmr.noise; + noiseM(:,1) = data.results.NMR.EiT1(:,end)./SNR; + [data.results.NMR.EiT1,~] = addNoiseToSignal(data.results.NMR.raw.EiT1,0,noiseM(:,1)); + noiseM(:,2) = data.results.NMR.EdT1(:,end)./SNR; + [data.results.NMR.EdT1,~] = addNoiseToSignal(data.results.NMR.raw.EdT1,0,noiseM(:,2)); + noiseM(:,3) = data.results.NMR.EiT2(:,1)./SNR; + [data.results.NMR.EiT2,~] = addNoiseToSignal(data.results.NMR.raw.EiT2,0,noiseM(:,3)); + noiseM(:,4) = data.results.NMR.EdT2(:,1)./SNR; + [data.results.NMR.EdT2,~] = addNoiseToSignal(data.results.NMR.raw.EdT2,0,noiseM(:,4)); + end else % reset the NMR signals with the raw data (without noise) data.results.NMR.EiT1 = data.results.NMR.raw.EiT1; data.results.NMR.EdT1 = data.results.NMR.raw.EdT1; data.results.NMR.EiT2 = data.results.NMR.raw.EiT2; data.results.NMR.EdT2 = data.results.NMR.raw.EdT2; + noiseM = zeros(size(data.results.NMR.EiT1,2),4); end % scale NMR signals by porosity @@ -57,12 +83,14 @@ data.results.NMR.EiT2 = data.nmr.porosity.*data.results.NMR.EiT2; data.results.NMR.EdT2 = data.nmr.porosity.*data.results.NMR.EdT2; -% save the noise value -data.results.NMR.noise = data.nmr.noise; +% save the noise matrix values +data.results.NMR.noise = noiseM; % save the porosity value data.results.NMR.porosity = data.nmr.porosity; % update the GUI data setappdata(fig,'data',data); +% update the NMR plot window +updatePlotsNMR; end diff --git a/functions/interface/updatePlotsCPS.m b/functions/interface/updatePlotsCPS.m index e855dca..80625b1 100644 --- a/functions/interface/updatePlotsCPS.m +++ b/functions/interface/updatePlotsCPS.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updatePlotsDistribution.m b/functions/interface/updatePlotsDistribution.m index 0f0f802..18f1c1c 100644 --- a/functions/interface/updatePlotsDistribution.m +++ b/functions/interface/updatePlotsDistribution.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -78,7 +78,8 @@ case 'free' mymark = {'o-','+-','s-','d-','x-'}; - mycols = [22 140 75;22 87 140;140 22 87;140 75 22;64 64 64]./255; + mycols = [0.8941 0.1020 0.1098;0.3020 0.6863 0.2902; + 0.2157 0.4941 0.7216;0.5961 0.3059 0.6392;0.6510 0.3373 0.1569]; switch nmrproc.T1T2 case 'T1' T = invstd.T1; @@ -102,7 +103,7 @@ % grid grid(ax,'on'); - case {'LU','NNLS'} + case {'LU'} % scale distribution by porosity F = invstd.T1T2f; if sum(F)>0 @@ -145,7 +146,211 @@ % y-limits set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); % y-label - set(get(ax,'YLabel'),'String',ylab2); + set(get(ax,'YLabel'),'String',ylab2); + end + + % x-limits + ticks = round(log10(min(invstd.T1T2me)) :1: log10(max(invstd.T1T2me))); + set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); + % x-label + set(get(ax,'XLabel'),'String',xlstring); + % grid + grid(ax,'on'); + + case {'NNLS'} + % scale distribution by porosity + F = invstd.T1T2f; + if sum(F)>0 + % apply same scaling to the uncertainty patch + if isfield(data.results.invstd,'uncert') + f_min = data.results.invstd.uncert.interp_f_min; + f_max = data.results.invstd.uncert.interp_f_max; + f_min = (data.invstd.porosity*100).*f_min./sum(F); + f_max = (data.invstd.porosity*100).*f_max./sum(F); + end + F = (data.invstd.porosity*100).*F./sum(F); + + ylims = [0 max(F)*1.05]; + else + ylims = [-1 1]; + end + if data.invstd.porosity == 1 + ylab1 = 'amplitudes [-]'; + ylab2 = 'cumulative amplitudes [-]'; + else + ylab1 = 'water content [vol. %]'; + ylab2 = 'cumulative water content [vol. %]'; + end + % F = data.invstd.porosity.*F./trapz(T,F); + + switch data.info.RTDflag + case 'freq' + if isfield(data.results.invstd,'uncert') + % plot uncertainty + for i = 1:size(invstd.uncert.interp_f,1) + plot(invstd.T1T2me,(data.invstd.porosity*100).*invstd.uncert.interp_f(i,:)./sum(invstd.T1T2f),... + '-','Color',[0.5 0.5 0.5],'LineWidth',1,'Parent',ax); + end +% verts = [invstd.T1T2me f_min'; flipud(invstd.T1T2me) flipud(f_max')]; +% faces = 1:1:size(verts,1); +% patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... +% 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); + % adjust y-limits + ylims(2) = max([ylims(2) max(f_max)*1.05]); + end + + plot(invstd.T1T2me,F,'-','Color',col.FIT,... + 'LineWidth',2,'Parent',ax); + % find approx. TLGM amplitude + amp = findApproxTlgmAmplitude(invstd.T1T2me,F,invstd.Tlgm); + stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... + 'LineWidth',2,'Tag','TLGM','Parent',ax); + + % y-limits + set(ax,'YScale','lin','YLim',ylims); + % y-label + set(get(ax,'YLabel'),'String',ylab1); + + case 'cum' + if isfield(data.results.invstd,'uncert') + verts = [invstd.T1T2me cumsum(F)-f_min'; flipud(invstd.T1T2me) flipud(cumsum(F)+f_max')]; + faces = 1:1:size(verts,1); + patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... + 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); + end + plot(invstd.T1T2me,cumsum(F),'-','Color',col.FIT,... + 'LineWidth',2,'Parent',ax); + % find approx. TLGM amplitude + amp = findApproxTlgmAmplitude(invstd.T1T2me,cumsum(F),invstd.Tlgm); + stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... + 'LineWidth',2,'Tag','TLGM','Parent',ax); + + % y-limits + set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); + % y-label + set(get(ax,'YLabel'),'String',ylab2); + end + + % x-limits + ticks = round(log10(min(invstd.T1T2me)) :1: log10(max(invstd.T1T2me))); + set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); + % x-label + set(get(ax,'XLabel'),'String',xlstring); + % grid + grid(ax,'on'); + + case {'MUMO'} + % single distributions for different T, sigma and amplitude + dist = zeros(length(invstd.x)/3,numel(invstd.T1T2me)); + for i = 1:length(invstd.x)/3 + mu = invstd.T(i); + sigma = invstd.S(i); + amp = invstd.E(i); + + tmp = 1./( sigma*sqrt(2*pi)).*exp(-((log(invstd.T1T2me) - log(mu))/ sqrt(2)/sigma).^2); + + % scale to amplitude + dist(i,:) = (tmp/sum(tmp)) * amp; + end + + % scale distribution by porosity + F = invstd.T1T2f; + if sum(F)>0 + for i = 1:length(invstd.x)/3 + dist(i,:) = (data.invstd.porosity*100).*dist(i,:)./sum(F); + end + % apply same scaling to the uncertainty patch + if isfield(data.results.invstd,'uncert') + f_min = data.results.invstd.uncert.interp_f_min; + f_max = data.results.invstd.uncert.interp_f_max; + f_min = (data.invstd.porosity*100).*f_min./sum(F); + f_max = (data.invstd.porosity*100).*f_max./sum(F); + end + F = (data.invstd.porosity*100).*F./sum(F); + + ylims = [0 max(F)*1.05]; + else + ylims = [-1 1]; + end + if data.invstd.porosity == 1 + ylab1 = 'amplitudes [-]'; + ylab2 = 'cumulative amplitudes [-]'; + else + ylab1 = 'water content [vol. %]'; + ylab2 = 'cumulative water content [vol. %]'; + end + % F = data.invstd.porosity.*F./trapz(T,F); + + mycols = [0.2157 0.4941 0.7216;0.3020 0.6863 0.2902; + 0.5961 0.3059 0.6392;0.6510 0.3373 0.1569;0.8941 0.1020 0.1098]; + + switch data.info.RTDflag + case 'freq' + if isfield(data.results.invstd,'uncert') + % plot uncertainty + % lines + % for i = 1:size(invstd.TDIST,1) + % plot(invstd.T1T2me,(data.invstd.porosity*100).*invstd.TDIST(i,:)./sum(invstd.T1T2f),... + % '-','Color',[0.5 0.5 0.5],'LineWidth',1,'Parent',ax); + % end + % patch +% TDIST = invstd.TDIST; +% for i = 1:size(invstd.TDIST,1) +% TDIST(i,:) = (data.invstd.porosity*100).*invstd.TDIST(i,:)./sum(invstd.T1T2f); +% end +% TDISTmin = min(TDIST); +% TDISTmax = max(TDIST); +% verts = [nmrproc.t(nmrproc.t>0) s_min; flipud(nmrproc.t(nmrproc.t>0)) flipud(s_max)]; +% faces = 1:1:size(verts,1); +% + verts = [invstd.T1T2me f_min'; flipud(invstd.T1T2me) flipud(f_max')]; + faces = 1:1:size(verts,1); + patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... + 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); + % adjust y-limits + ylims(2) = max([ylims(2) max(f_max)*1.05]); + end + + % plot total RTD + plot(invstd.T1T2me,F,'-','Color',col.FIT,... + 'LineWidth',2,'Parent',ax); + % plot individual RTDs + for i = 1:length(invstd.x)/3 + plot(invstd.T1T2me,dist(i,:),'--','Color',mycols(i,:),... + 'LineWidth',2,'Parent',ax); + end + % find approx. TLGM amplitude + amp = findApproxTlgmAmplitude(invstd.T1T2me,F,invstd.Tlgm); + stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... + 'LineWidth',2,'Tag','TLGM','Parent',ax); + + % y-limits + set(ax,'YScale','lin','YLim',ylims); + % y-label + set(get(ax,'YLabel'),'String',ylab1); + + case 'cum' + if isfield(data.results.invstd,'uncert') + verts = [invstd.T1T2me cumsum(F)-f_min'; flipud(invstd.T1T2me) flipud(cumsum(F)+f_max')]; + faces = 1:1:size(verts,1); + patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... + 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); + end + plot(invstd.T1T2me,cumsum(F),'-','Color',col.FIT,... + 'LineWidth',2,'Parent',ax); + for i = 1:length(invstd.x)/3 + plot(invstd.T1T2me,cumsum(dist(i,:)),'--','Color',mycols(i,:),... + 'LineWidth',2,'Parent',ax); + end + % find approx. TLGM amplitude + amp = findApproxTlgmAmplitude(invstd.T1T2me,cumsum(F),invstd.Tlgm); + stem(invstd.Tlgm,amp,'x-','Color',col.axisL,... + 'LineWidth',2,'Tag','TLGM','Parent',ax); + + % y-limits + set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); + % y-label + set(get(ax,'YLabel'),'String',ylab2); end % x-limits @@ -198,7 +403,8 @@ case 'free' mymark = {'o-','+-','s-','d-','x-'}; - mycols = [22 140 75;22 87 140;140 22 87;140 75 22;64 64 64]./255; + mycols = [0.8941 0.1020 0.1098;0.3020 0.6863 0.2902; + 0.2157 0.4941 0.7216;0.5961 0.3059 0.6392;0.6510 0.3373 0.1569]; switch nmrproc.T1T2 case 'T1' T = invstd.T1; @@ -233,7 +439,7 @@ 'LineWidth',2,'Parent',ax); % find approx. RLGM amplitude amp = findApproxTlgmAmplitude(requiv,F,Rlgm); - stem(Rlgm,amp,'x-','Color',[0.3 0.3 0.3],'LineWidth',2,'Tag','TLGM','Parent',ax); + stem(Rlgm,amp,'x-','Color',col.axisL,'LineWidth',2,'Tag','TLGM','Parent',ax); % y-limits set(ax,'YScale','lin','YLim',ylims); @@ -245,7 +451,67 @@ 'LineWidth',2,'Parent',ax); % find approx. RLGM amplitude amp = findApproxTlgmAmplitude(requiv,cumsum(F),Rlgm); - stem(Rlgm,amp,'x-','Color',[0.3 0.3 0.3],'LineWidth',2,'Tag','TLGM','Parent',ax); + stem(Rlgm,amp,'x-','Color',col.axisL,'LineWidth',2,'Tag','TLGM','Parent',ax); + + % y-limits + set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); + % y-label + set(get(ax,'YLabel'),'String',ylab2); + end + + % x-limits + ticks = floor(log10(min(requiv))) :1: ceil(log10(max(requiv))); + % set(ax,'XScale','log','XLim',[10^(ticks(1)) 10^(ticks(end))],'XTick',10.^ticks); + set(ax,'XScale','log','XLim',[min(requiv) max(requiv)],'XTick',10.^ticks); + % x-label + set(get(ax,'XLabel'),'String',xlstring); + % grid + grid(ax,'on'); + + case {'MUMO'} + % very basic RTD to PSD conversion + requiv = invstd.T1T2me.*rho.*a; + Rlgm = invstd.Tlgm.*rho.*a; + + switch data.info.PSDflag + case 'freq' + if isfield(data.results.invstd,'uncert') + verts = [requiv f_min'; flipud(requiv) flipud(f_max')]; + patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... + 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); + % adjust y-limits + ylims(2) = max([ylims(2) max(f_max)*1.05]); + end + plot(requiv,F,'-','Color',col.FIT,... + 'LineWidth',2,'Parent',ax); + for i = 1:length(invstd.x)/3 + plot(requiv,dist(i,:),'--','Color',mycols(i,:),... + 'LineWidth',2,'Parent',ax); + end + % find approx. RLGM amplitude + amp = findApproxTlgmAmplitude(requiv,F,Rlgm); + stem(Rlgm,amp,'x-','Color',col.axisL,'LineWidth',2,'Tag','TLGM','Parent',ax); + + % y-limits + set(ax,'YScale','lin','YLim',ylims); + % y-label + set(get(ax,'YLabel'),'String',ylab1); + + case 'cum' + if isfield(data.results.invstd,'uncert') + verts = [requiv cumsum(F)-f_min'; flipud(requiv) flipud(cumsum(F)+f_max')]; + patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... + 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); + end + plot(requiv,cumsum(F),'-','Color',col.FIT,... + 'LineWidth',2,'Parent',ax); + for i = 1:length(invstd.x)/3 + plot(requiv,cumsum(dist(i,:)),'--','Color',mycols(i,:),... + 'LineWidth',2,'Parent',ax); + end + % find approx. RLGM amplitude + amp = findApproxTlgmAmplitude(requiv,cumsum(F),Rlgm); + stem(Rlgm,amp,'x-','Color',col.axisL,'LineWidth',2,'Tag','TLGM','Parent',ax); % y-limits set(ax,'YScale','lin','YLim',[0 sum(F)*1.05]); diff --git a/functions/interface/updatePlotsDistributionInfo.m b/functions/interface/updatePlotsDistributionInfo.m index 199f4e8..2e843b2 100644 --- a/functions/interface/updatePlotsDistributionInfo.m +++ b/functions/interface/updatePlotsDistributionInfo.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updatePlotsGeometryType.m b/functions/interface/updatePlotsGeometryType.m index 3782325..a950982 100644 --- a/functions/interface/updatePlotsGeometryType.m +++ b/functions/interface/updatePlotsGeometryType.m @@ -23,8 +23,8 @@ function updatePlotsGeometryType(ax) % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updatePlotsJointInversion.m b/functions/interface/updatePlotsJointInversion.m index d1ef415..dca69df 100644 --- a/functions/interface/updatePlotsJointInversion.m +++ b/functions/interface/updatePlotsJointInversion.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updatePlotsLcurve.m b/functions/interface/updatePlotsLcurve.m index 7a7d18c..eb3847c 100644 --- a/functions/interface/updatePlotsLcurve.m +++ b/functions/interface/updatePlotsLcurve.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updatePlotsNMR.m b/functions/interface/updatePlotsNMR.m index 89ebbe9..a06ca0c 100644 --- a/functions/interface/updatePlotsNMR.m +++ b/functions/interface/updatePlotsNMR.m @@ -23,8 +23,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updatePlotsPSD.m b/functions/interface/updatePlotsPSD.m index acb4eec..3c71417 100644 --- a/functions/interface/updatePlotsPSD.m +++ b/functions/interface/updatePlotsPSD.m @@ -25,8 +25,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updatePlotsSignal.m b/functions/interface/updatePlotsSignal.m index 34f30e1..aa08f3d 100644 --- a/functions/interface/updatePlotsSignal.m +++ b/functions/interface/updatePlotsSignal.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -121,8 +121,10 @@ line(xlims,[0 0],'LineStyle','--','LineWidth',1,'Color','k','Parent',axI); imag_mean = mean(imag(nmrraw.s)); imag_std = std(imag(nmrraw.s)); - yticks = linspace(min(imag(nmrraw.s)),max(imag(nmrraw.s)),3); - set(axI,'XTickLabel','','YTick',yticks,'YTickLabelMode','auto'); +% yticks = linspace(min(imag(nmrraw.s)),max(imag(nmrraw.s)),3); + yticks = [imag_mean-imag_std*2 0 imag_mean+imag_std*2]; + ylim = [imag_mean-imag_std*3 imag_mean+imag_std*3]; + set(axI,'XTickLabel','','YLim',ylim,'YTick',yticks,'YTickLabelMode','auto'); switch loglinx case 'x-axis -> lin' % log axes set(axI,'XScale','log','XLim',xlims); @@ -144,16 +146,47 @@ hold(axE,'on'); % data - plot(nmrproc.t,nmrproc.s,'o','Color',col.RE,'LineWidth',1,'Parent',ax); - if isfield(data.results,'invstd') - plot(invstd.fit_t,invstd.fit_s,'Color',col.FIT,'LineWidth',2,'Parent',ax); - if nmrproc.noise > 0 - plot(nmrproc.t,invstd.residual./nmrproc.e,'Color',col.IM,... - 'LineWidth',1,'Parent',axE); - else - plot(nmrproc.t,invstd.residual,'Color',col.IM,... - 'LineWidth',1,'Parent',axE); - end + switch data.invstd.invtype + case {'MUMO','NNLS'} + if isfield(data.results,'invstd') && isfield(data.results.invstd,'uncert') + % uncertainty patch created from min max of uncertainty + % data + s_min = data.results.invstd.uncert.interp_s_min; + s_max = data.results.invstd.uncert.interp_s_max; + t = data.results.invstd.uncert.interp_t; + verts = [t(t>0) s_min(t>0); flipud(t(t>0)) flipud(s_max(t>0))]; + faces = 1:1:size(verts,1); + patch('Faces',faces,'Vertices',verts,'FaceColor',[0.64 0.64 0.64],... + 'FaceAlpha',0.75,'EdgeColor','none','Parent',ax); + end + + if isfield(data.results,'invstd') + plot(nmrproc.t,nmrproc.s,'-','Color',col.RE,'LineWidth',1,'Parent',ax); + plot(invstd.fit_t,invstd.fit_s,'Color',col.FIT,'LineWidth',2,'Parent',ax); + if nmrproc.noise > 0 + plot(nmrproc.t,invstd.residual./nmrproc.e,'Color',col.IM,... + 'LineWidth',1,'Parent',axE); + else + plot(nmrproc.t,invstd.residual,'Color',col.IM,... + 'LineWidth',1,'Parent',axE); + end + else + plot(nmrproc.t,nmrproc.s,'o','Color',col.RE,'LineWidth',1,'Parent',ax); + end + otherwise + if isfield(data.results,'invstd') + plot(nmrproc.t,nmrproc.s,'-','Color',col.RE,'LineWidth',1,'Parent',ax); + plot(invstd.fit_t,invstd.fit_s,'Color',col.FIT,'LineWidth',2,'Parent',ax); + if nmrproc.noise > 0 + plot(nmrproc.t,invstd.residual./nmrproc.e,'Color',col.IM,... + 'LineWidth',1,'Parent',axE); + else + plot(nmrproc.t,invstd.residual,'Color',col.IM,... + 'LineWidth',1,'Parent',axE); + end + else + plot(nmrproc.t,nmrproc.s,'o','Color',col.RE,'LineWidth',1,'Parent',ax); + end end % limits & ticks @@ -199,10 +232,10 @@ switch logliny case 'y-axis -> lin' % log axes ticks = floor(log10(ymin))-1 :1: ceil(log10(ymax)); - set(ax,'YScale','log','YLim',[10^(ticks(1)) ymax*1.05],... + set(ax,'YScale','log','YLim',[10^(ticks(1)) ymax*1.1],... 'YTick',10.^ticks); case 'y-axis -> log' % lin axes - set(ax,'YScale','lin','YLim',[ymin ymax*1.05],... + set(ax,'YScale','lin','YLim',[ymin ymax*1.1],... 'YTickMode','auto'); end end @@ -221,7 +254,15 @@ % legend if isfield(data.results,'invstd') - lgdstr = {'signal','fit'}; + if isfield(data.results,'invstd') && isfield(data.results.invstd,'uncert') + lgdstr = {'uncert','signal','fit'}; + else + lgdstr = {'signal','fit'}; + end +% switch data.invstd.invtype +% case {'MUMO','NNLS'} +% otherwise +% end switch nmrproc.T1T2 case 'T1' lgh = legend(ax,lgdstr,'Location','NorthWest',... diff --git a/functions/interface/updateStatusInformation.m b/functions/interface/updateStatusInformation.m index 6e206fc..d9cf38b 100644 --- a/functions/interface/updateStatusInformation.m +++ b/functions/interface/updateStatusInformation.m @@ -23,8 +23,8 @@ function updateStatusInformation(fig) % none % % See also: NUCLEUSinv, NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/interface/updateToolTips.m b/functions/interface/updateToolTips.m index 733a2de..783ddd6 100644 --- a/functions/interface/updateToolTips.m +++ b/functions/interface/updateToolTips.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -44,8 +44,9 @@ 'Available options:
    ',... 'Mono exp. Mono-exponential fitting.
    ',... 'Several free exp. (2-5) Multi-exponential fitting with up to 5 free relaxation times.
    ',... - 'Multi exp. (LSQ) Multi-exponential fitting with Optimization Toolbox.
    ',... - 'Multi exp. (LU decomp.) Multi-exponential fitting using a LU decomposition and Matlab''s "\"-operator.

    ',... + 'Multi exp. (LSQ) Multi-exponential fitting using the Optimization Toolbox.
    ',... + 'Multi exp. (LU decomp.) Multi-exponential fitting using a LU decomposition and Matlab''s "\"-operator.
    ',... + 'Multi modal Multi modal fitting using the Optimization Toolbox.

    ',... 'Depending on the chosen method there are additional options available.

    ',... 'Default value:
    ',... 'Multi exp. (LSQ)
    ']; @@ -64,7 +65,9 @@ 'L-curve Perform the L-curve test to find optimal regularization parameter lambda.
    ',... 'Multi exp. (LU decomp.):
    ',... 'Manual Manual regularization.
    ',... - 'Automatic Automatic regularization.

    ',... + 'Automatic Automatic regularization.
    ',... + 'Multi modal:
    ',... + '1-4 choose how many modes to use.

    ',... 'Default value:
    ',... 'Manual
    ']; case 'lsqnonneg' @@ -73,7 +76,8 @@ 'Mono exp. Mono-exponential fitting.
    ',... 'Several free exp. (2-5) Multi-exponential fitting with up to 5 free relaxation times.
    ',... 'Multi exp. (LSQ) Multi-exponential fitting with Non Negative Least Squares (LSQNONNEG).
    ',... - 'Multi exp. (LU decomp.) Multi-exponential fitting using a LU decomposition and Matlab''s "\"-operator.

    ',... + 'Multi exp. (LU decomp.) Multi-exponential fitting using a LU decomposition and Matlab''s "\"-operator.
    ',... + 'Multi modal Multi modal fitting using fminsearchbnd.

    ',... 'Depending on the chosen method there are additional options available.

    ',... 'Default value:
    ',... 'Multi exp. (LSQ)
    ']; @@ -92,7 +96,9 @@ 'L-curve Perform the L-curve test to find optimal regularization parameter lambda.
    ',... 'Multi exp. (LU decomp.):
    ',... 'Manual Manual regularization.
    ',... - 'Automatic Automatic regularization.

    ',... + 'Automatic Automatic regularization.
    ',... + 'Multi modal:
    ',... + '1-4 choose how many modes to use.

    ',... 'Default value:
    ',... 'Manual
    ']; end diff --git a/functions/interface/useSignalAsCalibration.m b/functions/interface/useSignalAsCalibration.m index d44e4a2..c536472 100644 --- a/functions/interface/useSignalAsCalibration.m +++ b/functions/interface/useSignalAsCalibration.m @@ -23,8 +23,8 @@ function useSignalAsCalibration(id) % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/applyGatesToSignal.m b/functions/inversion/applyGatesToSignal.m index fc637ad..b5b4389 100644 --- a/functions/inversion/applyGatesToSignal.m +++ b/functions/inversion/applyGatesToSignal.m @@ -32,8 +32,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/applyRegularization.m b/functions/inversion/applyRegularization.m index 8a52989..eedea83 100644 --- a/functions/inversion/applyRegularization.m +++ b/functions/inversion/applyRegularization.m @@ -37,8 +37,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/createKernelMatrix.m b/functions/inversion/createKernelMatrix.m index 648b586..a77addc 100644 --- a/functions/inversion/createKernelMatrix.m +++ b/functions/inversion/createKernelMatrix.m @@ -1,4 +1,4 @@ -function K = createKernelMatrix(t,T,Tbulk,Tflag,T1IRfac) +function K = createKernelMatrix(t,T,Tbulk,Tdiff,Tflag,T1IRfac) %createKernelMatrix creates a Kernel matrix from signal time vector "t" %and relaxation time vector "T" % @@ -9,6 +9,7 @@ % t - signal time vector % T - relaxation times vector % Tbulk - bulk relaxation time +% Tdiff - diffusion relaxation time % Tflag - 'T1' or 'T2' % T1IRfac - 1 or 2 (Sat. or Inv. Recovery) % @@ -16,7 +17,7 @@ % K - Kernel matrix size(length(t),length(T)) % % Example: -% K = createKernelMatrix(t,T,2,'T1') +% K = createKernelMatrix(t,T,2,3,'T1',1) % % Other m-files required: % none @@ -28,8 +29,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -42,9 +43,9 @@ %% calculate K switch Tflag case 'T1' - K = 1-T1IRfac.*(exp(-tr./Tr).*exp(-tr./Tbulk)); + K = 1-T1IRfac.*(exp(-tr./Tr).*exp(-tr./Tbulk).*exp(-tr./Tdiff)); case 'T2' - K = exp(-tr./Tr).*exp(-tr./Tbulk); + K = exp(-tr./Tr).*exp(-tr./Tbulk).*exp(-tr./Tdiff); end return diff --git a/functions/inversion/estimateJacobian.m b/functions/inversion/estimateJacobian.m new file mode 100644 index 0000000..b418456 --- /dev/null +++ b/functions/inversion/estimateJacobian.m @@ -0,0 +1,79 @@ +function J = estimateJacobian(f,x) +%estimateJacobian numerically estimates (in a very simple manner) a +%Jacobian at point x for a given function f +% +% Syntax: +% estimateJacobian +% +% Inputs: +% f - function handle +% x - point on function f +% +% Outputs: +% J - Jacobian +% +% Example: +% estimateJacobian(@(x)fcn_fitMultiModal(x,iparam),x); +% +% Other m-files required: +% none +% +% Subfunctions: +% none +% +% MAT-files required: +% none +% +% See also: NUCLEUSinv +% Author: see AUTHORS.md +% email: see AUTHORS.md +% License: MIT License (at end) + +%------------- BEGIN CODE -------------- + +% define increment +delta = 1e-7*sqrt(norm(x)); +% evaluate function at point x +y = feval(f,x); +% get dimensions of J +n = length(y); +m = length(x); +% initialize J +J = zeros(n,m); +% loop over paramters +for i = 1:m + dx = zeros(1,m); + dx(i) = delta/2; + % evaluate single parameters at x+dx and x-dx + % and divide the differenece by the increment + col = (feval(f,x+dx)-feval(f,x-dx))/delta; + % save result + J(:,i) = col; +end + +return + +%------------- END OF CODE -------------- + +%% License: +% MIT License +% +% Copyright (c) 2022 Thomas Hiller +% +% Permission is hereby granted, free of charge, to any person obtaining a copy +% of this software and associated documentation files (the "Software"), to deal +% in the Software without restriction, including without limitation the rights +% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the Software is +% furnished to do so, subject to the following conditions: +% +% The above copyright notice and this permission notice shall be included in all +% copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +% SOFTWARE. \ No newline at end of file diff --git a/functions/inversion/estimateUncertainty.m b/functions/inversion/estimateUncertainty.m new file mode 100644 index 0000000..f9206d3 --- /dev/null +++ b/functions/inversion/estimateUncertainty.m @@ -0,0 +1,516 @@ +function [invstd,uncert] = estimateUncertainty(invtype,invstd,iparam,parameter) +%estimateUncertainty calculates pseudo uncertainty estimates for multi +%modal and LSQ inversion results +% +% Syntax: +% estimateUncertainty(invtype,invstd,iparam,parameter) +% +% Inputs: +% invtype - string indicating the inversion method of the optimal +% fit ('NNLS' or 'MUMO') +% invstd - struct holding inversion results of the optimal fit +% iparam - struct holding original inversion settings +% parameter - struct that holds settings: +% uncertMethod : which calculation method to use for +% 'MUMO' the options are 'thresh' and 'ci' for +% 'NNLS' the options are 'RTD_var', 'Lambda', +% 'RMS_bound' and 'RMS_free' +% uncertThresh : threshold for uncertainty search range +% uncertChi2 : stop criteria for the chi2 deviation +% uncertN : number of models to calculate +% uncertMax : total number of unsuccessful attempts +% after which the calculation is stopped +% +% Outputs: +% invstd - same as input struct +% uncert - uncertainty data +% +% Example: +% [invstd] = estimateUncertainty('MUMO',invstd,iparam,uparam) +% +% Other m-files required: +% createKernelMatrix +% displayStatusText +% fitDataLSQ +% getFitErrors +% +% Subfunctions: +% none +% +% MAT-files required: +% none +% +% See also: +% Author: see AUTHORS.md +% email: see AUTHORS.md +% License: MIT License (at end) + +%------------- BEGIN CODE -------------- + +%% get GUI handle and data +fig = findobj('Tag','INV'); +if ~isempty(fig) + gui = getappdata(fig,'gui'); +else + % this routine will sill call 'displayStatusText' but then the output + % is displayed at the command line + gui = 0; +end + +% get the main parameters +uncertMethod = parameter.uncertMethod; +uncertChi2 = parameter.uncertChi2; +uncertThresh = parameter.uncertThresh; +uncertN = parameter.uncertN; +uncertMax = parameter.uncertMax; + +% original data that was fitted +time = parameter.time; +signal = parameter.signal; + +% kernel matrices for pure (single) E0 estimation and a second one +% that extends the original time vector to "0" -> needed for nicer plots of +% uncertainty towards shorter times +switch iparam.T1T2 + case 'T1' + K0 = createKernelMatrix(10*time(end),invstd.T1T2me',... + iparam.Tb,iparam.Td,'T1',iparam.T1IRfac); + + time0 = [time' 2*time(end) 5*time(end) 10*time(end)]; + K0f = createKernelMatrix(time0,invstd.T1T2me',... + iparam.Tb,iparam.Td,'T1',iparam.T1IRfac); + case 'T2' + K0 = createKernelMatrix(0,invstd.T1T2me',iparam.Tb,... + iparam.Td,'T2',iparam.T1IRfac); + + time0 = [0 1e-6 time(1)/10 time(1)/5 time(1)/3 time(1)/2 time']; + K0f = createKernelMatrix(time0,invstd.T1T2me',iparam.Tb,... + iparam.Td,'T2',iparam.T1IRfac); +end + +% switch depending on inversion method +switch invtype + case 'MUMO' + % data needed from the optimal fit + T = invstd.T; + S = invstd.S; + E = invstd.E; + x = invstd.x; + lb = invstd.lb; + ub = invstd.ub; + ci = invstd.ci; + + % kernel for the original fit needed for comparison of the uncertainty models + K = createKernelMatrix(time,invstd.T1T2me',iparam.Tb,iparam.Td,... + iparam.T1T2,iparam.T1IRfac); + + % counter + count = 0; + countm = 0; + + % initialize variables + TDIST = zeros(uncertN,numel(invstd.T1T2me)); + SINTERP = zeros(numel(time0),uncertN); + E0INTERP = zeros(uncertN,1); + % calculate uncertainty models + while count < uncertN + switch uncertMethod + case 'thresh' + % randomly vary all parameters +- thresh + a = 1-uncertThresh; + b = 1+uncertThresh; + rr = (b-a).*rand(1,length(ci)) + a; + Ti = log(T).*rr(1:3:end); % do it on log-scale + Si = S.*rr(2:3:end); + Ei = E.*rr(3:3:end); + + xi = zeros(size(x)); + xi(1:3:end) = Ti; + xi(2:3:end) = Si; + xi(3:3:end) = Ei; + case 'ci' + % randomly vary parameters within confidence interval + rr = 2.*rand(1,length(ci))-1; + xi = zeros(size(x)); + xi(1:3:end) = log(T); + xi(2:3:end) = S; + xi(3:3:end) = E; + xi = xi+ci'.*rr; + end + + % adjust for bounds if necessary + xi(xiub) = lb(xi>ub); + + % temporary values + Ti = exp(xi(1:3:end)); % transform back to lin-scale + Si = xi(2:3:end); + Ei = xi(3:3:end); + + % create a temporary distribution with the new parameters + TdistI = 0; + for i = 1:numel(T) + tmp = 1./( Si(i)*sqrt(2*pi)).*exp(-((log(invstd.T1T2me') - log(Ti(i)))/ sqrt(2)/Si(i)).^2); + % scale to amplitude + if sum(tmp)>0 + tmp = (tmp/sum(tmp)) * Ei(i); + end + % add the tmp per mu to Tdist + TdistI = TdistI + tmp; + end + % calculate temporary signal(s) + s_interp = K*TdistI'; + s0_interp = K0f*TdistI'; + + % get residuals and error measures + if isfield(iparam,'W') + % when signal gating was used the error estimates need to be adjusted + outI = getFitErrors(signal,s_interp,iparam.noise,iparam.W); + else + outI = getFitErrors(signal,s_interp,iparam.noise); + end + + % check if the temporary chi2 is within the desired limit + if abs(1-outI.chi2/invstd.chi2) <= uncertChi2 + % if YES then keep it + count = count + 1; + % save RTD + TDIST(count,:) = TdistI; + % save signal + SINTERP(:,count) = s0_interp; + % save E0 + E0INTERP(count,1) = K0*TdistI'; + % status bar info + infostring = ['Calculating uncertainty models: ',... + num2str(count),' / ',num2str(uncertN)]; + displayStatusText(gui,infostring); + % reset max counter + countm = 0; + else + % as long as we did not find a model keep counting + if count < 1 + countm = countm + 1; + infostring = ['Trying to find uncertainty model: ',... + num2str(countm),' / ',num2str(uncertMax)]; + displayStatusText(gui,infostring); + end + end + % after to many unsuccessful attempts STOP + if countm > uncertMax + infostring = ['No uncertainty model found: ',... + num2str(countm),' / ',num2str(uncertMax)]; + displayStatusText(gui,infostring); + break; + end + end + + % output data + % simple E0 confidence interval + invstd.ciE0 = 2*std(E0INTERP); + + % uncertainty calculation results + uncert.interp_t = time0(:); + uncert.interp_E0 = E0INTERP; + uncert.interp_f = TDIST; + uncert.interp_s = SINTERP; + + % uncertainty patch for fitted signal + uncert.interp_s_min = min(SINTERP,[],2); + uncert.interp_s_max = max(SINTERP,[],2); + + % uncertainty patch for fitted RTD + uncert.interp_f_min = min(TDIST); + uncert.interp_f_max = max(TDIST); + + invstd.uncert = uncert; + + case 'NNLS' + + % 'RTD_var' | 'Lambda' | 'RMS_bound' | 'RMS_free' + % uncertMethod = 'RMS_bound'; + + switch uncertMethod + case 'RTD_var' + % find uncertainty models by varying the optimal RTD bins + % individually + + % uncertN = 5; + % uncertThresh = 0.1; + % uncertChi2 = 0.05; + f_final = invstd.T1T2f; + + % initialize variables + % NOTE: we save 'uncertN' models for each RTD bin + TDIST = zeros(uncertN*numel(invstd.T1T2me),numel(invstd.T1T2me)); + SINTERP = zeros(numel(time0),uncertN*numel(invstd.T1T2me)); + E0INTERP = zeros(uncertN*numel(invstd.T1T2me),1); + % loop over all RTD bins + for i1 = 1:numel(f_final) + count = 0; + while count < uncertN + % start RTD is always the optimal one + x0 = f_final; + % global bounds + lb = zeros(size(x0)); + ub = max(f_final).*3.*ones(size(x0)); + % now draw a random value for the current RTD bin + a = 1-uncertThresh; + b = 1+uncertThresh; + rr = (b-a).*rand(1,1) + a; + % adjust the initial model and bounds accordingly + x0(i1) = f_final(i1)*rr; + lb(i1) = x0(i1); + ub(i1) = x0(i1); + + % save bounds for the LSQ inversion + iparam.bounds.lb = lb; + iparam.bounds.ub = ub; + iparam.bounds.f0 = x0; + + % calculate solution + invtmp = fitDataLSQ(time,signal,iparam); + s0_interp = K0f*invtmp.T1T2f; + + % check if the temporary chi2 and model norm are + % within the desired limits + if abs(1-invtmp.chi2/invstd.chi2) <= uncertChi2 && ... + abs(1-invtmp.xn/invstd.xn) <= uncertChi2/2 + % if YES then keep it + count = count + 1; + % save RTD + TDIST(i1*uncertN-(uncertN-count),:) = invtmp.T1T2f; + % save signal + SINTERP(:,i1*uncertN-(uncertN-count)) = s0_interp; + % save E0 + E0INTERP(i1*uncertN-(uncertN-count),1) = invtmp.E0; + % status bar info + infostring = ['Calculating uncertainty models: ',... + num2str(count),' / ',num2str(uncertN),... + ' for RTD bin: ',num2str(i1),' / ',num2str(numel(f_final))]; + displayStatusText(gui,infostring); + end + end + end + + case 'Lambda' + % find uncertainty models by varying the optimal + % regularization parameter lambda + + % set regularization to 'manual' just in case + iparam.regMethod = 'manual'; + + % lambda search range + a = log10(invstd.lambda_out/100); + b = log10(invstd.lambda_out*10); + + % counter + count = 0; + countm = 0; + + % initialize variables + TDIST = zeros(uncertN,numel(invstd.T1T2me)); + SINTERP = zeros(numel(time0),uncertN); + E0INTERP = zeros(uncertN,1); + % calculate uncertainty models + while count < uncertN + % draw a random lambda value + rr = (b-a).*rand(1,1) + a; + iparam.lambda = 10^(rr); + % calculate solution + invtmp = fitDataLSQ(time,signal,iparam); + s0_interp = K0f*invtmp.T1T2f; + + % check if temporary chi2 and model norm are within the + % desired limits + if abs(1-invtmp.chi2/invstd.chi2) <= uncertChi2 &&... + abs(1-invtmp.xn/invstd.xn) <= uncertChi2*10 + % if YES then keep it + count = count + 1; + % save RTD + TDIST(count,:) = invtmp.T1T2f; + % save signal + SINTERP(:,count) = s0_interp; + % save E0 + E0INTERP(count,1) = invtmp.E0; + % status bar info + infostring = ['Calculating uncertainty models: ',... + num2str(count),' / ',num2str(uncertN)]; + displayStatusText(gui,infostring); + % reset max counter + countm = 0; + else +% % update the lambda search range +% if invtmp.xn > invstd.xn % lambda was too small +% % new lower lambda search bound +% a = rr; +% end +% if invtmp.chi2 > invstd.chi2 % lambda was too big +% % new upper lambda search bound +% b = rr; +% end + % as long as we did not find a model keep counting + if count < 1 + countm = countm + 1; + infostring = ['Trying to find uncertainty model: ',... + num2str(countm),' / ',num2str(uncertMax)]; + displayStatusText(gui,infostring); + end + end + % after to many unsuccessful attempts STOP + if countm > uncertMax + infostring = ['No uncertainty model found: ',... + num2str(countm),' / ',num2str(uncertMax)]; + displayStatusText(gui,infostring); + break; + end + end + + case 'RMS_bound' + % find uncertainty models by adding random noise (based on + % fit RMS) on the optimal fit to create new "raw data" and + % invert them with the original optimal inversion settings + % select models based on chi2 and model norm bounds + + % set regularization to 'manual' just in case + iparam.regMethod = 'manual'; + + % counter + count = 0; + countm = 0; + + % initialize variables + TDIST = zeros(uncertN,numel(invstd.T1T2me)); + SINTERP = zeros(numel(time0),uncertN); + E0INTERP = zeros(uncertN,1); + % calculate uncertainty models + while count < uncertN + % the original fit + sig1 = invstd.fit_s; + % create some random noise based on original fit RMS + [signalN,~] = addNoiseToSignal(sig1,0,invstd.rms); + % calculate solution + invtmp = fitDataLSQ(time,signalN,iparam); + s0_interp = K0f*invtmp.T1T2f; + + % check if temporary chi2 and model norm are within the + % desired limits + if abs(1-invtmp.chi2/invstd.chi2) <= uncertChi2 &&... + abs(1-invtmp.xn/invstd.xn) <= uncertChi2*10 + % if YES then keep it + count = count + 1; + % save RTD + TDIST(count,:) = invtmp.T1T2f; + % save signal + SINTERP(:,count) = s0_interp; + % save E0 + E0INTERP(count,1) = invtmp.E0; + % status bar info + infostring = ['Calculating uncertainty models: ',... + num2str(count),' / ',num2str(uncertN)]; + displayStatusText(gui,infostring); + % reset max counter + countm = 0; + else + % as long as we did not find a model keep counting + if count < 1 + countm = countm + 1; + infostring = ['Trying to find uncertainty model: ',... + num2str(countm),' / ',num2str(uncertMax)]; + displayStatusText(gui,infostring); + end + end + % after to many unsuccessful attempts STOP + if countm > uncertMax + infostring = ['No uncertainty model found: ',... + num2str(countm),' / ',num2str(uncertMax)]; + displayStatusText(gui,infostring); + break; + end + end + + case 'RMS_free' + % find uncertainty models by adding random noise (based on + % fit RMS) on the optimal fit to create new "raw data" and + % invert them with the original optimal inversion settings + + % set regularization to 'manual' just in case + iparam.regMethod = 'manual'; + + % initialize variables + TDIST = zeros(uncertN,numel(invstd.T1T2me)); + SINTERP = zeros(numel(time0),uncertN); + E0INTERP = zeros(uncertN,1); + % calculate uncertainty models + for count = 1:uncertN + % the original fit + sig1 = invstd.fit_s; + % create some random noise based on original fit RMS + [signalN,~] = addNoiseToSignal(sig1,0,invstd.rms); + + % calculate solution + invtmp = fitDataLSQ(time,signalN,iparam); + s0_interp = K0f*invtmp.T1T2f; + % save RTD + TDIST(count,:) = invtmp.T1T2f; + % save signal + SINTERP(:,count) = s0_interp; + % save E0 + E0INTERP(count,1) = invtmp.E0; + % status bar info + infostring = ['Calculating uncertainty models: ',... + num2str(count),' / ',num2str(uncertN)]; + displayStatusText(gui,infostring); + end + end + + % output data + % simple E0 confidence interval + invstd.ciE0 = 2*std(E0INTERP); + + % uncertainty calculation results + uncert.interp_t = time0(:); + uncert.interp_E0 = E0INTERP; + uncert.interp_f = TDIST; + uncert.interp_s = SINTERP; + + % uncertainty patch for fitted signal + uncert.interp_s_min = min(SINTERP,[],2); + uncert.interp_s_max = max(SINTERP,[],2); + + % uncertainty patch for fitted RTD + uncert.interp_f_min = min(TDIST); + uncert.interp_f_max = max(TDIST); + + invstd.uncert = uncert; + + otherwise + % nothing to do + uncert = []; +end + +return + +%------------- END OF CODE -------------- + +%% License: +% MIT License +% +% Copyright (c) 2022 Thomas Hiller +% +% Permission is hereby granted, free of charge, to any person obtaining a copy +% of this software and associated documentation files (the "Software"), to deal +% in the Software without restriction, including without limitation the rights +% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the Software is +% furnished to do so, subject to the following conditions: +% +% The above copyright notice and this permission notice shall be included in all +% copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +% SOFTWARE. \ No newline at end of file diff --git a/functions/inversion/fcn_JointInvfixed.m b/functions/inversion/fcn_JointInvfixed.m index 1cc508f..a819ca4 100644 --- a/functions/inversion/fcn_JointInvfixed.m +++ b/functions/inversion/fcn_JointInvfixed.m @@ -13,6 +13,7 @@ % g : signal vector (all NMR signals) % indt : number of echoes/points per NMR signal % Tb : bulk relaxation time +% Td : diffusion relaxation time % T1T2 : flag between 'T1' or 'T2' inversion % T1IRfac : either '1' or '2' depending on T1 method % SatImbDrain : string indicating if a NMR signal is from @@ -47,8 +48,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -58,6 +59,7 @@ g = iparam.g; indt = iparam.indt; Tb = iparam.Tb; +Td = iparam.Td; T1T2 = iparam.T1T2; T1IRfac = iparam.T1IRfac; SatImbDrain = iparam.SatImbDrain; @@ -93,11 +95,11 @@ switch T1T2 case 'T1' for i=1:length(SV) - Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end case 'T2' for i=1:length(SV) - Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end end @@ -130,21 +132,23 @@ switch T1T2 case 'T1' for i=1:length(SV) - Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end % Kernel matrix for partial saturation Kc = zeros(length(t),length(SV)); for i=1:size(SVC,1) - Kc = Kc + ( squeeze(Amp(i,:,:)) .* ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) )); + Kc = Kc + ( squeeze(Amp(i,:,:)) .*... + ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) )); end case 'T2' for i=1:length(SV) - Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end % Kernel matrix for partial saturation Kc = zeros(length(t),length(SV)); for i=1:size(SVC,1) - Kc = Kc + ( squeeze(Amp(i,:,:)) .* exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) ); + Kc = Kc + ( squeeze(Amp(i,:,:)) .*... + exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) ); end end diff --git a/functions/inversion/fcn_JointInvfree.m b/functions/inversion/fcn_JointInvfree.m index 9c31d0a..bb5215c 100644 --- a/functions/inversion/fcn_JointInvfree.m +++ b/functions/inversion/fcn_JointInvfree.m @@ -11,6 +11,7 @@ % t : augmented time vector % g : augmented signal vector % Tb : bulk relaxation time +% Td : diffusion relaxation time % T1T2 : 'T1' / 'T2' flag % T1IRfac : either '1' or '2' depending on T1 method % L : smoothness constraint @@ -38,8 +39,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -48,6 +49,7 @@ t = iparam.t; g = iparam.g; Tb = iparam.Tb; +Td = iparam.Td; T1T2 = iparam.T1T2; T1IRfac = iparam.T1IRfac; L = iparam.L; @@ -73,11 +75,11 @@ switch T1T2 case 'T1' for i=1:length(SV) - Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end case 'T2' for i=1:length(SV) - Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end end K = Kf; @@ -97,23 +99,23 @@ switch T1T2 case 'T1' for i=1:length(SV) - Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end % Kernel matrix for partial saturation Kc = zeros(length(t),length(SV)); for i=1:size(SVC,1) Kc = Kc + ( squeeze(Amp(i,:,:)) .*... - ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) )); + ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) )); end case 'T2' for i=1:length(SV) - Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end % Kernel matrix for partial saturation Kc = zeros(length(t),length(SV)); for i=1:size(SVC,1) Kc = Kc + ( squeeze(Amp(i,:,:)) .*... - exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) ); + exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) ); end end % full saturation matrix @@ -161,19 +163,20 @@ case 'cyl' DD = zeros(length(t),length(SV)); for i=1:length(SV) - DD(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); + DD(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end case {'ang','poly'} % Kernel matrix for full saturation DD = zeros(length(t),length(SV)); for i=1:length(SV) - DD(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); + DD(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end % Kernel matrix for partial saturation D = zeros(length(t),length(SV)); for i=1:size(SVC,1) - D = D + ( squeeze(Amp(i,:,:)).* exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) ); + D = D + ( squeeze(Amp(i,:,:)).*... + exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) ); end DD(IPS~=1) = D(IPS~=1); end diff --git a/functions/inversion/fcn_JointInvshape.m b/functions/inversion/fcn_JointInvshape.m index c67baef..9739cfb 100644 --- a/functions/inversion/fcn_JointInvshape.m +++ b/functions/inversion/fcn_JointInvshape.m @@ -15,6 +15,7 @@ % g : signal vector (all NMR signals) % indt : number of echoes/points per NMR signal % Tb : bulk relaxation time +% Td : diffusion relaxation time % T1T2 : flag between 'T1' or 'T2' inversion % T1IRfac : either '1' or '2' depending on T1 method % SatImbDrain : string indicating if a NMR signal is from @@ -49,8 +50,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -60,6 +61,7 @@ g = iparam.g; indt = iparam.indt; Tb = iparam.Tb; +Td = iparam.Td; T1T2 = iparam.T1T2; T1IRfac = iparam.T1IRfac; SatImbDrain = iparam.SatImbDrain; @@ -112,21 +114,23 @@ switch T1T2 case 'T1' for i=1:length(SV) - Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = 1-T1IRfac.*exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end % Kernel matrix for partial saturation Kc = zeros(length(t),length(SV)); for i=1:size(SVC,1) - Kc = Kc + ( squeeze(Amp(i,:,:)) .* ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) )); + Kc = Kc + ( squeeze(Amp(i,:,:)) .*... + ( 1-T1IRfac.*exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) )); end case 'T2' for i=1:length(SV) - Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb)); + Kf(:,i) = exp(-t.*(rhos*SV(i) + 1/Tb + 1/Td)); end % Kernel matrix for partial saturation Kc = zeros(length(t),length(SV)); for i=1:size(SVC,1) - Kc = Kc + ( squeeze(Amp(i,:,:)) .* exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb)) ); + Kc = Kc + ( squeeze(Amp(i,:,:)) .*... + exp(-TT.*(rhos*squeeze(SVC(i,:,:)) + 1/Tb + 1/Td)) ); end end diff --git a/functions/inversion/fcn_fitFreeT1.m b/functions/inversion/fcn_fitFreeT1.m index ad849c9..a3d20df 100644 --- a/functions/inversion/fcn_fitFreeT1.m +++ b/functions/inversion/fcn_fitFreeT1.m @@ -28,8 +28,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/fcn_fitFreeT1_fmin.m b/functions/inversion/fcn_fitFreeT1_fmin.m index 8dc2903..30f66ba 100644 --- a/functions/inversion/fcn_fitFreeT1_fmin.m +++ b/functions/inversion/fcn_fitFreeT1_fmin.m @@ -29,8 +29,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/fcn_fitFreeT2.m b/functions/inversion/fcn_fitFreeT2.m index d53a1db..ed91709 100644 --- a/functions/inversion/fcn_fitFreeT2.m +++ b/functions/inversion/fcn_fitFreeT2.m @@ -27,8 +27,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/fcn_fitFreeT2_fmin.m b/functions/inversion/fcn_fitFreeT2_fmin.m index 24d3cec..823d1f8 100644 --- a/functions/inversion/fcn_fitFreeT2_fmin.m +++ b/functions/inversion/fcn_fitFreeT2_fmin.m @@ -29,8 +29,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/fcn_fitFreeT2w.m b/functions/inversion/fcn_fitFreeT2w.m index 4c0b325..f264333 100644 --- a/functions/inversion/fcn_fitFreeT2w.m +++ b/functions/inversion/fcn_fitFreeT2w.m @@ -31,8 +31,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/fcn_fitMultiModal.m b/functions/inversion/fcn_fitMultiModal.m new file mode 100644 index 0000000..154f150 --- /dev/null +++ b/functions/inversion/fcn_fitMultiModal.m @@ -0,0 +1,116 @@ +function F = fcn_fitMultiModal(x,iparam) +%fcn_fitMultiModal is the objective function for N free distribution +%fitting that is minimized with 'lsqnonlin' +% +% Syntax: +% fcn_fitMultiModal(x,iparam) +% +% Inputs: +% x - parameter vector +% x(3*i-2) = mu (relaxation time) +% x(3*i-1) = sigma (width of distribution) +% x(3*i) = amp (relative amplitude) +% iparam - struct that holds additional settings: +% t : time vector +% s : signal vector +% T : relaxation times +% e : noise vector / error weights (optional) +% +% Outputs: +% F - residual +% +% Example: +% F = fcn_fitMultiModal(x,params) +% +% Other m-files required: +% createKernelMatrix +% +% Subfunctions: +% none +% +% MAT-files required: +% none +% +% See also: +% Author: see AUTHORS.md +% email: see AUTHORS.md +% License: MIT License (at end) + +%------------- BEGIN CODE -------------- + +% get all neccessary parameters +flag = iparam.flag; +T1IRfac = iparam.T1IRfac; +nModes = iparam.nModes; +t = iparam.t; +s = iparam.s; +T = iparam.T; +Tb = iparam.Tb; +Td = iparam.Td; + +% get the global (combined) RTD distribution +Tdist = 0; +for i = 1:nModes + mu = exp(x(3*i-2)); + sigma = x(3*i-1); + amp = x(3*i); + + % get the temporary RTD with current mu and sigma + tmp = 1./( sigma*sqrt(2*pi)).*exp(-((log(T) - log(mu))/ sqrt(2)/sigma).^2); + + % scale the temporary RDT to current amplitude + tmp = (tmp/sum(tmp)) * amp; + + % add the current temporary RTD to the global Tdist + Tdist = Tdist + tmp; +end + +% get the kernel function to calculate the signal out of the global RTD +K = createKernelMatrix(t,T,Tb,Td,flag,T1IRfac); +si = K*Tdist'; + + +% get error weights if available +if isfield(iparam,'e') + e = iparam.e; +else + e = ones(size(s)); +end + +% change output depending on solver +switch iparam.optim + case 'on' % lsqnonlin + % scale the residual + F = e.*(si - s); + case 'off' % fminsearchbnd + F = e.*(si - s); + SSE = sum(F.^2); + F = SSE; +end + +return + +%------------- END OF CODE -------------- + +%% License: +% MIT License +% +% Copyright (c) 2022 Thomas Hiller +% +% Permission is hereby granted, free of charge, to any person obtaining a copy +% of this software and associated documentation files (the "Software"), to deal +% in the Software without restriction, including without limitation the rights +% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the Software is +% furnished to do so, subject to the following conditions: +% +% The above copyright notice and this permission notice shall be included in all +% copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +% SOFTWARE. \ No newline at end of file diff --git a/functions/inversion/fitDataFree.m b/functions/inversion/fitDataFree.m index 257e310..34e8161 100644 --- a/functions/inversion/fitDataFree.m +++ b/functions/inversion/fitDataFree.m @@ -54,8 +54,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -85,8 +85,9 @@ % start values for E and T x0 = zeros(1,2*nExp); for i = 1:nExp - x0(2*i-1) = max(signal)/nExp; - x0(2*i) = i*max(t)/4; + x0(2*i-1) = i*max(signal)/nExp; + x0(2*i) = i*max(t)/nExp; +% x0(2*i) = exp(i*max(log(t))/nExp); end switch parameter.optim @@ -112,10 +113,10 @@ iparam.t = t; iparam.s = s; - [x,~,~,~,output,~,jacobian] = lsqnonlin(@(x)fcn_fitFreeT2w(x,iparam),... - x0,zeros(size(x0)),[],options); - % [x,~,~,~,output,~,jacobian] = lsqcurvefit(@fcn_fitFreeT2,... - % x0,t,s,zeros(size(x0)),[],options); +% [x,~,~,~,output,~,jacobian] = lsqnonlin(@(x)fcn_fitFreeT2w(x,iparam),... +% x0,zeros(size(x0)),[],options); + [x,~,~,~,output,~,jacobian] = lsqcurvefit(@fcn_fitFreeT2,... + x0,t,s,zeros(size(x0)),[],options); end case 'off' % solver options diff --git a/functions/inversion/fitDataLSQ.m b/functions/inversion/fitDataLSQ.m index 373a62c..5f8f5c9 100644 --- a/functions/inversion/fitDataLSQ.m +++ b/functions/inversion/fitDataLSQ.m @@ -14,6 +14,7 @@ % T1T2 : flag between 'T1' or 'T2' inversion % T1IRfac : either '1' or '2' depending on T1 method % Tb : bulk relaxation time +% Td : diffusion relaxation time % Tint : relaxation times [log10(tmin) log10(tmax) Ndec] % regMethod: 'manual', 'gcv_tikh', 'gcv_trunc', % 'gcv_damp', 'discrep' @@ -23,6 +24,8 @@ % principle % W : error weighting matrix (optional) % solver : LSQ solver ('lsqlin' or 'lsqnonneg') +% bounds : predefined lower and upper bounds and start +% model (optional and only for 'lsqlin') % % Outputs: % fitdata - struct that holds the inversion results: @@ -30,7 +33,7 @@ % fit_s : signal vector for plotting % T1T2me : relaxation time values % T1T2f : relaxation time spectrum -% Tlgm : T logmean +% Tlgm : T log-mean % E0 : initial amplitude at t=0 (T2) or t=inf (T1) % resnorm : residual norm % residual : vector of residuals @@ -64,8 +67,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -86,6 +89,7 @@ flag = parameter.T1T2; % T1/T2 switch T1IRfac = parameter.T1IRfac; % T1 Sat/Inv Recovery factor Tb = parameter.Tb; % bulk relaxation time +Td = parameter.Td; % diffusion relaxation time tstart = parameter.Tint(1); % log10 value tend = parameter.Tint(2); % log10 value N = parameter.Tint(3); % N per decade @@ -98,13 +102,23 @@ T1T2me = logspace(tstart,tend,(tend-tstart)*N); % create the Kernel matrix for inversion -K = createKernelMatrix(t,T1T2me,Tb,flag,T1IRfac); +K = createKernelMatrix(t,T1T2me,Tb,Td,flag,T1IRfac); if strcmp(parameter.solver,'lsqlin') - % initial T2 amplitudes - f0 = zeros(size(T1T2me)); - f0_lb = f0; - f0_ub = 1.5*max(g)*ones(size(T1T2me)); + if isfield(parameter,'bounds') + f0 = parameter.bounds.f0; + f0_lb = parameter.bounds.lb; + f0_ub = parameter.bounds.ub; + else + % initial T2 amplitudes + f0 = zeros(size(T1T2me)); + f0_lb = f0; + f0_ub = 1.5*max(g)*ones(size(T1T2me)); + % T2 measurements: cut everything < first considered echo to zero + f0_ub(T1T2me < time(1)/5) = 0; + % T1 measurements: cut everything > 5*time of last point in SR-curve + % f0_ub(T1T2me > time(end)) = 0; + end end % derivative matrix @@ -138,14 +152,19 @@ options.Display = parameter.info; options.OptimalityTolerance = 1e-18; options.StepTolerance = 1e-18; - [f,~,~,~,~,~] = lsqlin(KK,gg,[],[],[],[],... - f0_lb,f0_ub,[],options); + if isfield(parameter,'bounds') + [f,~,~,~,~,~] = lsqlin(KK,gg,[],[],[],[],... + f0_lb,f0_ub,f0,options); + else + [f,~,~,~,~,~] = lsqlin(KK,gg,[],[],[],[],... + f0_lb,f0_ub,[],options); + end case 'lsqnonneg' options = optimset('Display',parameter.info,'TolX',1e-12); [f,~,~,~,~,~] = lsqnonneg(KK,gg,options); end -% rescale f so that the sum(f)= unscaled E0 +% rescale f so that the sum(f) = unscaled E0 f = (f.*maxS); % the 'inverted' signal @@ -177,13 +196,11 @@ % get "initial" value E0 if strcmp(flag,'T1') - t2 = 10*time(end); - K2 = createKernelMatrix(t2,T1T2me,Tb,flag,T1IRfac); + K0 = createKernelMatrix(10*time(end),T1T2me,Tb,Td,flag,T1IRfac); elseif strcmp(flag,'T2') - t2 = 0; - K2 = createKernelMatrix(t2,T1T2me,Tb,flag,T1IRfac); + K0 = createKernelMatrix(0,T1T2me,Tb,Td,flag,T1IRfac); end -E0 = K2*f; +E0 = K0*f; % output struct fitdata.fit_t = time(:); @@ -192,6 +209,7 @@ fitdata.T1T2f = f(:); fitdata.Tlgm = getTLogMean(T1T2me,f); fitdata.E0 = E0; +fitdata.ciE0 = NaN; fitdata.resnorm = out.resnorm; fitdata.residual = out.residual; fitdata.chi2 = out.chi2; diff --git a/functions/inversion/fitDataLUdecomp.m b/functions/inversion/fitDataLUdecomp.m index aeb93e8..579111d 100644 --- a/functions/inversion/fitDataLUdecomp.m +++ b/functions/inversion/fitDataLUdecomp.m @@ -12,6 +12,7 @@ % T1T2 : flag between 'T1' or 'T2' inversion % T1IRfac : either '1' or '2' depending on T1 method % Tb : bulk relaxation time +% Td : diffusion relaxation time % Tint : relaxation times [log10(tmin) log10(tmax) Ndec] % Lorder : smoothness constraint (derivative matrix) % lambda : regularization parameter (if -1 automatic @@ -54,8 +55,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % NOTE: I harvested this routine partly from the Internet but forgot where % I found the routines ... so there is no warranty at all @@ -77,6 +78,7 @@ flag = parameter.T1T2; % T1/T2 switch T1IRfac = parameter.T1IRfac; % T1 Sat/Inv Recovery factor Tb = parameter.Tb; % bulk relaxation time +Td = parameter.Td; % diffusion relaxation time tstart = parameter.Tint(1); % log10 value tend = parameter.Tint(2); % log10 value N = parameter.Tint(3); % N per decade @@ -88,7 +90,7 @@ T1T2me = logspace(tstart,tend,(tend-tstart)*N); % create the Kernel matrix -K = createKernelMatrix(t,T1T2me,Tb,flag,T1IRfac); +K = createKernelMatrix(t,T1T2me,Tb,Td,flag,T1IRfac); % calculate reg matrix H m = length(T1T2me); @@ -165,10 +167,10 @@ % get "initial" value E0 if strcmp(flag,'T1') t2 = 10*time(end); - K2 = createKernelMatrix(t2,T1T2me,Tb,flag,T1IRfac); + K2 = createKernelMatrix(t2,T1T2me,Tb,Td,flag,T1IRfac); elseif strcmp(flag,'T2') t2 = 0; - K2 = createKernelMatrix(t2,T1T2me,Tb,flag,T1IRfac); + K2 = createKernelMatrix(t2,T1T2me,Tb,Td,flag,T1IRfac); end E0 = K2*f; diff --git a/functions/inversion/fitDataMultiModal.m b/functions/inversion/fitDataMultiModal.m new file mode 100644 index 0000000..9e776e0 --- /dev/null +++ b/functions/inversion/fitDataMultiModal.m @@ -0,0 +1,299 @@ +function [fitdata] = fitDataMultiModal(time,signal,parameter,nModes) +%fitDataMultiModal is a control routine that uses either 'lsqnonlin' or +%'fminsearchbnd' to fit NMR data with 'nModes' multi modal relaxation time +%distributions (T1 or T2) +% +% Syntax: +% fitDataMultiModal(time,signal,flag,parameter,nExp) +% +% InputsR: +% time - time vector +% signal - NMR signal vector (no complex data allowed!) +% parameter - struct that holds additional settings: +% T1T2 : flag between 'T1' or 'T2' inversion +% T1IRfac : either '1' or '2' depending on T1 method +% Tb : bulk relaxation time +% Td : diffusion relaxation time +% Tint : relaxation times [log10(tmin) log10(tmax) Ndec] +% noise : noise level needed for 'discrep' discrepancy +% principle +% optim : 'on' or 'off' (Optimization Toolbox) +% W : error weighting matrix (optional) +% nModes - No. of free distributions +% +% Outputs: +% fitdata - struct that holds the inversion results: +% fit_t : time vector for plotting +% fit_s : signal vector for plotting +% T1T2me : relaxation time values +% T1T2f : relaxation time spectrum +% Tlgm : T log-mean +% E0 : initial amplitude at t=0 (T2) or t=max (T1) +% ciE : E0 confidence interval (NaN as placeholder) +% resnorm : residual norm +% residual: vector of residuals +% errnorm : error norm +% lambda_out : dummy 0 +% rms : RMS error +% chi2 : chi square error +% ci : confidence interval +% T : relaxation times per mode +% S : width per mode +% E : amplitude per mode; +% x : all parameters combined +% lb : lower bounds +% ub : upper bounds +% output : output struct (output from 'lsqnonlin' or +% 'fminsearchbnd') +% +% Example: +% [fitdata] = fitDataMultiModal(t,s,parameter,2) +% +% Other m-files required: +% createKernelMatrix +% estimateJacobian +% fcn_fitMultiModal +% fitDataFree +% fminsearchbnd +% getFitErrors +% getFitFreeJacobian +% getConfInterval +% lsqnonlin (Optimization Toolbox) +% +% Subfunctions: +% none +% +% MAT-files required: +% none +% +% See also: +% Author: see AUTHORS.md +% email: see AUTHORS.md +% License: MIT License (at end) + +%------------- BEGIN CODE -------------- + +% make column vector +t = time(:); +s = signal(:); + +% error weights after gating +if isfield(parameter,'W') + e = diag(parameter.W); + iparam.e = sqrt(e); +end + +% get the input parameters +% T1/T2 switch +flag = parameter.T1T2; +% T1 Sat/Inv Recovery factor +T1IRfac = parameter.T1IRfac; +% bulk relaxation time +Tb = parameter.Tb; +% diffusion relaxation time +Td = parameter.Td; +% smallest value in RTD (log10 value) +tstart = parameter.Tint(1); +% largest value in RTD (log10 value) +tend = parameter.Tint(2); +% N per decade in RTD +N = parameter.Tint(3); + +% get boundary values for mu, sigma and amp by first applying a free +% exponential fit +param0.T1IRfac = T1IRfac; +param0.noise = parameter.noise; +param0.optim = parameter.optim; +if isfield(parameter,'W') + param0.W = parameter.W; +end +% free exponential fit to get some reasonable start values +invstd0 = fitDataFree(t,s,flag,param0,nModes); + +% start values for E and T +x0 = zeros(1,3*nModes); +lb = zeros(1,3*nModes); +ub = zeros(1,3*nModes); +for i = 1:nModes + % initial values for T, sigma and E + x0(3*i-2) = log(invstd0.x(2*i)); + x0(3*i-1) = 1; + x0(3*i) = invstd0.x(2*i-1); + + % lower bounds for T, sigma and E + lb(3*i-2) = log(1e-6);%log(invstd0.x(2*i)*0.8);%log(invstd0.x(2*i) - 10*invstd0.ci(2*i)); + lb(3*i-1) = 0.01; + lb(3*i) = invstd0.x(2*i-1)*0.8;%invstd0.x(2*i-1) - 10*invstd0.ci(2*i-1); + + % upper bounds for T, sigma and E + ub(3*i-2) = log(10);%log(invstd0.x(2*i) + 50*invstd0.ci(2*i)); + ub(3*i-1) = 3.5; + ub(3*i) = max(invstd0.E0)*1.1;%invstd0.x(2*i-1) + 50*invstd0.ci(2*i-1); +end + +% switch off output if no option is given via 'parameter' +if ~isfield(parameter,'info') + parameter.info = 'off'; +end + +% create the relaxation time vector +T1T2me = logspace(tstart,tend,(tend-tstart)*N); + +% just needed for debugging the Optimization Toolbox availability +% parameter.optim = 'off'; + +switch parameter.optim + case 'on' + % solver options + options = optimoptions('lsqnonlin'); + options.Algorithm = 'levenberg-marquardt'; + options.Display = parameter.info; + options.OptimalityTolerance = 1e-12; + options.StepTolerance = 1e-12; + + iparam.optim = parameter.optim; + iparam.flag = flag; + iparam.T1IRfac = T1IRfac; + iparam.nModes = nModes; + iparam.t = t; + iparam.s = s; + iparam.T = T1T2me; + iparam.Tb = Tb; + iparam.Td = Td; + [x,~,~,~,output,~,jacobian] = lsqnonlin(@(x)fcn_fitMultiModal(x,iparam),... + x0,lb,ub,options); + + case 'off' + % solver options + options = optimset('Display',parameter.info,'MaxFunEvals',10^6,... + 'MaxIter',5000,'TolFun',1e-12,'TolX',1e-12); + + iparam.optim = parameter.optim; + iparam.flag = flag; + iparam.T1IRfac = T1IRfac; + iparam.nModes = nModes; + iparam.t = t; + iparam.s = s; + iparam.T = T1T2me; + iparam.Tb = Tb; + iparam.Td = Td; + [x,~,~,output] = fminsearchbnd(@(x) fcn_fitMultiModal(x,iparam),... + x0,lb,ub,options); + + % get Jacobian + % therefore we need to switch the 'optim' on to get the correct + % output of 'fcn_fitMultiModal' + iparam.optim = 'on'; + jacobian = estimateJacobian(@(x)fcn_fitMultiModal(x,iparam),x); +end + +% assemble the final RTD +Tdist = 0; +for i = 1:length(x)/3 + mu = exp(x(3*i-2)); % T + sigma = x(3*i-1); % S + amp = x(3*i); % E + + tmp = 1./( sigma*sqrt(2*pi)).*exp(-((log(T1T2me) - log(mu))/ sqrt(2)/sigma).^2); + + % scale to amplitude + tmp = (tmp/sum(tmp)) * amp; + % add the tmp per mu to Tdist + Tdist = Tdist + tmp; +end +f = Tdist; +% the fitted signal +K = createKernelMatrix(t,T1T2me,Tb,Td,flag,1); +si = K*f'; + +% get the fit +fit_t = t; +fit_s = si; + +% get residuals and error measures +if isfield(parameter,'W') + % when signal gating was used the error estimates need to be adjusted + out = getFitErrors(signal,fit_s,parameter.noise,parameter.W); +else + out = getFitErrors(signal,fit_s,parameter.noise); +end + +% confidence interval +ci = getConfInterval(out.resnorm,jacobian,0.05); + +% sort the relaxation times in ascending order and adjust the confidence +% interval accordingly +T = exp(x(1:3:end)); +S = x(2:3:end); +E = x(3:3:end); +[T,idx] = sort(T); +S = S(idx); +E = E(idx); +ciT = ci(1:3:end); +ciS = ci(2:3:end); +ciE = ci(3:3:end); +ciT = ciT(idx); +ciS = ciS(idx); +ciE = ciE(idx); +ci(1:3:end) = ciT; +ci(2:3:end) = ciS; +ci(3:3:end) = ciE; + +% get "initial" value E0 +switch flag + case 'T1' + K0 = createKernelMatrix(10*time(end),T1T2me,Tb,Td,flag,T1IRfac); + case 'T2' + K0 = createKernelMatrix(0,T1T2me,Tb,Td,flag,T1IRfac); +end +E0 = K0*f'; + +% output struct +fitdata.fit_t = fit_t; +fitdata.fit_s = fit_s; +fitdata.T1T2me = T1T2me(:); +fitdata.T1T2f = f(:); +fitdata.Tlgm = getTLogMean(T1T2me,f); +fitdata.E0 = E0; +fitdata.ciE0 = NaN; +fitdata.resnorm = out.resnorm; +fitdata.residual = out.residual; +fitdata.errornorm = out.errnorm1; +fitdata.lambda_out = 0; +fitdata.rms = out.rms; +fitdata.chi2 = out.chi2; +fitdata.ci = ci; +fitdata.T = T; +fitdata.S = S; +fitdata.E = E; +fitdata.x = x; +fitdata.lb = lb; +fitdata.ub = ub; +fitdata.output = output; + +return + +%------------- END OF CODE -------------- + +%% License: +% MIT License +% +% Copyright (c) 2022 Thomas Hiller +% +% Permission is hereby granted, free of charge, to any person obtaining a copy +% of this software and associated documentation files (the "Software"), to deal +% in the Software without restriction, including without limitation the rights +% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the Software is +% furnished to do so, subject to the following conditions: +% +% The above copyright notice and this permission notice shall be included in all +% copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +% SOFTWARE. \ No newline at end of file diff --git a/functions/inversion/getChi2.m b/functions/inversion/getChi2.m index ebad62c..b7b672d 100644 --- a/functions/inversion/getChi2.m +++ b/functions/inversion/getChi2.m @@ -25,8 +25,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/getConfInterval.m b/functions/inversion/getConfInterval.m index f55869a..6a6e8ba 100644 --- a/functions/inversion/getConfInterval.m +++ b/functions/inversion/getConfInterval.m @@ -31,8 +31,8 @@ % % See also: "Parameter Estimation and Inverse Problems", 2nd Ed. % by Aster et. al p.32 ff -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/getFitErrors.m b/functions/inversion/getFitErrors.m index 354202f..1852f40 100644 --- a/functions/inversion/getFitErrors.m +++ b/functions/inversion/getFitErrors.m @@ -34,8 +34,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/getFitFreeJacobian.m b/functions/inversion/getFitFreeJacobian.m index 0c0237d..88bf645 100644 --- a/functions/inversion/getFitFreeJacobian.m +++ b/functions/inversion/getFitFreeJacobian.m @@ -28,8 +28,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/getLambdaFromLCurve.m b/functions/inversion/getLambdaFromLCurve.m index e6a1901..6692d30 100644 --- a/functions/inversion/getLambdaFromLCurve.m +++ b/functions/inversion/getLambdaFromLCurve.m @@ -26,8 +26,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/getLambdaFromRMS.m b/functions/inversion/getLambdaFromRMS.m index c101b7a..d5f1770 100644 --- a/functions/inversion/getLambdaFromRMS.m +++ b/functions/inversion/getLambdaFromRMS.m @@ -27,8 +27,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/getStudentInvCDF.m b/functions/inversion/getStudentInvCDF.m index 26787e0..44b086d 100644 --- a/functions/inversion/getStudentInvCDF.m +++ b/functions/inversion/getStudentInvCDF.m @@ -28,8 +28,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/inversion/getTLogMean.m b/functions/inversion/getTLogMean.m index da658dc..dc772c5 100644 --- a/functions/inversion/getTLogMean.m +++ b/functions/inversion/getTLogMean.m @@ -26,8 +26,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/addNoiseToSignal.m b/functions/modeling/addNoiseToSignal.m index 6c7c265..9e69f4b 100644 --- a/functions/modeling/addNoiseToSignal.m +++ b/functions/modeling/addNoiseToSignal.m @@ -27,8 +27,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/createPSD.m b/functions/modeling/createPSD.m index 4dde474..795f340 100644 --- a/functions/modeling/createPSD.m +++ b/functions/modeling/createPSD.m @@ -29,8 +29,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getAngularityFactor.m b/functions/modeling/getAngularityFactor.m index 110494c..a98f48f 100644 --- a/functions/modeling/getAngularityFactor.m +++ b/functions/modeling/getAngularityFactor.m @@ -24,8 +24,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getAreaFactor.m b/functions/modeling/getAreaFactor.m index 0260b62..cf50a4b 100644 --- a/functions/modeling/getAreaFactor.m +++ b/functions/modeling/getAreaFactor.m @@ -25,8 +25,8 @@ % % See also: % Tuller & Or, 2001, WRR, Vol. 37(5), 1257-1276 -% Author: Stepahn Costabel -% email: stephan.costabel[at]bgr.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getConduct.m b/functions/modeling/getConduct.m index d3e1de2..02b49a7 100644 --- a/functions/modeling/getConduct.m +++ b/functions/modeling/getConduct.m @@ -32,8 +32,8 @@ % See also: % Tuller & Or, 2001, WRR, Vol. 37(5), 1257-1276 % Patzek & Silin, 2001, JColIntSci, Vol. 236(2), 295-304 -% Author: Stepahn Costabel -% email: stephan.costabel[at]bgr.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getConstants.m b/functions/modeling/getConstants.m index 46315f5..71f37a2 100644 --- a/functions/modeling/getConstants.m +++ b/functions/modeling/getConstants.m @@ -24,8 +24,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getCornerNMRparameter.m b/functions/modeling/getCornerNMRparameter.m index 57c1477..3e4fb89 100644 --- a/functions/modeling/getCornerNMRparameter.m +++ b/functions/modeling/getCornerNMRparameter.m @@ -32,8 +32,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getCornerSaturation.m b/functions/modeling/getCornerSaturation.m index a6aea23..07cc5ad 100644 --- a/functions/modeling/getCornerSaturation.m +++ b/functions/modeling/getCornerSaturation.m @@ -27,8 +27,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getCriticalPressure.m b/functions/modeling/getCriticalPressure.m index 1a292dc..77b687d 100644 --- a/functions/modeling/getCriticalPressure.m +++ b/functions/modeling/getCriticalPressure.m @@ -29,8 +29,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getGeometryParameter.m b/functions/modeling/getGeometryParameter.m index b577c02..0fba4a6 100644 --- a/functions/modeling/getGeometryParameter.m +++ b/functions/modeling/getGeometryParameter.m @@ -38,8 +38,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getNMRSignal.m b/functions/modeling/getNMRSignal.m index 15a0146..ece93be 100644 --- a/functions/modeling/getNMRSignal.m +++ b/functions/modeling/getNMRSignal.m @@ -9,6 +9,7 @@ % nmr - structure containing fields: % t : time vector [s] % Tb : bulk relaxation time [s] +% Td : diffusion relaxation time [s] % rho : surface relaxivity [m/s] % type - either 'cyl', 'ang' and 'poly' % SatData - structure (output from 'getSaturationfromPressure') @@ -40,8 +41,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- @@ -56,6 +57,7 @@ % get general parameters t = nmr.t; Tb = nmr.Tb; +Td = nmr.Td; rho = nmr.rho; %% some informative wait-bar ;-) @@ -88,13 +90,13 @@ % for all time steps for j = 1:length(t) EiT1(p,j) = sum(SatData.Si(p,:) .* psdData.psd .* ... - (1-exp(-t(j) .* (1./Tb+rho.*SVi(p,:)) ))); + (1-exp(-t(j) .* (1./Td+1./Tb+rho.*SVi(p,:)) ))); EiT2(p,j) = sum(SatData.Si(p,:) .* psdData.psd .* ... - exp(-t(j) .* (1./Tb+rho.*SVi(p,:)) ) ); + exp(-t(j) .* (1./Td+1./Tb+rho.*SVi(p,:)) ) ); EdT1(p,j) = sum(SatData.Sd(p,:) .* psdData.psd .* ... - (1-exp(-t(j) .* (1./Tb+rho.*SVd(p,:)) ))); + (1-exp(-t(j) .* (1./Td+1./Tb+rho.*SVd(p,:)) ))); EdT2(p,j) = sum(SatData.Sd(p,:) .* psdData.psd .* ... - exp(-t(j) .* (1./Tb+rho.*SVd(p,:)) ) ); + exp(-t(j) .* (1./Td+1./Tb+rho.*SVd(p,:)) ) ); end if wbopts.show waitbar(p / steps,hwb,['processing ... ',num2str(p),' / ',... @@ -128,31 +130,31 @@ for j = 1:numel(psdData.r) % --- imbibition --- if SatData.isfullsati(p,j) == 1 % if fully saturated -> Ampl = 1 - sigiT1(j,:) = (1-exp(-t .* (1./Tb + rho.*SVi(j,1)) )); - sigiT2(j,:) = exp(-t .* (1./Tb + rho.*SVi(j,1)) ); + sigiT1(j,:) = (1-exp(-t .* (1./Td + 1./Tb + rho.*SVi(j,1)) )); + sigiT2(j,:) = exp(-t .* (1./Td + 1./Tb + rho.*SVi(j,1)) ); else % partially saturated pore -> account for corners for jj = 1:Ncorners Ampl = Aai(j,jj) / SatData.A0(j); sigiT1(j,:) = sigiT1(j,:) + (Ampl * (1-exp(-t .* ... - (1./Tb + rho.*SVi(j,jj)))) ); + (1./Td + 1./Tb + rho.*SVi(j,jj)))) ); sigiT2(j,:) = sigiT2(j,:) + (Ampl * exp(-t .* ... - (1./Tb + rho.*SVi(j,jj))) ); + (1./Td + 1./Tb + rho.*SVi(j,jj))) ); end end % --- drainage --- if SatData.isfullsatd(p,j) == 1 % if fully saturated -> Ampl = 1 - sigdT1(j,:) = (1-exp(-t .* (1./Tb + rho.*SVd(j,1)) )); - sigdT2(j,:) = exp(-t .* (1./Tb + rho.*SVd(j,1)) ); + sigdT1(j,:) = (1-exp(-t .* (1./Td + 1./Tb + rho.*SVd(j,1)) )); + sigdT2(j,:) = exp(-t .* (1./Td + 1./Tb + rho.*SVd(j,1)) ); else % partially saturated pore -> account for corners for jj = 1:Ncorners Ampl = Aad(j,jj) / SatData.A0(j); sigdT1(j,:) = sigdT1(j,:) + (Ampl * (1-exp(-t .* ... - (1./Tb + rho.*SVd(j,jj)))) ); + (1./Td + 1./Tb + rho.*SVd(j,jj)))) ); sigdT2(j,:) = sigdT2(j,:) + (Ampl * exp(-t .* ... - (1./Tb + rho.*SVd(j,jj))) ); + (1./Td + 1./Tb + rho.*SVd(j,jj))) ); end end diff --git a/functions/modeling/getNMRTimeVector.m b/functions/modeling/getNMRTimeVector.m index 04b7ec9..450fbbe 100644 --- a/functions/modeling/getNMRTimeVector.m +++ b/functions/modeling/getNMRTimeVector.m @@ -35,8 +35,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getPartialSaturationMatrix.m b/functions/modeling/getPartialSaturationMatrix.m index 702eac9..e2aafa2 100644 --- a/functions/modeling/getPartialSaturationMatrix.m +++ b/functions/modeling/getPartialSaturationMatrix.m @@ -28,8 +28,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getPointCoordinates.m b/functions/modeling/getPointCoordinates.m index f3cddd8..a19b60d 100644 --- a/functions/modeling/getPointCoordinates.m +++ b/functions/modeling/getPointCoordinates.m @@ -25,8 +25,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getPressureRangeFromPSD.m b/functions/modeling/getPressureRangeFromPSD.m index 375faa4..420b434 100644 --- a/functions/modeling/getPressureRangeFromPSD.m +++ b/functions/modeling/getPressureRangeFromPSD.m @@ -27,8 +27,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getRaRaEps.m b/functions/modeling/getRaRaEps.m index 8068cb4..e67b490 100644 --- a/functions/modeling/getRaRaEps.m +++ b/functions/modeling/getRaRaEps.m @@ -27,8 +27,8 @@ % % See also: % Ransohoff & Radke, 1988, JColIntSci, Vol. 121(2), 392-401 -% Author: Stepahn Costabel -% email: stephan.costabel[at]bgr.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getSaturationFromPressure.m b/functions/modeling/getSaturationFromPressure.m index 88f0323..d382d0f 100644 --- a/functions/modeling/getSaturationFromPressure.m +++ b/functions/modeling/getSaturationFromPressure.m @@ -38,8 +38,8 @@ % none % % See also: -% Author: Thomas Hiller, Stephan Costabel -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getSaturationFromPressureBatch.m b/functions/modeling/getSaturationFromPressureBatch.m index 8b54955..3176cd8 100644 --- a/functions/modeling/getSaturationFromPressureBatch.m +++ b/functions/modeling/getSaturationFromPressureBatch.m @@ -46,8 +46,8 @@ % none % % See also: -% Author: Thomas Hiller, Stephan Costabel -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getSaturationLevelData.m b/functions/modeling/getSaturationLevelData.m index b065f0a..f84b538 100644 --- a/functions/modeling/getSaturationLevelData.m +++ b/functions/modeling/getSaturationLevelData.m @@ -29,8 +29,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/functions/modeling/getShapeFactor.m b/functions/modeling/getShapeFactor.m index a49856c..2953b1e 100644 --- a/functions/modeling/getShapeFactor.m +++ b/functions/modeling/getShapeFactor.m @@ -24,8 +24,8 @@ % none % % See also: -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/nucleusinv_gui.png b/nucleusinv_gui.png index 58d0b20..f773e19 100644 Binary files a/nucleusinv_gui.png and b/nucleusinv_gui.png differ diff --git a/nucleusmod_gui.png b/nucleusmod_gui.png index cf771ca..024b302 100644 Binary files a/nucleusmod_gui.png and b/nucleusmod_gui.png differ diff --git a/startNUCLEUSinv.m b/startNUCLEUSinv.m index cf38212..671bc34 100644 --- a/startNUCLEUSinv.m +++ b/startNUCLEUSinv.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSinv -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE -------------- diff --git a/startNUCLEUSmod.m b/startNUCLEUSmod.m index c9a6863..fcd4220 100644 --- a/startNUCLEUSmod.m +++ b/startNUCLEUSmod.m @@ -24,8 +24,8 @@ % none % % See also: NUCLEUSmod -% Author: Thomas Hiller -% email: thomas.hiller[at]leibniz-liag.de +% Author: see AUTHORS.md +% email: see AUTHORS.md % License: MIT License (at end) %------------- BEGIN CODE --------------