├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── MODA.m ├── README.md ├── User Manual.pdf ├── allguis ├── codes │ ├── Graphics │ │ ├── clear_axes_lines.m │ │ ├── clear_axes_points.m │ │ └── fillsig.m │ ├── Universal │ │ ├── MODATFAcalc.m │ │ ├── MODAclose.m │ │ ├── MODAcsvsave.m │ │ ├── MODAload.m │ │ ├── MODAread.m │ │ ├── MODAreadcheck.m │ │ ├── MODAsave.m │ │ ├── MODAsettings.m │ │ ├── imodwt.m │ │ ├── matchRotation.m │ │ ├── modwt.m │ │ ├── newid.m │ │ └── wsurr.m │ ├── cell2csv │ │ ├── cell2csv.m │ │ └── license.txt │ ├── cmap │ │ ├── cmap.mat │ │ └── linecolors.mat │ ├── ginputc │ │ ├── ginputc.m │ │ ├── ginputc_original.m │ │ └── license.txt │ └── reading │ │ ├── csv_to_mvar.m │ │ ├── read_from_csv.m │ │ └── read_from_mat.m ├── guis │ ├── MODA.fig │ ├── bayesian │ │ ├── Bayesian.fig │ │ ├── Bayesian.m │ │ ├── Bayesian_old.m │ │ └── Functions │ │ │ ├── CFprint.m │ │ │ ├── MODAbayes_intdelete.m │ │ │ ├── MODAbayes_loadfilt.m │ │ │ ├── bandpass_butter.m │ │ │ ├── bayesPhs.m │ │ │ ├── bayes_main.m │ │ │ ├── dirc.m │ │ │ ├── full_bayesian.m │ │ │ ├── loop_butter.m │ │ │ ├── surrogate.m │ │ │ └── sync_map.m │ ├── bispectrum │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── Bispectrum.fig │ │ ├── Bispectrum.m │ │ └── Functions │ │ │ ├── biphaseWavMod.m │ │ │ ├── biphaseWavNew.m │ │ │ ├── bispecWavMod.m │ │ │ ├── bispecWavNew.m │ │ │ ├── bispectrum_analysis.m │ │ │ ├── compareMatrix.m │ │ │ ├── myWt.m │ │ │ ├── python │ │ │ ├── biphaseWavPython.m │ │ │ ├── bispecWavPython.m │ │ │ └── wtAtf2Python.m │ │ │ ├── surrogate.m │ │ │ ├── wavsurrogate.m │ │ │ ├── wtAtf2.m │ │ │ └── wtAtfMod.m │ ├── coherence │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── CoherenceMulti.fig │ │ ├── CoherenceMulti.m │ │ └── Functions │ │ │ ├── MODAwpc.m │ │ │ ├── surrcalc.m │ │ │ ├── tlphcoh.m │ │ │ └── wphcoh.m │ ├── filtering │ │ ├── Filtering.fig │ │ ├── Filtering.m │ │ └── Functions │ │ │ ├── Fourier.m │ │ │ ├── MODAridge_filter.m │ │ │ ├── bandpass_butter.m │ │ │ ├── ecurve.m │ │ │ ├── loop_butter.m │ │ │ ├── rectfr.m │ │ │ └── ridge_extraction.m │ └── tfa │ │ ├── Functions │ │ ├── testwt.m │ │ ├── wft.m │ │ ├── wt.m │ │ └── wtwrapper.m │ │ ├── TimeFrequencyAnalysis.fig │ │ ├── TimeFrequencyAnalysis.m │ │ └── TimeFrequencyAnalysis_temp.fig └── images │ ├── MODAbanner3.svg │ ├── MODAbanner4.pdf │ ├── MODAbanner4.png │ ├── MODAbanner4.svg │ ├── MODAbanner5.pdf │ ├── MODAbanner5.png │ ├── MODAbanner5.svg │ ├── frontbanner.pdf │ ├── frontbanner.png │ ├── frontbanner.svg │ ├── logo.pdf │ ├── logo.png │ ├── logo.svg │ ├── logo2.png │ ├── physicslogo.png │ ├── physicslogoBW.png │ ├── splashscreen.pdf │ ├── splashscreen.png │ └── splashscreen.svg ├── docs ├── developer-guide.md ├── images │ ├── change_folder.png │ ├── data_orientation.png │ ├── launcher_window.png │ ├── sampling_frequency.png │ ├── timefrequency_empty.png │ ├── xlim.png │ └── zoom_signal.png └── user-guide.md ├── example_sigs ├── 1signal_10Hz.mat ├── 2signals_10Hz.mat ├── 6signals_10Hz.mat ├── IEEEsigs │ ├── IEEEex_10Hz.mat │ ├── xp_100Hz.mat │ └── xp_10Hz.mat ├── signals │ ├── X_0.mat │ ├── X_05.mat │ ├── X_12.mat │ ├── fm_square_200Hz.mat │ ├── freq_mod_200Hz.mat │ ├── load_first.mat │ ├── load_second.mat │ ├── noisy.mat │ ├── noisySIN.mat │ └── noisyyy.mat └── x.mat └── scripts └── fontsize.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore folder used for packaging code as Python libraries. 2 | packages/ 3 | 4 | # Ignore data files in the root of the repository. 5 | /*.mat 6 | /*.csv 7 | 8 | # Created by https://www.gitignore.io/api/matlab 9 | # Edit at https://www.gitignore.io/?templates=matlab 10 | 11 | ### MATLAB ### 12 | # Windows default autosave extension 13 | *.asv 14 | 15 | # OSX / *nix default autosave extension 16 | *.m~ 17 | 18 | # Compiled MEX binaries (all platforms) 19 | *.mex* 20 | 21 | # Packaged app and toolbox files 22 | *.mlappinstall 23 | *.mltbx 24 | 25 | # Generated helpsearch folders 26 | helpsearch*/ 27 | 28 | # Simulink code generation folders 29 | slprj/ 30 | sccprj/ 31 | 32 | # Matlab code generation folders 33 | codegen/ 34 | 35 | # Simulink autosave extension 36 | *.autosave 37 | 38 | # Octave session info 39 | octave-workspace 40 | 41 | # End of https://www.gitignore.io/api/matlab 42 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # Configures "pre-commit" to automatically update table of contents using "doctoc". 2 | repos: 3 | - repo: https://github.com/thlorenz/doctoc 4 | rev: v1.4.0 5 | hooks: 6 | - id: doctoc 7 | args: [".", # Apply to everything inside the root of the repository. 8 | '--title=## Table of Contents', # Set the title of the table of contents. 9 | "--maxlevel=2", # Only add sections with `#` or `##`. 10 | "--github"] # Use GitHub formatting. 11 | -------------------------------------------------------------------------------- /MODA.m: -------------------------------------------------------------------------------- 1 | function varargout = MODA(varargin) 2 | % MODA MATLAB code for MODA.fig 3 | % MODA, by itself, creates a new MODA or raises the existing 4 | % singleton*. 5 | % 6 | % H = MODA returns the handle to a new MODA or the handle to 7 | % the existing singleton*. 8 | % 9 | % MODA('CALLBACK',hObject,eventData,handles,...) calls the local 10 | % function named CALLBACK in MODA.M with the given input arguments. 11 | % 12 | % MODA('Property','Value',...) creates a new MODA or raises the 13 | % existing singleton*. Starting from the left, property value pairs are 14 | % applied to the GUI before MODA_OpeningFcn gets called. An 15 | % unrecognized property name or invalid value makes property application 16 | % stop. All inputs are passed to MODA_OpeningFcn via varargin. 17 | % 18 | % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one 19 | % instance to run (singleton)". 20 | % 21 | % See also: GUIDE, GUIDATA, GUIHANDLES 22 | 23 | % Edit the above text to modify the response to help MODA 24 | 25 | % Last Modified by GUIDE v2.5 03-Oct-2017 10:58:42 26 | 27 | % Begin initialization code - DO NOT EDIT 28 | folder = fileparts(which(mfilename)); 29 | addpath(genpath(folder)); 30 | gui_Singleton = 1; 31 | gui_State = struct('gui_Name', mfilename, ... 32 | 'gui_Singleton', gui_Singleton, ... 33 | 'gui_OpeningFcn', @MODA_OpeningFcn, ... 34 | 'gui_OutputFcn', @MODA_OutputFcn, ... 35 | 'gui_LayoutFcn', [] , ... 36 | 'gui_Callback', []); 37 | if nargin && ischar(varargin{1}) 38 | gui_State.gui_Callback = str2func(varargin{1}); 39 | end 40 | 41 | if nargout 42 | [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); 43 | else 44 | gui_mainfcn(gui_State, varargin{:}); 45 | end 46 | % End initialization code - DO NOT EDIT 47 | 48 | 49 | % --- Executes just before MODA is made visible. 50 | function MODA_OpeningFcn(hObject, eventdata, handles, varargin) 51 | % This function has no output args, see OutputFcn. 52 | % hObject handle to figure 53 | % eventdata reserved - to be defined in a future version of MATLAB 54 | % handles structure with handles and user data (see GUIDATA) 55 | % varargin command line arguments to MODA (see VARARGIN) 56 | 57 | % Choose default command line output for MODA 58 | handles.output = hObject; 59 | movegui(gcf,'center') 60 | axes(handles.logo) 61 | matlabImage = imread('frontbanner.png'); 62 | image(matlabImage) 63 | axis off 64 | %axis image 65 | 66 | % Update handles structure 67 | guidata(hObject, handles); 68 | 69 | % UIWAIT makes MODA wait for user response (see UIRESUME) 70 | % uiwait(handles.figure1); 71 | 72 | 73 | % --- Outputs from this function are returned to the command line. 74 | function varargout = MODA_OutputFcn(hObject, eventdata, handles) 75 | % varargout cell array for returning output args (see VARARGOUT); 76 | % hObject handle to figure 77 | % eventdata reserved - to be defined in a future version of MATLAB 78 | % handles structure with handles and user data (see GUIDATA) 79 | 80 | % Get default command line output from handles structure 81 | varargout{1} = handles.output; 82 | 83 | 84 | % --- Executes on button press in TFA. 85 | function TFA_Callback(~,~,~) 86 | 87 | TimeFrequencyAnalysis 88 | 89 | 90 | % --- Executes on button press in WPC. 91 | function WPC_Callback(~,~,~) 92 | 93 | CoherenceMulti 94 | 95 | 96 | % --- Executes on button press in filt. 97 | function filt_Callback(~,~,~) 98 | 99 | Filtering 100 | 101 | 102 | % --- Executes on button press in bisp. 103 | function bisp_Callback(~,~,~) 104 | 105 | Bispectrum 106 | 107 | 108 | % --- Executes on button press in bayesian. 109 | function bayesian_Callback(~,~,~) 110 | 111 | Bayesian 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Table of Contents 4 | 5 | - [MODA](#moda) 6 | - [Purpose](#purpose) 7 | - [Getting started](#getting-started) 8 | - [References](#references) 9 | - [Example applications](#example-applications) 10 | 11 | 12 | 13 | # MODA 14 | 15 | [![DOI](https://zenodo.org/badge/194114858.svg)](https://zenodo.org/badge/latestdoi/194114858) 16 | 17 | MODA (Multiscale Oscillatory Dynamics Analysis) is a numerical toolbox developed by the 18 | [Nonlinear & Biomedical Physics group](https://www.lancaster.ac.uk/physics/research/experimental-condensed-matter/nonlinear-and-biomedical-physics/) at [Lancaster University](https://www.lancaster.ac.uk/physics/) and the Nonlinear Dynamics and Synergetic Group at the Faculty of Electrical 19 | Engineering, University of Ljubljana, Slovenia under the supervision of Aneta Stefanovska. 20 | 21 | > **Note:** A Python implementation of MODA, [PyMODA](https://github.com/luphysics/PyMODA), is currently in development. PyMODA does not require a MATLAB license. 22 | 23 | ## Purpose 24 | 25 | MODA is designed for analysing real-life time-series 26 | that are assumed to be the output of some *a priori* unknown non-autonomous dynamical system, 27 | and deriving important properties about this dynamical system from the time-series. 28 | 29 | MODA includes 30 | methods both for analysing the recordings of a single signal over time, and for analysing a set 31 | of recordings of multiple different signals over time. In particular, it has tools for analysing 32 | bivariate time-series consisting of the simultaneous recordings of two different signals over time, 33 | with a view to examining possible connections between the two signals. 34 | 35 | ## Getting started 36 | 37 | To get started, please see the [User Guide](/docs/user-guide.md). 38 | 39 | # References 40 | 41 | #### Overview 42 | 1. J Newman, G Lancaster and A Stefanovska, “Multiscale Oscillatory Dynamics 43 | Analysis”, v1.01, User Manual, 2018. 44 | 2. P Clemson, G Lancaster, A Stefanovska, “Reconstructing time-dependent dynamics”, *Proc IEEE* 45 | **104**, 223–241 (2016). 46 | 3. P Clemson, A Stefanovska, “Discerning non-autonomous dynamics”, *Phys Rep* **542**, 297-368 (2014). 47 | 48 | #### Time-Frequency Analysis 49 | 1. D Iatsenko, P V E McClintock, A Stefanovska, “Linear and synchrosqueezed time-frequency 50 | representations revisited: Overview, standards of use, resolution, reconstruction, concentration, and 51 | algorithms”, *Dig Sig Proc* **42**, 1–26 (2015). 52 | 2. P Clemson, G Lancaster, A Stefanovska, “Reconstructing time-dependent dynamics”, *Proc IEEE* 53 | **104**, 223–241 (2016). 54 | 3. G Lancaster, D Iatsenko, A Pidde, V Ticcinelli, A Stefanovska, “Surrogate data for hypothesis testing of 55 | physical systems”, *Phys Rep* **748**, 1–60 (2018). 56 | 57 | #### Wavelet Phase Coherence 58 | 1. Bandrivskyy A, Bernjak A, McClintock P V E, Stefanovska A, “Wavelet phase coherence analysis: 59 | Application to skin temperature and blood flow”, *Cardiovasc Engin* **4**, 89–93 (2004). 60 | 2. Sheppard L W, Stefanovska A, McClintock P V E, “Testing for time-localised coherence in bivariate 61 | data”, *Phys. Rev. E* **85**, 046205 (2012). 62 | 63 | #### Ridge Extraction & Filtering 64 | 1. D Iatsenko, P V E McClintock, A Stefanovska, “Nonlinear mode decomposition: A noise-robust, 65 | adaptive decomposition method”, *Phys Rev E* **92**, 032916 (2015). 66 | 2. D Iatsenko, P V E McClintock, A Stefanovska, “Extraction of instantaneous frequencies from ridges in 67 | time-frequency representations of signals”, *Sig Process* **125**, 290–303 (2016). 68 | 69 | #### Wavelet Bispectrum Analysis 70 | 1. J Jamšek, A Stefanovska, P V E McClintock, “Wavelet bispectral analysis for the study of interactions 71 | among oscillators whose basic frequencies are significantly time variable”, *Phys Rev E* **76**, 046221 72 | (2007). 73 | 2. J Jamšek, M Paluš, A Stefanovska, “Detecting couplings between interacting oscillators with 74 | time-varying basic frequencies: Instantaneous wavelet bispectrum and information theoretic approach”, 75 | *Phys Rev E* **81**, 036207 (2010). 76 | 3. J Newman, A Pidde, A Stefanovska, “Defining the wavelet bispectrum”, submitted (2019). 77 | 78 | #### Dynamical Bayesian Inference 79 | 1. V N Smelyanskiy, D G Luchinsky, A Stefanovska, P V E McClintock, “Inference of a nonlinear stochastic model of the cardiorespiratory 80 | interaction”, *Phys Rev Lett* **94**, 098101 (2005). 81 | 2. T Stankovski, A Duggento, P V E McClintock, A Stefanovska, “Inference of time-evolving coupled dynamical systems in the presence of noise”, 82 | *Phys Rev Lett* **109**, 024101 (2012). 83 | 3. T Stankovski, A Duggento, P V E McClintock, A Stefanovska, “A tutorial on time-evolving dynamical Bayesian inference”, *Eur Phys J – Special 84 | Topics* **223**, 2685-2703 (2014). 85 | 4. T Stankovski, T Pereira, P V E McClintock, A Stefanovska, “Coupling functions: Universal insights into dynamical interaction mechanisms”, *Rev 86 | Mod Phys* **89**, 045001 (2017). 87 | 5. Special issue of the *Philos Trans Royal Soc A* (2019) with contributions by Kuramoto and others. 88 | 89 | # Example applications 90 | 91 | #### Wavelet Phase Coherence 92 | 1. Sheppard L W, Vuksanović V, McClintock P V E, Stefanovska A, Oscillatory dynamics of 93 | vasoconstriction and vasodilation identified by time-localized phase coherence *Phys Med Biol* 94 | **56**, 3583–3601 (2011). 95 | 2. A Bernjak, J Cui, S Iwase, T Mano, A Stefanovska, D L Eckberg, “Human sympathetic outflows to skin 96 | and muscle target organs fluctuate concordantly over a wide range of time-varying frequencies”, *J 97 | Physiol* **590**, 363–375 (2012). 98 | 3. P Kvandal, L Sheppard, S A Landsverk, A Stefanovska, K A Kirkebøen, “Impaired cerebrovascular 99 | reactivity after acute traumatic brain injury can be detected by wavelet phase coherence analysis of the 100 | intracranial and arterial blood pressure signals”, *J Clin Monit Comput* **27**, 375-383 (2013). 101 | 102 | #### Ridge Extraction & Filtering 103 | 1. D Iatsenko, A Bernjak, T Stankovski, Y Shiogai, P J Owen-Lynch, P B M Clarkson, P V E McClintock, 104 | A Stefanovska, “Evolution of cardiorespiratory interactions with age”, *Phil Trans R Soc A* **371**, 105 | 20110622 (2013). 106 | 2. V Ticcinelli, T Stankovski, D Iatsenko, A Bernjak, A E Bradbury, A R Gallagher, P B M Clarkson, P V 107 | E McClintock, A Stefanovska, “Coherence and coupling functions reveal microvascular impairment in 108 | treated hypertension”, *Front Physiol* **8**, 749 (2017). 109 | 3. YA Abdulhameed, G Lancaster, PVE McClintock, A Stefanovska, “On the suitability of laser-Doppler 110 | flowmetry for capturing microvascular blood flow dynamics from darkly pigmented skin”, *Physiol Meas*, 111 | **40**, 074005 (2019). 112 | 113 | #### Wavelet Bispectrum Analysis 114 | 1. J Jamšek, A Stefanovska, P V E McClintock, “Nonlinear cardio-respiratory interactions revealed by 115 | time-phase bispectral analysis”, *Phys Medicine Biol* **49**, 4407 (2004). 116 | 117 | #### Dynamical Bayesian Inference 118 | 1. B Musizza, A Stefanovska, P V E McClintock, M Paluš, J Petrovčič, S Ribarič, F F Bajrović, “Interactions between cardiac, respiratory and 119 | EEG-delta oscillations in rats during anaesthesia”, *J Physiol* **580** 315–326 (2007). 120 | 2. T Stankovski, V Ticcinelli, P V E McClintock, A Stefanovska, “Coupling functions in networks of oscillators”, *New J Phys* **17**, 035002 (2015). 121 | 3. T Stankovski, S Petkoski, J Ræder, A F Smith, P V E McClintock, A Stefanovska, “Alterations in the coupling functions between cortical and 122 | cardio-respiratory oscillations due to anaesthesia with propofol and sevoflurane”, *Philos Trans Royal Soc A* **374**, 20150186 (2016). 123 | 4. V Ticcinelli, T Stankovski, D Iatsenko, A Bernjak, A E Bradbury, A R Gallagher, P B M Clarkson, P V E McClintock, A Stefanovska, “Coherence 124 | and coupling functions reveal microvascular impairment in treated hypertension”, *Front Physiol* **8**, 749 (2017). 125 | -------------------------------------------------------------------------------- /User Manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/User Manual.pdf -------------------------------------------------------------------------------- /allguis/codes/Graphics/clear_axes_lines.m: -------------------------------------------------------------------------------- 1 | function clear_axes_lines( h ) 2 | %CLEAR_AXES_LINES Deletes lines on an axes 3 | child_handles = allchild(h); 4 | for i = 1:size(child_handles,1) 5 | if(strcmp(get(child_handles(i),'Type'),'line')) 6 | delete(child_handles(i)) 7 | end 8 | end 9 | 10 | -------------------------------------------------------------------------------- /allguis/codes/Graphics/clear_axes_points.m: -------------------------------------------------------------------------------- 1 | function clear_axes_points( h ) 2 | %CLEAR_AXES_POINTS Deletes points on an axes 3 | child_handles = allchild(h); 4 | for i = 1:size(child_handles,1) 5 | if(strcmp(get(child_handles(i),'Type'),'line')) 6 | xdat = get(child_handles(i),'XData'); 7 | if(length(xdat) == 1) 8 | delete(child_handles(i)) 9 | end 10 | elseif(strcmp(get(child_handles(i),'Type'),'text')) 11 | delete(child_handles(i)) 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /allguis/codes/Graphics/fillsig.m: -------------------------------------------------------------------------------- 1 | % Fill between curves based on threshold 2 | 3 | function val=fillsig(xvec,sig1,sig2,thresh1,thresh2,direction,col) 4 | % sig1, sig2 - signals to shade between 5 | % thresh1, thresh2 - signals to calculate significance 6 | % xvec=freq; 7 | % sig1=pLANH_PNH; 8 | % sig2=x; 9 | % direction='less'; % Can be 'greater' 10 | % col=[.5 .5 .5]; 11 | % 12 | % figure 13 | % semilogx(xvec,sig1) 14 | % hold on 15 | % semilogx(xvec,sig2,'r--'); 16 | 17 | if strcmp(direction,'less') 18 | n=find(thresh1thresh2); 21 | end 22 | 23 | if isempty(n) 24 | val=0; 25 | else 26 | val=1; 27 | end 28 | 29 | d=diff(n); 30 | n2=find(d>1); 31 | 32 | if isfinite(n2) 33 | 34 | if length(n2)==1 35 | ar{1}=n(1:n2); 36 | ar{2}=n(n2+1:end); 37 | else 38 | ar{1}=n(1:n2(1)); 39 | ar{length(n2)+1}=n(n2(end)+1:end); 40 | for k=1:length(n2)-1 41 | ar{k+1}=n(n2(k)+1:n2(k+1)); 42 | end 43 | 44 | end 45 | else 46 | ar{1}=n; 47 | end 48 | s=size(ar); 49 | for j=1:s(2) 50 | f=xvec(ar{j}); 51 | X=[f',fliplr(f')]; 52 | Y=[sig1(ar{j}),fliplr(sig2(ar{j}))]; 53 | fill(X,Y,col,'EdgeColor',col) 54 | end 55 | 56 | -------------------------------------------------------------------------------- /allguis/codes/Universal/MODATFAcalc.m: -------------------------------------------------------------------------------- 1 | function handles=MODATFAcalc(hObject, eventdata, handles,ty) 2 | %ty - type of calculation (1=multiple, 2=single) 3 | set(handles.plot_TS,'Enable','on') 4 | set(handles.save_3dplot,'Enable','on') 5 | set(handles.save_both_plot,'Enable','on') 6 | set(handles.save_avg_plot,'Enable','on') 7 | set(handles.save_mm_plot,'Enable','on') 8 | 9 | set(handles.wt_single,'Enable','off') 10 | set(handles.wavlet_transform,'Enable','off') 11 | if ty==2 12 | set(handles.save_WT_coeff,'Enable','on') 13 | elseif ty==1 14 | set(handles.save_WT_coeff,'Enable','off') 15 | end 16 | set(handles.save_session,'Enable','on') 17 | 18 | handles.failed=false; 19 | try 20 | % Obtain parameters from GUI 21 | fmax = str2double(get(handles.max_freq,'String')); 22 | fmin = str2double(get(handles.min_freq,'String')); 23 | fs = handles.sampling_freq; 24 | f0 = str2double(get(handles.central_freq,'String')); A=f0<=0.4; 25 | items = get(handles.wavelet_type,'String'); 26 | index_selected = get(handles.wavelet_type,'Value'); 27 | wtype = items{index_selected}; B=strcmp(wtype,'Bump'); 28 | handles.fc = str2double(get(handles.central_freq,'String')); 29 | 30 | if (A+0)+(B+0)==2 31 | errordlg('The bump wavelet requires that f0 > 0.4. Please enter a higher value.','Parameter Error'); 32 | handles.failed = true; 33 | set(handles.wt_single,'Enable','on') 34 | set(handles.wavlet_transform,'Enable','on') 35 | return; 36 | end 37 | 38 | if fmax>fs/2 39 | errordlg(['Maximum frequency cannot be higher than the Nyquist frequency. Please enter a value less than or equal to ',num2str(fs/2),' Hz.'],'Parameter Error'); 40 | handles.failed = true; 41 | set(handles.wt_single,'Enable','on') 42 | set(handles.wavlet_transform,'Enable','on') 43 | return; 44 | end 45 | 46 | %% Forces user to input minimum frequency for WFT, and changes resolution parameter according to fr/fmin, where fr is the user input resolution 47 | if handles.calc_type==2 && isnan(fmin) 48 | errordlg(['Minimum frequency must be specified for WFT'],'Parameter Error'); 49 | handles.failed = true; 50 | set(handles.wt_single,'Enable','on') 51 | set(handles.wavlet_transform,'Enable','on') 52 | return; 53 | elseif handles.calc_type==2 54 | handles.fc=f0/fmin; 55 | end 56 | 57 | if isnan(fs) 58 | errordlg('Sampling frequency must be specified','Parameter Error'); 59 | handles.failed = true; 60 | end 61 | 62 | if handles.calc_type == 1 63 | set(handles.status,'String','Calculating Wavelet Transform...'); 64 | %status_Callback(hObject, eventdata, handles, 'Calculating Wavelet Transform...'); 65 | else 66 | set(handles.status,'String','Calculating Windowed Fourier Transform...'); 67 | %status_Callback(hObject, eventdata, handles, 'Calculating Windowed Fourier Transform...'); 68 | end 69 | 70 | 71 | items = get(handles.wavelet_type,'String'); 72 | index_selected = get(handles.wavelet_type,'Value'); 73 | wtype = items{index_selected}; 74 | 75 | if strcmp(wtype,'Kaiser') 76 | a=str2double(get(handles.kaisera,'String')); 77 | wtype = ['kaiser-',num2str(a)]; 78 | else 79 | end 80 | 81 | items = get(handles.preprocess,'String'); 82 | index_selected = get(handles.preprocess,'Value'); 83 | ppselect = items{index_selected}; 84 | 85 | items = get(handles.cutedges,'String'); 86 | index_selected = get(handles.cutedges,'Value'); 87 | cutselect = items{index_selected}; 88 | 89 | if ~isfield(handles,'sig') 90 | errordlg('Signal not found','Signal Error'); 91 | handles.failed = true; 92 | end 93 | sig = handles.sig; 94 | 95 | xl = csv_to_mvar(get(handles.xlim,'String')); 96 | xl = xl.*fs; 97 | xl(2) = min(xl(2),size(sig,2)); 98 | xl(1) = max(xl(1),1); 99 | xl = xl./fs; 100 | time_axis = xl(1):1/fs:xl(2); 101 | if length(time_axis)>=2000 102 | screensize = max(get(groot,'Screensize')); 103 | under_sample = floor(size(sig,2)/screensize); 104 | else 105 | under_sample = 1; 106 | end 107 | if handles.calc_type == 2 108 | under_sample = ceil(under_sample*3.5); 109 | end 110 | handles.time_axis_us = time_axis(1:under_sample:end); 111 | n = size(handles.sig,1) ; 112 | handles.WT = cell(n, 1); 113 | 114 | % Taking only selected part of the signal 115 | xl = get(handles.xlim,'String'); 116 | xl = csv_to_mvar(xl); 117 | xl = xl.*fs; 118 | xl(2) = min(xl(2),size(handles.sig,2)); 119 | xl(1) = max(xl(1),1); 120 | handles.sig_cut = sig(:,xl(1):xl(2)); 121 | 122 | 123 | if handles.calc_type==1 124 | if fmin<=1/(length(handles.sig_cut)/fs) 125 | errordlg(['WT minimum frequency too low. To automatically calculate for minimum possible frequency leave "Min Freq" field blank.'],'Parameter Error'); 126 | handles.failed = true; 127 | set(handles.wt_single,'Enable','on') 128 | set(handles.wavlet_transform,'Enable','on') 129 | return; 130 | end 131 | else 132 | end 133 | if handles.calc_type == 1 134 | set(handles.status,'String','Calculating Wavelet Transform...'); 135 | else 136 | set(handles.status,'String','Calculating Windowed Fourier Transform...'); 137 | end 138 | 139 | handles.amp_WT = cell(n,1); 140 | handles.pow_WT = cell(n,1); 141 | handles.pow_arr = cell(n,1); 142 | handles.amp_arr = cell(n,1); 143 | 144 | handles.h = waitbar(0,'Calculating transform...',... 145 | 'CreateCancelBtn',... 146 | 'setappdata(gcbf,''canceling'',1)'); 147 | setappdata(handles.h,'canceling',0) 148 | guidata(hObject,handles); 149 | 150 | if ty==2 151 | I=get(handles.signal_list,'Value'); 152 | else 153 | I=1:n; 154 | end 155 | 156 | for p = I 157 | if getappdata(handles.h,'canceling') 158 | break; 159 | end 160 | 161 | % Number of signals being transformed. 162 | if ty==1, count=n; 163 | else, count=1; end 164 | 165 | if handles.calc_type == 1 166 | set(handles.status,'String',sprintf('Calculating Wavelet Transform of Signal %d/%d',p,count)); 167 | 168 | else 169 | set(handles.status,'String',sprintf('Calculating Windowed Fourier Transform of Signal %d/%d',p,count)); 170 | 171 | end 172 | wtwrapper; 173 | handles.WT=WT; 174 | WTamp = abs(WT); 175 | WTpow = abs(WT).^2; 176 | handles.pow_arr{p,1} = nanmean(WTpow.'); % Calculating Average Power 177 | handles.amp_arr{p,1} = nanmean(WTamp.'); % Calculating Average Amplitude 178 | 179 | handles.amp_WT{p,1} = WTamp(:,1:under_sample:end); 180 | handles.pow_WT{p,1} = WTpow(:,1:under_sample:end); 181 | waitbar(p/n,handles.h); 182 | end 183 | guidata(hObject,handles); 184 | 185 | delete(handles.h); 186 | set(handles.wt_single,'Enable','on') 187 | set(handles.wavlet_transform,'Enable','on') 188 | set(handles.mat_save,'Enable','on') 189 | set(handles.csv_save,'Enable','on') 190 | set(handles.save_WT_coeff,'Enable','on') 191 | set(handles.save_session,'Enable','on') 192 | catch e 193 | errordlg(e.message,'Error'); 194 | handles.failed = true; 195 | set(handles.wt_single,'Enable','on') 196 | set(handles.wavlet_transform,'Enable','on') 197 | delete(handles.h) 198 | rethrow(e) 199 | end 200 | guidata(hObject,handles); -------------------------------------------------------------------------------- /allguis/codes/Universal/MODAclose.m: -------------------------------------------------------------------------------- 1 | % MODA GUI closing function 2 | function MODAclose(hObject,handles) 3 | if isfield(handles,'sig') 4 | choice = questdlg('Are you sure you want to close? Unsaved data will be lost.', ... 5 | 'Exit','Yes','No','default'); 6 | switch choice 7 | case 'Yes' 8 | if isfield(handles,'h') 9 | delete(handles.h) 10 | else 11 | end 12 | delete(hObject); 13 | return; 14 | 15 | case 'No' 16 | end 17 | 18 | if isempty(choice) 19 | return; 20 | end 21 | else 22 | delete(hObject); 23 | end 24 | -------------------------------------------------------------------------------- /allguis/codes/Universal/MODAcsvsave.m: -------------------------------------------------------------------------------- 1 | function data=MODAcsvsave(D,ind) 2 | %D=Filtered_data; 3 | % ind=1 - filtered data 4 | % ind=2 - filtered phases/freq 5 | % ind=3 - filtered amplitudes 6 | 7 | L=length(D.Time); 8 | Nb=size(D.Freq_bands,1); 9 | 10 | data{1,1}='MODA v1.0 - Filtering & Ridge Extraction'; 11 | data{2,1}=date; 12 | data{3,1}=[]; 13 | data{4,1}='PARAMETERS'; 14 | data{5,1}='Sampling frequency (Hz)'; 15 | data{5,2}=D.Sampling_frequency; 16 | data{6,1}='Filter type'; 17 | data{6,2}=D.Filter_type; 18 | if isfield(D,'Preprocessing') 19 | data{7,1}='Preprocessing'; 20 | data{7,2}=D.Preprocessing; 21 | else 22 | end 23 | % data{8,1}='Cut Edges'; 24 | % data{8,2}=D.Cut_Edges; 25 | data{9,1}='Time start (s)'; 26 | data{9,2}=min(D.Time); 27 | data{10,1}='Time end (s)'; 28 | data{10,2}=max(D.Time); 29 | for n=1:Nb 30 | data{n+10,1}=['Band ',num2str(n)]; 31 | data{n+10,2}=D.Freq_bands{n}; 32 | c=n+10; 33 | end 34 | 35 | if isfield(D,'Ridge_recon') 36 | Ns=size(D.Ridge_recon,1); 37 | data{c+1,1}='Analysis_type'; 38 | data{c+1,2}=D.Analysis_type; 39 | data{c+2,1}='Frequency_resolution'; 40 | data{c+2,2}=D.Frequency_resolution; 41 | else 42 | Ns=size(D.Filtered_sigs,1); 43 | end 44 | 45 | dstart=c+4; 46 | 47 | data{dstart,1}='Time (s)'; 48 | for l=1:L; 49 | data{l+dstart,1}=D.Time(l); 50 | end 51 | if ind==1 52 | if isfield(D,'Filtered_sigs') 53 | 54 | for j=1:Ns 55 | for k=1:Nb 56 | data{dstart,1+(Ns*(k-1)+j)}=['Sig',num2str(j),' Band',num2str(k)]; 57 | for b=1:L 58 | data{b+dstart,1+(Ns*(k-1)+j)}=D.Filtered_sigs{j,k}(b); 59 | end 60 | 61 | end 62 | 63 | end 64 | 65 | else 66 | for j=1:Ns 67 | for k=1:Nb 68 | data{dstart,1+(Ns*(k-1)+j)}=['Sig',num2str(j),' Band',num2str(k)]; 69 | for b=1:L 70 | data{b+dstart,1+(Ns*(k-1)+j)}=D.Ridge_recon{j,k}(b); 71 | end 72 | 73 | end 74 | 75 | end 76 | 77 | end 78 | elseif ind==2 79 | 80 | if isfield(D,'Filtered_sigs') 81 | 82 | for j=1:Ns 83 | for k=1:Nb 84 | data{dstart,1+(Ns*(k-1)+j)}=['Phase',num2str(j),' Band',num2str(k)]; 85 | for b=1:L 86 | data{b+dstart,1+(Ns*(k-1)+j)}=D.Filtered_phases{j,k}(b); 87 | end 88 | 89 | end 90 | 91 | end 92 | 93 | else 94 | for j=1:Ns 95 | for k=1:Nb 96 | data{dstart,1+(Ns*(k-1)+j)}=['Freq',num2str(j),' Band',num2str(k)]; 97 | for b=1:L 98 | data{b+dstart,1+(Ns*(k-1)+j)}=D.Ridge_frequency{j,k}(b); 99 | end 100 | 101 | end 102 | 103 | end 104 | 105 | end 106 | elseif ind==3 107 | 108 | if isfield(D,'Filtered_sigs') 109 | 110 | for j=1:Ns 111 | for k=1:Nb 112 | data{dstart,1+(Ns*(k-1)+j)}=['Amp',num2str(j),' Band',num2str(k)]; 113 | for b=1:L 114 | data{b+dstart,1+(Ns*(k-1)+j)}=D.Filtered_amplitudes{j,k}(b); 115 | end 116 | 117 | end 118 | 119 | end 120 | 121 | else 122 | for j=1:Ns 123 | for k=1:Nb 124 | data{dstart,1+(Ns*(k-1)+j)}=['Amp',num2str(j),' Band',num2str(k)]; 125 | for b=1:L 126 | data{b+dstart,1+(Ns*(k-1)+j)}=D.Ridge_amplitude{j,k}(b); 127 | end 128 | 129 | end 130 | 131 | end 132 | 133 | end 134 | else 135 | end 136 | -------------------------------------------------------------------------------- /allguis/codes/Universal/MODAload.m: -------------------------------------------------------------------------------- 1 | % Load previous session 2 | 3 | function handles=MODAload 4 | 5 | [filename,pathname] = uigetfile('*.*'); % Request file location from user 6 | name = fullfile(pathname,filename); 7 | 8 | handles = load(name); % Load data -------------------------------------------------------------------------------- /allguis/codes/Universal/MODAread.m: -------------------------------------------------------------------------------- 1 | % MODA data loading function 2 | 3 | function [handles,sig,E]=MODAread(handles,type,varargin) 4 | 5 | % Parse varargin for whether the number of signals should be even. 6 | % This is used in phase coherence, bispectrum analysis and 7 | % Bayesian inference. 8 | even = false; 9 | n = length(varargin); 10 | for k = 1:n 11 | if strcmp("even", varargin{k}) 12 | even = true; 13 | break; 14 | end 15 | end 16 | 17 | E=1; 18 | set(handles.status,'String','Importing Signal...'); % Update status 19 | 20 | [filename,pathname] = uigetfile('*.*'); % Request file location from user 21 | name = fullfile(pathname,filename); 22 | 23 | if filename==0 24 | sig=0; 25 | return; 26 | end 27 | 28 | try 29 | sig = load(name); % Load data. 30 | catch exception 31 | % Catch exception when opening Excel CSV files with BOM. 32 | sig = readmatrix(name); 33 | end 34 | 35 | if isstruct(sig) % If loaded signal is a MATLAB structure, convert to array 36 | sig=struct2array(sig); 37 | else 38 | end 39 | 40 | handles.sampling_freq = str2double(cell2mat(newid(['Enter the sampling frequency of the data (',filename,') in Hz']))); 41 | fs = handles.sampling_freq; 42 | 43 | if isnan(fs) 44 | errordlg('Sampling frequency must be specified') 45 | E=0; 46 | return; 47 | end 48 | 49 | choice = questdlg('Select Orientation of Data set?', ... 50 | 'Data Import','Column wise','Row wise','default'); 51 | switch choice 52 | case 'Column wise' 53 | sig = sig'; 54 | 55 | end 56 | 57 | if isempty(choice) 58 | errordlg('Data set orientation must be specified') 59 | E=0; 60 | return; 61 | end 62 | 63 | num_signals = length(sig(:,1)); 64 | 65 | % If there are an odd number of signals but an even number must be 66 | % supplied, remove the last one. 67 | % Only do this if there are 3 or more signals, because users may want to 68 | % analyse a single signal. 69 | if even && num_signals > 2 && mod(num_signals, 2) ~= 0 70 | sig = sig(1:end-1,:); 71 | end 72 | 73 | handles.sig = sig; 74 | handles.sig_cut=handles.sig; 75 | handles.sig_pp=sig; 76 | time = linspace(0,length(handles.sig)/handles.sampling_freq,length(handles.sig)); 77 | handles.time_axis = time; 78 | handles.time_axis_cut = time; 79 | handles.xl=[handles.time_axis_cut(1) handles.time_axis_cut(end)]; 80 | 81 | if type==1 82 | N=size(sig); 83 | if N(1)==1; 84 | handles.sig=[handles.sig;handles.sig]; 85 | handles.sig_cut=[handles.sig;handles.sig]; 86 | handles.sig_pp=[handles.sig;handles.sig]; 87 | else 88 | 89 | %% Plot time series 90 | linkaxes([handles.time_series_1 handles.time_series_2],'x'); % Ensures axis limits are identical for both plots 91 | plot(handles.time_series_1,handles.time_axis,handles.sig(1,:),'color',handles.linecol(1,:)); 92 | xlim(handles.time_series_1,[0 handles.time_axis(end)]); 93 | plot(handles.time_series_2,handles.time_axis,handles.sig(1+size(handles.sig,1)/2,:),'color',handles.linecol(1,:)); 94 | xlim(handles.time_series_2,[0 handles.time_axis(end)]); 95 | xlabel(handles.time_series_2,'Time (s)'); 96 | ylabel(handles.time_series_1,'Sig 1'); 97 | ylabel(handles.time_series_2,'Sig 2'); 98 | 99 | if mod(N(1),2)==1; 100 | errordlg('Number of data sets must be even','Data Error'); 101 | E=0; 102 | return; 103 | 104 | end 105 | 106 | %% Create signal list 107 | if isfield(handles,'signal_list') 108 | list = cell(size(sig,1)/2,1); 109 | list{1,1} = 'Signal Pair 1'; 110 | 111 | for i = 2:size(sig,1)/2 112 | list{i,1} = sprintf('Signal Pair %d',i); 113 | end 114 | 115 | set(handles.signal_list,'String',list); 116 | else 117 | end 118 | end 119 | else 120 | 121 | %% Plot time series 122 | plot(handles.time_series,handles.time_axis,sig(1,:),'color',handles.linecol(1,:)); 123 | xlim(handles.time_series,[0 handles.time_axis(end)]); 124 | xlabel(handles.time_series,'Time (s)'); 125 | ylabel(handles.time_series,'Sig'); 126 | 127 | end 128 | 129 | 130 | 131 | 132 | set(handles.plot_TS,'Enable','on') 133 | 134 | set(handles.status,'String','Select data and define parameters'); 135 | 136 | 137 | -------------------------------------------------------------------------------- /allguis/codes/Universal/MODAreadcheck.m: -------------------------------------------------------------------------------- 1 | % MODA data loading check function 2 | 3 | function [handles,A]=MODAreadcheck(handles) 4 | 5 | handles.it=handles.it+1; 6 | A=0; 7 | if handles.it>1 8 | choice = questdlg('Loading new data will erase unsaved data. Continue?', ... 9 | 'Data Import','Yes','No','default'); 10 | switch choice 11 | case 'Yes' 12 | A=1; 13 | 14 | case 'No' 15 | 16 | A=0; 17 | 18 | end 19 | 20 | else 21 | A=1; 22 | end -------------------------------------------------------------------------------- /allguis/codes/Universal/MODAsave.m: -------------------------------------------------------------------------------- 1 | % Save current session 2 | 3 | function MODAsave(handles) 4 | try 5 | [FileName,PathName] = uiputfile('.mat','Save data as'); 6 | save_location = strcat(PathName,FileName); 7 | 8 | save(save_location,'handles'); 9 | catch e 10 | errordlg(e.message,'Error') 11 | rethrow(e) 12 | end 13 | 14 | -------------------------------------------------------------------------------- /allguis/codes/Universal/MODAsettings.m: -------------------------------------------------------------------------------- 1 | % MODA GUI settings function 2 | 3 | function handles=MODAsettings(hObject,handles) 4 | 5 | % Positioning 6 | screensize = get( groot, 'Screensize' ); 7 | x=screensize(3); 8 | y=screensize(4); 9 | if x<1600 || y<860 10 | GUIsize=[x y]; 11 | set(gcf,'units','pixels','position',[0 0 GUIsize(1) GUIsize(2)]) 12 | else 13 | GUIsize=[1600 860]; 14 | x2=x-GUIsize(1); 15 | y2=y-GUIsize(2); 16 | set(gcf,'units','pixels','position',[x2/2 y2/2 GUIsize(1) GUIsize(2)]) 17 | end 18 | 19 | % Colours 20 | load('cmap.mat') 21 | handles.cmap=cmap; 22 | handles.linecol= cmap([1,18,40,50,60,64,15],:); 23 | handles.line2width=2; 24 | 25 | % Logos 26 | axes(handles.logo); 27 | matlabImage = imread('physicslogo.png'); 28 | image(matlabImage) 29 | axis off 30 | axis image 31 | 32 | axes(handles.nbmplogo); 33 | matlabImage = imread('MODAbanner5.png'); 34 | image(matlabImage) 35 | axis off 36 | axis image 37 | 38 | % Fonts 39 | h = findall(0,'Type','uicontrol'); 40 | set(h,'FontUnits','points'); 41 | set(h,'FontSize',8); 42 | set(h,'FontUnits','normalized'); 43 | 44 | % Default calculation types 45 | handles.calc_type = 1; 46 | handles.plot_type = 2; 47 | 48 | handles.it=0; % Number of times data has been loaded 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /allguis/codes/Universal/imodwt.m: -------------------------------------------------------------------------------- 1 | function xrec = imodwt(w,varargin) 2 | %IMODWT Inverse maximal overlap discrete wavelet transform. 3 | % XREC = IMODWT(W) returns the reconstructed signal based on the maximal 4 | % overlap discrete wavelet transform (MODWT) coefficients in W. W is a 5 | % LEV+1-by-N matrix which is the MODWT of an N-point input signal down to 6 | % level LEV. By default, IMODWT assumes that you used the 'sym4' wavelet 7 | % with periodic boundary handling to obtain the MODWT. If you do not 8 | % modify the coefficients, XREC is a perfect reconstruction of the 9 | % signal. 10 | % 11 | % XREC = IMODWT(W,WNAME) reconstructs the signal using the wavelet WNAME. 12 | % WNAME must be the same wavelet used in the analysis of the signal with 13 | % MODWT. 14 | % 15 | % XREC = IMODWT(W,Lo,Hi) reconstructs the signal using the scaling 16 | % filter Lo and the wavelet filter Hi. You cannot specify both WNAME and 17 | % Lo and Hi. Lo and Hi must be the same filters used in the analysis with 18 | % MODWT. 19 | % 20 | % XREC = IMODWT(...,LEV) reconstructs the signal up to level LEV. XREC is 21 | % a projection onto the scaling space at level LEV. LEV is a nonnegative 22 | % integer between 0 and strictly less than size(W,1)-1. The default is 23 | % LEV = 0, which results in perfect reconstruction if you do not modify 24 | % the coefficients. 25 | % 26 | % XREC = IMODWT(...,'reflection') uses the 'reflection' boundary 27 | % condition in the reconstruction. If you specify 'reflection', IMODWT 28 | % assumes that the length of the original signal is 1/2 the number of 29 | % columns in the input coefficient matrix W. You must enter the entire 30 | % string 'reflection'. If you added a wavelet named 'reflection' using 31 | % the wavelet manager, you must rename that wavelet prior to using this 32 | % option. 'reflection' may be placed in any position in the input 33 | % argument list after W. By default both MODWT and IMODWT assume periodic 34 | % signal extension at the boundary. 35 | % 36 | % %Example 1: 37 | % % Demonstrate perfect reconstruction of ECG data with the MODWT. 38 | % 39 | % load wecg; 40 | % wecg = wecg(1:end-1); 41 | % w = modwt(wecg,'sym4',10); 42 | % xrec = imodwt(w); 43 | % max(abs(xrec-wecg')) 44 | % subplot(2,1,1) 45 | % plot(wecg); title('Original Signal'); 46 | % subplot(2,1,2) 47 | % plot(xrec); title('Reconstructed Signal'); 48 | % 49 | % %EXAMPLE 2: 50 | % % Reconstruct a signal approximation based on the level-3 and 51 | % % level-4 wavelet coefficients. 52 | % 53 | % load wecg; 54 | % wecg = wecg(1:end-1); 55 | % w = modwt(wecg,'db2',10); 56 | % idx = 3:4; 57 | % wnew = zeros(size(w)); 58 | % wnew = w(idx,:); 59 | % xrec = imodwt(wnew); 60 | % subplot(211) 61 | % plot(wecg); title('Original Signal'); 62 | % subplot(212) 63 | % plot(xrec); 64 | % title('Reconstruction from Level-3 and Level-4 Wavelet Coefficients'); 65 | % 66 | % See also modwt, modwtmra, modwtvar, modwtcorr, modwtxcorr 67 | 68 | % Check number of input arguments 69 | narginchk(1,5); 70 | 71 | % Input cannot be a row or column vector. IMODWT expects at least a two row 72 | % matrix 73 | if (isrow(w) || iscolumn(w)) 74 | error(message('Wavelet:modwt:InvalidCFSSize')); 75 | end 76 | 77 | % Input must be real-value, finite, and double precision 78 | validateattributes(w,{'double'},{'real','nonnan','finite'}); 79 | 80 | % Parse input arguments 81 | params = parseinputs(varargin{:}); 82 | 83 | % Get the original input size 84 | % Get the level of the MODWT 85 | N = size(w,2); 86 | Nrep = N; 87 | J = size(w,1)-1; 88 | 89 | 90 | boundary = params.boundary; 91 | if (~isempty(boundary) && ~strcmpi(boundary,'reflection')) 92 | error(message('Wavelet:modwt:Invalid_Boundary')); 93 | end 94 | 95 | % Adjust final output length if MODWT obtained with 'reflection' 96 | if strcmpi(boundary,'reflection') 97 | N = N/2; 98 | end 99 | 100 | % If the wavelet is specified as a string, obtain filters from wavemngr 101 | if (isfield(params,'wname') && ~isfield(params,'Lo')) 102 | [~,~,Lo,Hi] = wfilters(params.wname); 103 | wtype = wavemngr('type',params.wname); 104 | if (wtype ~= 1) 105 | error(message('Wavelet:modwt:Orth_Filt')); 106 | end 107 | end 108 | 109 | %If scaling and wavelet filters specified as vectors, ensure they 110 | %satisfy the orthogonality conditions 111 | 112 | if (isfield(params,'Lo') && ~isfield(params,'wname')) 113 | filtercheck = CheckFilter(params.Lo,params.Hi); 114 | if ~filtercheck 115 | error(message('Wavelet:modwt:Orth_Filt')); 116 | end 117 | Lo = params.Lo; 118 | Hi = params.Hi; 119 | end 120 | 121 | 122 | % Scale scaling and wavelet filters for MODWT 123 | Lo = Lo./sqrt(2); 124 | Hi = Hi./sqrt(2); 125 | 126 | 127 | % If the number of samples is less than the length of the scaling filter 128 | % we have to periodize the data and then truncate. 129 | if (NrepJ) 143 | error(message('Wavelet:modwt:Incorrect_ReconLevel')); 144 | end 145 | 146 | vin = w(J+1,:); 147 | 148 | % IMODWT algorithm 149 | 150 | for jj = J:-1:lev 151 | vout = imodwtrec(vin,w(jj,:),G,H,jj); 152 | vin = vout; 153 | end 154 | 155 | % Return proper output length 156 | xrec = vout(1:N); 157 | 158 | 159 | 160 | 161 | %----------------------------------------------------------------- 162 | function Vout = imodwtrec(Vin,Win,G,H,J) 163 | N = length(Vin); 164 | Vhat = fft(Vin); 165 | What = fft(Win); 166 | upfactor = 2^(J-1); 167 | Gup = conj(G(1+mod(upfactor*(0:N-1),N))); 168 | Hup = conj(H(1+mod(upfactor*(0:N-1),N))); 169 | Vout = ifft(Gup.*Vhat+Hup.*What); 170 | 171 | 172 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 173 | function params = parseinputs(varargin) 174 | % Parse varargin and check for valid inputs 175 | 176 | % Assign default inputs 177 | params.boundary = []; 178 | params.lev = 0; 179 | params.wname = 'sym4'; 180 | 181 | 182 | % Check for 'reflection' boundary 183 | tfbound = strcmpi(varargin,'reflection'); 184 | 185 | % Determine if 'reflection' boundary is specified 186 | if any(tfbound) 187 | params.boundary = varargin{tfbound>0}; 188 | varargin(tfbound>0) = []; 189 | end 190 | 191 | % If boundary is the only input in addition to the data, return with 192 | % defaults 193 | if isempty(varargin) 194 | return; 195 | end 196 | 197 | % Only remaining char variable must be wavelet name 198 | tfchar = cellfun(@ischar,varargin); 199 | 200 | if (nnz(tfchar) == 1) 201 | params.wname = varargin{tfchar>0}; 202 | end 203 | 204 | % Only scalar input must be the level 205 | tfscalar = cellfun(@isscalar,varargin); 206 | 207 | % Check for numeric inputs 208 | tffilters = cellfun(@isnumeric,varargin); 209 | 210 | % At most 3 numeric inputs are supported 211 | if nnz(tffilters)>3 212 | error(message('Wavelet:modwt:Invalid_Numeric')); 213 | end 214 | 215 | % If there are at least two numeric inputs, the first two must be the 216 | % scaling and wavelet filters 217 | 218 | if (nnz(tffilters)>1) 219 | idxFilt = find(tffilters,2,'first'); 220 | params.Lo = varargin{idxFilt(1)}; 221 | params.Hi = varargin{idxFilt(2)}; 222 | if (length(params.Lo) < 2 || length(params.Hi) < 2) 223 | error(message('Wavelet:modwt:Invalid_Filt_Length')); 224 | end 225 | params = rmfield(params,'wname'); 226 | end 227 | 228 | 229 | % Any scalar input must be the level 230 | if any(tfscalar) 231 | params.lev = varargin{tfscalar>0}; 232 | end 233 | 234 | % If the user specifies a filter, use that instead of default wavelet 235 | if (isfield(params,'Lo') && any(tfchar)) 236 | error(message('Wavelet:FunctionInput:InvalidWavFilter')); 237 | end 238 | 239 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 240 | function out = CheckFilter(Lo,Hi) 241 | % For a user-supplied scaling and wavelet filter, check that 242 | % both correspond to an orthogonal wavelet 243 | Lo = Lo(:); 244 | Hi = Hi(:); 245 | Lscaling = length(Lo); 246 | Lwavelet = length(Hi); 247 | evenlengthLo = 1-rem(Lscaling,2); 248 | evenlengthHi = 1-rem(Lwavelet,2); 249 | 250 | if all([evenlengthLo evenlengthHi]) 251 | evenlength = 1; 252 | else 253 | evenlength = 0; 254 | end 255 | 256 | if (Lscaling ~= Lwavelet) 257 | equallen = 0; 258 | else 259 | equallen = 1; 260 | end 261 | 262 | normLo = norm(Lo,2); 263 | sumLo = sum(Lo); 264 | normHi = norm(Hi,2); 265 | sumHi = sum(Hi); 266 | tol = 1e-7; 267 | 268 | if (abs(normLo-1) > tol && abs(normHi -1) > tol) 269 | unitnorm = 0; 270 | else 271 | unitnorm = 1; 272 | end 273 | 274 | if (abs(sumLo-sqrt(2))> tol && abs(sumHi) > tol) 275 | sumfilters = 0; 276 | else 277 | sumfilters = 1; 278 | end 279 | 280 | 281 | zeroevenlags = 1; 282 | 283 | if (Lscaling > 2) 284 | L = Lscaling; 285 | xcorrHi = conv(Hi,flipud(Hi)); 286 | xcorrLo = conv(Lo,flipud(Lo)); 287 | xcorrLo = xcorrLo(L+2:2:end); 288 | xcorrHi = xcorrHi(L+2:2:end); 289 | zeroevenlagsLo = 1-any(abs(xcorrLo>tol)); 290 | zeroevenlagsHi = 1-any(abs(xcorrHi>tol)); 291 | zeroevenlags = max(zeroevenlagsLo,zeroevenlagsHi); 292 | end 293 | out = all([evenlength equallen unitnorm sumfilters zeroevenlags]); 294 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | % [EOF] imodwt.m 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | -------------------------------------------------------------------------------- /allguis/codes/Universal/matchRotation.m: -------------------------------------------------------------------------------- 1 | function sig = matchRotation(original, s) 2 | % function to support wavsurrogates 3 | % author: Aleksandra Pidde, a.eksandra.pidde@gmail.com 4 | rev = s(end:-1:1); 5 | [sig1, err1] = matchRot(original, s); 6 | [sig2, err2] = matchRot(original, rev); 7 | if err1 < err2 8 | sig = sig1; 9 | else 10 | sig = sig2; 11 | end 12 | end 13 | 14 | function [sig, err] = matchRot(original, s) 15 | N = length(s); 16 | err = sum((original - s).^2); 17 | sig = s; 18 | [~, dim] = max(size(s)); 19 | for i = 2 : N - 1 20 | tmp = circshift(s, 1, dim); 21 | er = sum((original - tmp).^2); 22 | if er < err 23 | err = er; 24 | sig = tmp; 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /allguis/codes/Universal/modwt.m: -------------------------------------------------------------------------------- 1 | function w = modwt(x,varargin) 2 | %MODWT Maximal overlap discrete wavelet transform. 3 | % W = MODWT(X) computes the maximal overlap discrete wavelet transform of 4 | % a 1-D real-valued, double-precision input signal, X. The signal can be 5 | % a row or column vector and must contain at least two samples. By 6 | % default, the maximal overlap discrete wavelet transform is computed 7 | % down to level floor(log2(length(X))) using the Daubechies 8 | % least-asymmetric wavelet with 4 vanishing moments ('sym4') and periodic 9 | % boundary handling. W is a LEV+1-by-N matrix containing the wavelet 10 | % coefficients and final-level scaling coefficients. LEV is the level of 11 | % the MODWT. The m-th row of the matrix contains the wavelet (detail) 12 | % coefficients for scale 2^m. The LEV+1-th row of the matrix contains the 13 | % scaling coefficients for scale 2^LEV. 14 | % 15 | % W = MODWT(X,WNAME) computes the MODWT using the wavelet, WNAME. WNAME 16 | % is a character vector denoting the name of an orthogonal wavelet. 17 | % Orthogonal wavelets are designated as type 1 wavelets in the wavelet 18 | % manager. Valid built-in orthogonal wavelet families begin with 19 | % 'haar','dbN', 'fkN', 'coifN', or 'symN' where N is the number of 20 | % vanishing moments for all families except 'fk'. For 'fk', N is the 21 | % number of filter coefficients. You can determine valid values for N by 22 | % using waveinfo. For example, waveinfo('db'). You can check if your 23 | % wavelet is orthogonal by using wavemngr('type',wname) to see if a 1 is 24 | % returned. For example, wavemngr('type','db2'). 25 | % 26 | % W = MODWT(X,Lo,Hi) computes the maximal overlap discrete wavelet 27 | % transform using the scaling filter, Lo, and the wavelet filter, Hi. Lo 28 | % and Hi are even-length row or column vectors. These filters must 29 | % satisfy the conditions for an orthogonal wavelet. You cannot specify 30 | % both WNAME and a filter pair, Lo and Hi. 31 | % 32 | % W = MODWT(...,LEV) computes the maximal overlap discrete wavelet 33 | % transform down to the level, LEV. LEV is a positive integer that cannot 34 | % exceed floor(log2(length(X))). If unspecified, LEV defaults to 35 | % floor(log2(length(X))). 36 | % 37 | % W = MODWT(...,'reflection') uses reflection boundary handling by 38 | % extending the signal symmetrically at the right boundary to twice the 39 | % signal length,[x flip(x)], before computing the wavelet transform. The 40 | % number of wavelet and scaling coefficients returned are twice the 41 | % length of the input signal. By default, the signal is extended 42 | % periodically. You must enter the entire character vector 'reflection'. 43 | % If you added a wavelet named 'reflection' using the wavelet manager, 44 | % you must rename that wavelet prior to using this option. 'reflection' 45 | % may be placed in any position in the input argument list after X. 46 | % 47 | % 48 | % % Example 1: 49 | % % Obtain the maximal overlap discrete wavelet transform of the Nile 50 | % % river minimum water level data. The data is 663 samples in length 51 | % % sampled yearly. Use the Haar wavelet and transform the data down 52 | % % to level 8. Plot the level-3 wavelet coefficients. 53 | % 54 | % load nileriverminima; 55 | % w = modwt(nileriverminima,'haar',8); 56 | % plot(w(3,:)); title('Level-3 Wavelet Coefficients'); 57 | % 58 | % % Example 2: 59 | % % Check that the maximal overlap discrete wavelet transform 60 | % % partitions the variance of the signal by scale. 61 | % 62 | % load noisdopp; 63 | % [~,~,Lo,Hi] = wfilters('sym8'); 64 | % w = modwt(noisdopp,Lo,Hi,10); 65 | % varbylev = var(w,1,2); 66 | % sum(varbylev) 67 | % var(noisdopp,1) 68 | % 69 | % See also IMODWT MODWTMRA MODWTCORR MODWTXCORR 70 | 71 | 72 | % Check number of input arguments 73 | narginchk(1,5); 74 | 75 | % Validate that data is real, 1-D double-precision 76 | % with no NaNs or Infs 77 | 78 | validateattributes(x,{'double'},{'real','nonnan','finite'}); 79 | 80 | 81 | 82 | %Input must be 1-D 83 | if (~isrow(x) && ~iscolumn(x)) 84 | error(message('Wavelet:modwt:OneD_Input')); 85 | end 86 | 87 | %Input must contain at least two samples 88 | if (numel(x)<2) 89 | error(message('Wavelet:modwt:LenTwo')); 90 | end 91 | 92 | 93 | % Convert data to row vector 94 | x = x(:)'; 95 | % Record original data length 96 | datalength = length(x); 97 | 98 | %Parse input arguments 99 | params = parseinputs(datalength,varargin{:}); 100 | 101 | %Check that the level of the transform does not exceed floor(log2(numel(x)) 102 | J = params.J; 103 | Jmax = floor(log2(datalength)); 104 | if (J <= 0) || (J > Jmax) || (J ~= fix(J)) 105 | error(message('Wavelet:modwt:MRALevel')); 106 | end 107 | 108 | boundary = params.boundary; 109 | if (~isempty(boundary) && ~strcmpi(boundary,'reflection')) 110 | error(message('Wavelet:modwt:Invalid_Boundary')); 111 | end 112 | 113 | % increase signal length if 'reflection' is specified 114 | if strcmpi(boundary,'reflection') 115 | x = [x flip(x)]; 116 | end 117 | 118 | % obtain new signal length if needed 119 | siglen = length(x); 120 | Nrep = siglen; 121 | 122 | 123 | % If wavelet specified as a string, ensure that wavelet is orthogonal 124 | if (isfield(params,'wname') && ~isfield(params,'Lo')) 125 | [~,~,Lo,Hi] = wfilters(params.wname); 126 | wtype = wavemngr('type',params.wname); 127 | if (wtype ~= 1) 128 | error(message('Wavelet:modwt:Orth_Filt')); 129 | end 130 | end 131 | 132 | %If scaling and wavelet filters are specified as vectors, ensure they 133 | %satisfy the orthogonality conditions 134 | 135 | if (isfield(params,'Lo') && ~isfield(params,'wname')) 136 | filtercheck = CheckFilter(params.Lo,params.Hi); 137 | if ~filtercheck 138 | error(message('Wavelet:modwt:Orth_Filt')); 139 | end 140 | Lo = params.Lo; 141 | Hi = params.Hi; 142 | end 143 | 144 | % Scale the scaling and wavelet filters for the MODWT 145 | Lo = Lo./sqrt(2); 146 | Hi = Hi./sqrt(2); 147 | 148 | % Ensure Lo and Hi are row vectors 149 | Lo = Lo(:)'; 150 | Hi = Hi(:)'; 151 | 152 | % If the signal length is less than the filter length, need to 153 | % periodize the signal in order to use the DFT algorithm 154 | 155 | if (siglen tol && abs(normHi -1) > tol) 223 | unitnorm = 0; 224 | else 225 | unitnorm = 1; 226 | 227 | end 228 | 229 | if (abs(sumLo-sqrt(2)) > tol && abs(sumHi) > tol) 230 | sumfilters = 0; 231 | else 232 | sumfilters = 1; 233 | end 234 | 235 | 236 | zeroevenlags = 1; 237 | 238 | if (Lscaling > 2) 239 | L = Lscaling; 240 | xcorrHi = conv(Hi,flipud(Hi)); 241 | xcorrLo = conv(Lo,flipud(Lo)); 242 | xcorrLo = xcorrLo(L+2:2:end); 243 | xcorrHi = xcorrHi(L+2:2:end); 244 | zeroevenlagsLo = 1-any(abs(xcorrLo>tol)); 245 | zeroevenlagsHi = 1-any(abs(xcorrHi>tol)); 246 | zeroevenlags = max(zeroevenlagsLo,zeroevenlagsHi); 247 | end 248 | out = all([evenlength equallen unitnorm sumfilters zeroevenlags]); 249 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 250 | 251 | 252 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 253 | function params = parseinputs(siglen,varargin) 254 | % Parse varargin and check for valid inputs 255 | 256 | % Assign defaults 257 | params.boundary = []; 258 | params.J = floor(log2(siglen)); 259 | params.wname = 'sym4'; 260 | 261 | % Check for 'reflection' boundary 262 | tfbound = strcmpi(varargin,'reflection'); 263 | 264 | % Determine if 'reflection' boundary is specified 265 | if any(tfbound) 266 | params.boundary = varargin{tfbound>0}; 267 | varargin(tfbound>0) = []; 268 | end 269 | 270 | % If boundary is the only input in addition to the data, return with 271 | % defaults 272 | if isempty(varargin) 273 | return; 274 | end 275 | 276 | % Only remaining char variable must be wavelet name 277 | tfchar = cellfun(@ischar,varargin); 278 | if (nnz(tfchar) == 1) 279 | params.wname = varargin{tfchar>0}; 280 | end 281 | 282 | % Only scalar input must be the level 283 | tfscalar = cellfun(@isscalar,varargin); 284 | 285 | % Check for numeric inputs 286 | tffilters = cellfun(@isnumeric,varargin); 287 | 288 | % At most 3 numeric inputs are supported 289 | if nnz(tffilters)>3 290 | error(message('Wavelet:modwt:Invalid_Numeric')); 291 | end 292 | 293 | % There's one numeric argument and it's not a wavelet level 294 | if (nnz(tffilters)==1) && (nnz(tfscalar) == 0) 295 | error(message('Wavelet:FunctionInput:InvalidLoHiFilters')); 296 | end 297 | 298 | % If there are at least two numeric inputs, the first two must be the 299 | % scaling and wavelet filters 300 | if (nnz(tffilters)>1) 301 | idxFilt = find(tffilters,2,'first'); 302 | params.Lo = varargin{idxFilt(1)}; 303 | params.Hi = varargin{idxFilt(2)}; 304 | params = rmfield(params,'wname'); 305 | 306 | if (length(params.Lo) < 2 || length(params.Hi) < 2) 307 | error(message('Wavelet:modwt:Invalid_Filt_Length')); 308 | end 309 | 310 | end 311 | 312 | % Any scalar input must be the level 313 | if any(tfscalar) 314 | params.J = varargin{tfscalar>0}; 315 | end 316 | 317 | % If the user specifies a filter, use that instead of default wavelet 318 | if (isfield(params,'Lo') && any(tfchar)) 319 | error(message('Wavelet:FunctionInput:InvalidWavFilter')); 320 | end 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | % [EOF] modwt.m 349 | 350 | 351 | -------------------------------------------------------------------------------- /allguis/codes/Universal/wsurr.m: -------------------------------------------------------------------------------- 1 | % WIAAFT surrogate 2 | clear surrLev 3 | sig=y; 4 | %wvlt='la16'; 5 | fs=1; 6 | 7 | w=modwt(sig); 8 | N2=size(w,1); 9 | N=length(sig); 10 | 11 | for j=1:N2 12 | tmp=surrcalc(sig, 1, 'IAAFT2', 0, fs); 13 | surrLev(j,:)=matchRotation(w(j,:),tmp); 14 | 15 | end 16 | 17 | surr=imodwt(surrLev); 18 | 19 | maxit = 200; % maximum number of iterations 20 | [sorted, sortInd] = sort(sig); 21 | itrank(sortInd) = linspace(1, N, N); 22 | ftsig = fft(sig); 23 | surrtmp = surr; 24 | iter = 1; 25 | oldrank = zeros(1, N); 26 | 27 | while (max(abs(oldrank - itrank)) ~= 0 && iter < maxit) % equal spectrum, similar amplitude distribution 28 | oldrank = itrank; 29 | % replace Fourier amplitudes (real() since makes mistakes of order \epsilon) 30 | itFt = real(ifft(abs(ftsig).* exp(1i * angle(fft(surrtmp))))); 31 | [~, itind] = sort(itFt); % find the ordering of the new signal 32 | itrank(itind)= linspace(1, N, N); 33 | surrtmp = sorted(itrank); 34 | iter = iter + 1; 35 | end 36 | surr = itFt; 37 | 38 | figure 39 | plot(time,sig) 40 | hold on 41 | plot(time,surr) 42 | legend('Sig','Surr') -------------------------------------------------------------------------------- /allguis/codes/cell2csv/cell2csv.m: -------------------------------------------------------------------------------- 1 | function cell2csv(fileName, cellArray, separator, excelYear, decimal) 2 | % % Writes cell array content into a *.csv file. 3 | % % 4 | % % CELL2CSV(fileName, cellArray[, separator, excelYear, decimal]) 5 | % % 6 | % % fileName = Name of the file to save. [ e.g. 'text.csv' ] 7 | % % cellArray = Name of the Cell Array where the data is in 8 | % % 9 | % % optional: 10 | % % separator = sign separating the values (default = ',') 11 | % % excelYear = depending on the Excel version, the cells are put into 12 | % % quotes before they are written to the file. The separator 13 | % % is set to semicolon (;) (default = 1997 which does not change separator to semicolon ;) 14 | % % decimal = defines the decimal separator (default = '.') 15 | % % 16 | % % by Sylvain Fiedler, KA, 2004 17 | % % updated by Sylvain Fiedler, Metz, 06 18 | % % fixed the logical-bug, Kaiserslautern, 06/2008, S.Fiedler 19 | % % added the choice of decimal separator, 11/2010, S.Fiedler 20 | % % modfiedy and optimized by Jerry Zhu, June, 2014, jerryzhujian9@gmail.com 21 | % % now works with empty cells, numeric, char, string, row vector, and logical cells. 22 | % % row vector such as [1 2 3] will be separated by two spaces, that is "1 2 3" 23 | % % One array can contain all of them, but only one value per cell. 24 | % % 2x times faster than Sylvain's codes (8.8s vs. 17.2s): 25 | % % tic;C={'te','tm';5,[1,2];true,{}};C=repmat(C,[10000,1]);cell2csv([datestr(now,'MMSS') '.csv'],C);toc; 26 | % % 27 | % % Copyright (c) 2014, Jerry 28 | % % All rights reserved. 29 | % % 30 | % % Redistribution and use in source and binary forms, with or without 31 | % % modification, are permitted provided that the following conditions are 32 | % % met: 33 | % % 34 | % % * Redistributions of source code must retain the above copyright 35 | % % notice, this list of conditions and the following disclaimer. 36 | % % * Redistributions in binary form must reproduce the above copyright 37 | % % notice, this list of conditions and the following disclaimer in 38 | % % the documentation and/or other materials provided with the distribution 39 | % % 40 | % % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 41 | % % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 | % % IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 | % % ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 44 | % % LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 45 | % % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 46 | % % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 47 | % % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 48 | % % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 | % % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50 | % % POSSIBILITY OF SUCH DAMAGE. 51 | 52 | 53 | %% Checking for optional Variables 54 | if ~exist('separator', 'var') 55 | separator = ','; 56 | end 57 | 58 | if ~exist('excelYear', 'var') 59 | excelYear = 1997; 60 | end 61 | 62 | if ~exist('decimal', 'var') 63 | decimal = '.'; 64 | end 65 | 66 | %% Setting separator for newer excelYears 67 | if excelYear > 2000 68 | separator = ';'; 69 | end 70 | 71 | % convert cell 72 | cellArray = cellfun(@StringX, cellArray, 'UniformOutput', false); 73 | 74 | %% Write file 75 | datei = fopen(fileName, 'w'); 76 | [nrows,ncols] = size(cellArray); 77 | for row = 1:nrows 78 | fprintf(datei,[sprintf(['%s' separator],cellArray{row,1:ncols-1}) cellArray{row,ncols} '\n']); 79 | end 80 | % Closing file 81 | fclose(datei); 82 | 83 | % sub-function 84 | function x = StringX(x) 85 | % If zero, then empty cell 86 | if isempty(x) 87 | x = ''; 88 | % If numeric -> String, e.g. 1, [1 2] 89 | elseif isnumeric(x) && isrow(x) 90 | x = num2str(x); 91 | if decimal ~= '.' 92 | x = strrep(x, '.', decimal); 93 | end 94 | % If logical -> 'true' or 'false' 95 | elseif islogical(x) 96 | if x == 1 97 | x = 'TRUE'; 98 | else 99 | x = 'FALSE'; 100 | end 101 | % If matrix array -> a1 a2 a3. e.g. [1 2 3] 102 | % also catch string or char here 103 | elseif isrow(x) && ~iscell(x) 104 | x = num2str(x); 105 | % everthing else, such as [1;2], {1} 106 | else 107 | x = 'NA'; 108 | end 109 | 110 | % If newer version of Excel -> Quotes 4 Strings 111 | if excelYear > 2000 112 | x = ['"' x '"']; 113 | end 114 | end % end sub-function 115 | end % end function -------------------------------------------------------------------------------- /allguis/codes/cell2csv/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Jerry 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /allguis/codes/cmap/cmap.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/codes/cmap/cmap.mat -------------------------------------------------------------------------------- /allguis/codes/cmap/linecolors.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/codes/cmap/linecolors.mat -------------------------------------------------------------------------------- /allguis/codes/ginputc/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, The MathWorks, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution. 13 | * In all cases, the software is, and all modifications and derivatives 14 | of the software shall be, licensed to you solely for use in conjunction 15 | with MathWorks products and service offerings. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /allguis/codes/reading/csv_to_mvar.m: -------------------------------------------------------------------------------- 1 | function x = csv_to_mvar( s ) 2 | %CSV_TO_MVAR converts comma separated string to a vector 3 | x = eval( [ '[', s, ']' ] ); 4 | end 5 | 6 | -------------------------------------------------------------------------------- /allguis/codes/reading/read_from_csv.m: -------------------------------------------------------------------------------- 1 | function M = read_from_csv 2 | %Reads from the file and creates a MATLAB variable to be used by the program 3 | 4 | [filename,pathname,filterindex] = uigetfile('*.csv'); %only allows csv format files to be read 5 | name = fullfile(pathname,filename) 6 | 7 | M = csvread(name); 8 | -------------------------------------------------------------------------------- /allguis/codes/reading/read_from_mat.m: -------------------------------------------------------------------------------- 1 | function M = read_from_mat 2 | %Reads from the file and creates a MATLAB variable to be used by the program 3 | 4 | [filename,pathname,filterindex] = uigetfile('*.mat'); %only allows csv format files to be read 5 | 6 | name = fullfile(pathname,filename) 7 | M = load(name); 8 | -------------------------------------------------------------------------------- /allguis/guis/MODA.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/guis/MODA.fig -------------------------------------------------------------------------------- /allguis/guis/bayesian/Bayesian.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/guis/bayesian/Bayesian.fig -------------------------------------------------------------------------------- /allguis/guis/bayesian/Functions/CFprint.m: -------------------------------------------------------------------------------- 1 | function [t1,t2,q1,q2]=CFprint(cc,bn) 2 | %plots the coupling functions from the inferred parameters 3 | 4 | %---inputs--- 5 | %cc - vector of inferred parameters 6 | %bn - order of Fourier base function 7 | 8 | %Note that the input is vector of parameters for one time window 9 | %% 10 | %---evaluating the coupling functions ----- 11 | t1=0:0.13:2*pi;t2=0:0.13:2*pi; 12 | q1(1:length(t1),1:length(t1))=0;q2=q1; 13 | u=cc; K=length(u)/2; 14 | for i1=1:length(t1) 15 | for j1=1:length(t2) 16 | br=2; 17 | 18 | for ii=1:bn 19 | q1(i1,j1)=q1(i1,j1)+u(br)*sin(ii*t1(i1))+u(br+1)*cos(ii*t1(i1)); 20 | q2(i1,j1)=q2(i1,j1)+u(K+br)*sin(ii*t2(j1))+u(K+br+1)*cos(ii*t2(j1)); 21 | br=br+2; 22 | end 23 | for ii=1:bn 24 | q1(i1,j1)=q1(i1,j1)+u(br)*sin(ii*t2(j1))+u(br+1)*cos(ii*t2(j1)); 25 | q2(i1,j1)=q2(i1,j1)+u(K+br)*sin(ii*t1(i1))+u(K+br+1)*cos(ii*t1(i1)); 26 | br=br+2; 27 | end 28 | 29 | for ii=1:bn 30 | for jj=1:bn 31 | q1(i1,j1)=q1(i1,j1)+u(br)*sin(ii*t1(i1)+jj*t2(j1))+u(br+1)*cos(ii*t1(i1)+jj*t2(j1)); 32 | q2(i1,j1)=q2(i1,j1)+u(K+br)*sin(ii*t1(i1)+jj*t2(j1))+u(K+br+1)*cos(ii*t1(i1)+jj*t2(j1)); 33 | br=br+2; 34 | 35 | q1(i1,j1)=q1(i1,j1)+u(br)*sin(ii*t1(i1)-jj*t2(j1))+u(br+1)*cos(ii*t1(i1)-jj*t2(j1)); 36 | q2(i1,j1)=q2(i1,j1)+u(K+br)*sin(ii*t1(i1)-jj*t2(j1))+u(K+br+1)*cos(ii*t1(i1)-jj*t2(j1)); 37 | br=br+2; 38 | end 39 | end 40 | 41 | end 42 | end 43 | 44 | %---plotting ----- 45 | % f1=figure; 46 | % 47 | % subplot(1,2,1);surf(t1,t2,q1','FaceColor','interp'); 48 | % view([-40 50]) 49 | % set(gca,'fontname','Helvetica','fontsize',12,'Xgrid','off','Ygrid','off') 50 | % xlabel('\phi_1');ylabel('\phi_2');zlabel('q_1(\phi_1,\phi_2)');axis tight 51 | % 52 | % subplot(1,2,2);surf(t1,t2,q2','FaceColor','interp'); 53 | % view([-40 50]) 54 | % set(gca,'fontname','Helvetica','fontsize',12,'Xgrid','off','Ygrid','off') 55 | % xlabel('\phi_1');ylabel('\phi_2');zlabel('q_2(\phi_1,\phi_2)');axis tight 56 | % 57 | % colormap(hot) 58 | % set(gcf, 'Position', get(0,'Screensize')); % Maximize figure. 59 | 60 | %uncomment this lines for saving the figure 61 | % saveas(f1,'filename','jpg'); 62 | % saveas(f1,'filename','fig'); 63 | 64 | %% 65 | -------------------------------------------------------------------------------- /allguis/guis/bayesian/Functions/MODAbayes_intdelete.m: -------------------------------------------------------------------------------- 1 | function handles=MODAbayes_intdelete(hObject,eventdata,handles) 2 | % Function to deleta data from handles 3 | 4 | %switch eventdata.Key 5 | %case 'delete' % Excutes when user presses delete 6 | interval_selected = get(handles.interval_list_1,'Value'); 7 | n=1:handles.c; 8 | 9 | if isempty(interval_selected), return; end 10 | 11 | ne=n(1:end ~=interval_selected); 12 | if isfield(handles,'pinput') 13 | else 14 | handles.int1=handles.int1(ne,:); % Delete data 15 | handles.int2=handles.int2(ne,:); 16 | end 17 | handles.winds=handles.winds(ne); 18 | handles.pr=handles.pr(ne); 19 | handles.ovr=handles.ovr(ne); 20 | handles.forder=handles.forder(ne); 21 | handles.ns=handles.ns(ne); 22 | handles.confidence_level=handles.confidence_level(ne); 23 | 24 | if isfield(handles,'tm') && size(handles.tm,2)==handles.c 25 | handles.tm=handles.tm(:,ne); 26 | handles.cc=handles.cc(:,ne); 27 | handles.e=handles.e(:,ne); 28 | handles.cpl1=handles.cpl1(:,ne); 29 | handles.cpl2=handles.cpl2(:,ne); 30 | handles.cf1=handles.cf1(:,ne); 31 | handles.cf2=handles.cf2(:,ne); 32 | handles.mcf1=handles.mcf1(:,ne); 33 | handles.mcf2=handles.mcf2(:,ne); 34 | handles.surr_cpl1=handles.surr_cpl1(:,ne); 35 | handles.surr_cpl2=handles.surr_cpl2(:,ne); 36 | handles.p1=handles.p1(:,ne); 37 | handles.p2=handles.p2(:,ne); 38 | else 39 | end 40 | 41 | 42 | if min(interval_selected)>1 43 | set(handles.interval_list_1,'Value',min(interval_selected)-1); 44 | else 45 | set(handles.interval_list_1,'Value',1); 46 | end 47 | 48 | list = get(handles.interval_list_1,'String'); 49 | list(interval_selected,:) = []; 50 | set(handles.interval_list_1,'String',list); 51 | 52 | interval_selected = get(handles.interval_list_2,'Value'); 53 | if min(interval_selected)>1 54 | set(handles.interval_list_2,'Value',min(interval_selected)-1); 55 | else 56 | set(handles.interval_list_2,'Value',1); 57 | end 58 | 59 | list = get(handles.interval_list_2,'String'); 60 | list(interval_selected,:) = []; 61 | 62 | set(handles.interval_list_2,'String',list); 63 | if isfield(handles,'bands') && ~isempty(handles.bands) 64 | try 65 | handles.bands(:,interval_selected) = []; 66 | guidata(hObject,handles); 67 | catch exception 68 | % Catch "Matrix index is out of range for deletion." exception. 69 | end 70 | else 71 | end 72 | 73 | drawnow; 74 | handles.c=handles.c-1; 75 | guidata(hObject,handles); 76 | 77 | end 78 | 79 | % handles.int1(interval_selected,:)=[]; % Delete data 80 | % handles.int2(interval_selected,:)=[]; 81 | % handles.winds(interval_selected,:)=[]; 82 | % handles.pr(interval_selected,:)=[]; 83 | % handles.ovr(interval_selected,:)=[]; 84 | % handles.forder(interval_selected,:)=[]; 85 | % handles.ns(interval_selected,:)=[]; 86 | % 87 | % if min(interval_selected)>1 88 | % set(handles.interval_list_1,'Value',min(interval_selected)-1); 89 | % else 90 | % set(handles.interval_list_1,'Value',1); 91 | % end 92 | % 93 | % list = get(handles.interval_list_1,'String'); 94 | % list(interval_selected,:) = []; 95 | % set(handles.interval_list_1,'String',list); 96 | % 97 | % interval_selected = get(handles.interval_list_2,'Value'); 98 | % if min(interval_selected)>1 99 | % set(handles.interval_list_2,'Value',min(interval_selected)-1); 100 | % else 101 | % set(handles.interval_list_2,'Value',1); 102 | % end 103 | % list = get(handles.interval_list_2,'String'); 104 | % list(interval_selected,:) = []; 105 | % set(handles.interval_list_2,'String',list); 106 | % if isfield(handles,'bands') 107 | % handles.bands(:,interval_selected) = []; 108 | % guidata(hObject,handles); 109 | % else 110 | % end 111 | % drawnow; 112 | % 113 | % guidata(hObject,handles); 114 | %end -------------------------------------------------------------------------------- /allguis/guis/bayesian/Functions/MODAbayes_loadfilt.m: -------------------------------------------------------------------------------- 1 | function handles=MODAbayes_loadfilt(hObject,eventdata,handles,ty) 2 | 3 | % ty=1 - load filtered phases, 1 sig, 2 bands 4 | % ty=2 - load filtered phases, 2 sigs, 1 band 5 | handles.pinput=1; 6 | set(handles.curr_time,'visible','off'); 7 | 8 | linkaxes([handles.time_series_1 handles.time_series_2],'x'); 9 | set(handles.status,'String','Importing Signal...'); 10 | 11 | if ty==1 12 | [filename,pathname] = uigetfile('*.mat','Load phases'); 13 | name = fullfile(pathname,filename); 14 | sig = load(name); 15 | sig = struct2cell(sig); 16 | sig = cell2mat(sig); 17 | 18 | if isfield(sig,'Ridge_recon') 19 | phiall=sig.Ridge_phase; 20 | else 21 | phiall=sig.Filtered_phases; 22 | end 23 | 24 | S=size(phiall,1); 25 | 26 | for j=1:S 27 | phi1(j,:)=phiall{j,1}; 28 | phi2(j,:)=phiall{j,2}; 29 | end 30 | 31 | handles.int1=sig.Freq_bands{1,1}; 32 | handles.int2=sig.Freq_bands{2,1}; 33 | handles.sampling_freq=sig.Sampling_frequency; 34 | 35 | 36 | elseif ty==2 37 | [filename,pathname] = uigetfile('*.mat','Load phase 1'); 38 | name = fullfile(pathname,filename); 39 | sig1 = load(name); 40 | 41 | if isfield(sig1.Filtered_data,'Ridge_recon') 42 | phi1=cell2mat(sig1.Filtered_data.Ridge_phase); 43 | else 44 | phi1=cell2mat(sig1.Filtered_data.Filtered_phases); 45 | end 46 | 47 | [filename,pathname] = uigetfile('*.mat','Load phase 2'); 48 | name = fullfile(pathname,filename); 49 | sig2 = load(name); 50 | 51 | if isfield(sig2.Filtered_data,'Ridge_recon') 52 | phi2=cell2mat(sig2.Filtered_data.Ridge_phase); 53 | else 54 | phi2=cell2mat(sig2.Filtered_data.Filtered_phases); 55 | end 56 | 57 | handles.int1=sig1.Filtered_data.Freq_bands{1,1}; 58 | handles.int2=sig2.Filtered_data.Freq_bands{1,1}; 59 | handles.sampling_freq=sig1.Filtered_data.Sampling_frequency; 60 | 61 | 62 | if sig1.Filtered_data.Sampling_frequency~=sig2.Filtered_data.Sampling_frequency 63 | errordlg('Data sets must have the same sampling frequency','Parameter Error'); 64 | return; 65 | else 66 | end 67 | 68 | end 69 | 70 | handles.sig=[phi1;phi2]; 71 | handles.sig_cut=handles.sig; 72 | handles.phase1=phi1; 73 | handles.phase2=phi2; 74 | set(handles.freq_1,'String',handles.int1); 75 | set(handles.freq_2,'String',handles.int2); 76 | 77 | time = linspace(0,length(handles.sig)/handles.sampling_freq,length(handles.sig)); 78 | handles.time_axis = time; 79 | handles.time_axis_cut = time; 80 | 81 | %% Create signal list 82 | list = cell(size(handles.sig,1)/2,1); 83 | list{1,1} = 'Signal Pair 1'; 84 | 85 | for i = 2:size(handles.sig,1)/2 86 | list{i,1} = sprintf('Signal Pair %d',i); 87 | end 88 | set(handles.signal_list,'String',list); 89 | 90 | %% Plot time series 91 | linkaxes([handles.time_series_1 handles.time_series_2],'x'); % Ensures axis limits are identical for both plots 92 | plot(handles.time_series_1,handles.time_axis,handles.sig(1,:),'color',handles.linecol(1,:)); 93 | xlim(handles.time_series_1,[0 handles.time_axis(end)]); 94 | plot(handles.time_series_2,handles.time_axis,handles.sig(1+size(handles.sig,1)/2,:),'color',handles.linecol(1,:)); 95 | xlim(handles.time_series_2,[0 handles.time_axis(end)]); 96 | xlabel(handles.time_series_2,'Time (s)'); 97 | ylabel(handles.time_series_1,'Sig 1'); 98 | ylabel(handles.time_series_2,'Sig 2'); 99 | 100 | set(handles.plot_TS,'Enable','on') 101 | 102 | set(handles.status,'String','Select data and define parameters'); 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /allguis/guis/bayesian/Functions/bandpass_butter.m: -------------------------------------------------------------------------------- 1 | function [d] = bandpass_butter(c,or,flp,fhi,fs) 2 | % 3 | % [d]=bandpass(c,flp) 4 | % 5 | % bandpass a time series with a 2nd order butterworth filter 6 | % 7 | % c = input time series 8 | % or-order for the filter 9 | % flp = lowpass corner frequency of filter 10 | % fhi = hipass corner frequency 11 | % fs = sampling frequency 12 | % 13 | n=or; % 2nd order butterworth filter 14 | fnq=1/2*fs; % Nyquist frequency 15 | Wn=[flp/fnq fhi/fnq]; % butterworth bandpass non-dimensional frequency 16 | [b,a]=butter(n,Wn); % construct the filter 17 | d=filtfilt(b,a,c); % zero phase filter the data 18 | return; -------------------------------------------------------------------------------- /allguis/guis/bayesian/Functions/bayesPhs.m: -------------------------------------------------------------------------------- 1 | function [Cpt, XIpt, E]=bayesPhs(Cpr,XIpr,h,max_loops,eps,phi1,phi2,bn) 2 | %infers the parameters and the noise within one block of data 3 | 4 | %---inputs--- 5 | %Cpr - prior vector of parameters 6 | %XIpr - prior concentration matrix (i.e. inv(covariance) matrix) 7 | %h - sampling rate (e.g. h=0.01) 8 | %max_loops - number of loops to stop for the error for convergence 9 | %eps - error/tolerance for convergence 10 | %phi1,phi2 - input block of data 11 | %bn - order of Fourier base function 12 | 13 | %---outputs--- 14 | %Cpt - posterior vector of parameters 15 | %XIpt - poaterior concentration matrix (i.e. inv(covariance) matrix) 16 | %E - noise matrix 17 | 18 | %% ------------ 19 | 20 | %phi1S & phi2S - the midpoint time series 21 | phi1S=(phi1(2:end)+phi1(1:end-1))/2; phi2S=(phi2(2:end)+phi2(1:end-1))/2; 22 | 23 | %phi1T & phi2T - the derivative time series 24 | phi1T=(phi1(2:end)-phi1(1:end-1))/h; phi2T=(phi2(2:end)-phi2(1:end-1))/h; 25 | phiT=[phi1T;phi2T]; 26 | 27 | L=2; %number of dimensions 28 | M=2+2*((2*bn+1)^2-1); %number of base functions 29 | K=M/L; %number of dimensions for the C vector 30 | lastwarn(''); %reset the last warning message 31 | 32 | %the following evaluations fill temporary variables to be used bellow in the main calculations 33 | p=calculateP(phi1S,phi2S,K,bn); 34 | v1=calculateV(phi1S,phi2S,K,bn,1); 35 | v2=calculateV(phi1S,phi2S,K,bn,2); 36 | 37 | 38 | %loop to converge iteratively the result until desired precision is reached 39 | C_old=Cpr; 40 | Cpt=Cpr; %initialize Cpt 41 | for loop=1:max_loops 42 | 43 | [E]=calculateE(Cpt',phiT,L,h,p); 44 | [Cpt,XIpt]=calculateC(E,p,v1,v2,Cpr,XIpr,M,L,phiT,h); 45 | 46 | if(sum((C_old-Cpt).*(C_old-Cpt)./(Cpt.*Cpt))> [tm,cc,e]=bayes_main(ph1,ph2,40,0.01,1,0.2,1,2); 22 | %% 23 | 24 | cc=[]; 25 | win=win/h; 26 | w=ovr*win; 27 | ps=ph2-ph1; 28 | pw=win*h*pr; 29 | 30 | M=2+2*((2*bn+1)^2-1); 31 | L=2; 32 | 33 | Cpr=zeros(M/L,L);XIpr=zeros(M); 34 | 35 | 36 | %unwrap the phases if they are not 37 | if (max(ph1)<(2*pi+0.1)) 38 | ph1=unwrap(ph1); 39 | ph2=unwrap(ph2); 40 | end 41 | 42 | %set the right dimensions for the vectors 43 | [m,n]=size(ph1); 44 | if m0) 78 | while ((abs(mth)-4*pi)> eps)&&(br<100) 79 | dot_th_next= calculate_dot_th1th2(th_next,c,bn); 80 | h= - (mth-4*pi)/(dot_th_next(1)+dot_th_next(2)); 81 | th_next = rk4(th_next,c,h,bn); 82 | mth=th_next(1)+th_next(2); 83 | 84 | br=br+1; 85 | end 86 | else 87 | while ((abs(mth)+4*pi)> eps)&&(br<100) 88 | dot_th_next= calculate_dot_th1th2(th_next,c,bn); 89 | h= - (mth+4*pi)/(dot_th_next(1)+dot_th_next(2)); 90 | th_next = rk4(th_next,c,h,bn); 91 | mth=th_next(1)+th_next(2); 92 | 93 | br=br+1; 94 | end 95 | 96 | end 97 | 98 | Dth_next= th_next(2)-th_next(1) ; 99 | 100 | end 101 | 102 | %% ------------------------------rk4--------------------------------------- 103 | function [ th_next ] = rk4(th_0,c,h,bn) 104 | 105 | k_1= calculate_dot_th1th2(th_0,c,bn); 106 | k_2= calculate_dot_th1th2((th_0 + 0.5*h*k_1),c,bn); 107 | k_3= calculate_dot_th1th2((th_0 + 0.5*h*k_2),c,bn); 108 | k_4= calculate_dot_th1th2((th_0 + h*k_3),c,bn); 109 | th_next=th_0 + h/6. * (k_1 + k_2 + k_3 + k_4); 110 | end 111 | 112 | 113 | %% -----------------------calculate_dot_th1th2----------------------------- 114 | function [ dot_th1th2 ] = calculate_dot_th1th2(th,c,bn) 115 | 116 | K=length(c)/2; 117 | dot_th1th2(1) = c(1); 118 | dot_th1th2(2) = c(K+1); 119 | br=2; 120 | 121 | for ii=1:bn 122 | dot_th1th2(1)=dot_th1th2(1)+c(br)*sin(ii*th(1))+c(br+1)*cos(ii*th(1)); 123 | dot_th1th2(2)=dot_th1th2(2)+c(K+br)*sin(ii*th(2))+c(K+br+1)*cos(ii*th(2)); 124 | br=br+2; 125 | end 126 | 127 | for ii=1:bn 128 | dot_th1th2(1)=dot_th1th2(1)+c(br)*sin(ii*th(2))+c(br+1)*cos(ii*th(2)); 129 | dot_th1th2(2)=dot_th1th2(2)+c(K+br)*sin(ii*th(1))+c(K+br+1)*cos(ii*th(1)); 130 | br=br+2; 131 | end 132 | 133 | for ii=1:bn 134 | for jj=1:bn 135 | dot_th1th2(1)=dot_th1th2(1)+c(br)*sin(ii*th(1)+jj*th(2))+c(br+1)*cos(ii*th(1)+jj*th(2)); 136 | dot_th1th2(2)=dot_th1th2(2)+c(br+1)*sin(ii*th(1)+jj*th(2))+c(br+3)*cos(ii*th(1)+jj*th(2)); 137 | br=br+2; 138 | 139 | dot_th1th2(1)=dot_th1th2(1)+c(br)*sin(ii*th(1)-jj*th(2))+c(br+1)*cos(ii*th(1)-jj*th(2)); 140 | dot_th1th2(2)=dot_th1th2(2)+c(K+br)*sin(ii*th(1)-jj*th(2))+c(K+br+1)*cos(ii*th(1)-jj*th(2)); 141 | br=br+2; 142 | end 143 | end 144 | 145 | end 146 | 147 | %% --------------uneven_forward_wrapping_aware_f2_differences-------------- 148 | 149 | function [ f ] = uneven_forward_wrapping_aware_f2_differences(fx0,fxh,fxk,h,k) 150 | 151 | fx0 = wrapToPi(fx0); 152 | fxh = wrapToPi(fxh); 153 | fxk = wrapToPi(fxk); 154 | 155 | temp= ( h*fxk -k*fxh + (k-h)*fx0 ) / ( k*(k - h) ); 156 | f(2)= 2*temp/h; 157 | f(1)= (fxh - fx0)/h - h*temp; 158 | end 159 | 160 | %% -------------------------wrapToPi_-------------------------------------- 161 | function fx0 = wrapToPi(fx1) 162 | fx0=mod(fx1,2*pi); 163 | end 164 | %% -------------------------END-------------------------------------------- -------------------------------------------------------------------------------- /allguis/guis/bispectrum/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | ################# 32 | ## MATLAB 33 | ################# 34 | *.asv 35 | 36 | ################# 37 | ## Visual Studio 38 | ################# 39 | 40 | ## Ignore Visual Studio temporary files, build results, and 41 | ## files generated by popular Visual Studio add-ons. 42 | 43 | # User-specific files 44 | *.suo 45 | *.user 46 | *.sln.docstates 47 | 48 | # Build results 49 | 50 | [Dd]ebug/ 51 | [Rr]elease/ 52 | x64/ 53 | build/ 54 | [Bb]in/ 55 | [Oo]bj/ 56 | 57 | # MSTest test Results 58 | [Tt]est[Rr]esult*/ 59 | [Bb]uild[Ll]og.* 60 | 61 | *_i.c 62 | *_p.c 63 | *.ilk 64 | *.meta 65 | *.obj 66 | *.pch 67 | *.pdb 68 | *.pgc 69 | *.pgd 70 | *.rsp 71 | *.sbr 72 | *.tlb 73 | *.tli 74 | *.tlh 75 | *.tmp 76 | *.tmp_proj 77 | *.log 78 | *.vspscc 79 | *.vssscc 80 | .builds 81 | *.pidb 82 | *.log 83 | *.scc 84 | 85 | # Visual C++ cache files 86 | ipch/ 87 | *.aps 88 | *.ncb 89 | *.opensdf 90 | *.sdf 91 | *.cachefile 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | 98 | # Guidance Automation Toolkit 99 | *.gpState 100 | 101 | # ReSharper is a .NET coding add-in 102 | _ReSharper*/ 103 | *.[Rr]e[Ss]harper 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | *.ncrunch* 113 | .*crunch*.local.xml 114 | 115 | # Installshield output folder 116 | [Ee]xpress/ 117 | 118 | # DocProject is a documentation generator add-in 119 | DocProject/buildhelp/ 120 | DocProject/Help/*.HxT 121 | DocProject/Help/*.HxC 122 | DocProject/Help/*.hhc 123 | DocProject/Help/*.hhk 124 | DocProject/Help/*.hhp 125 | DocProject/Help/Html2 126 | DocProject/Help/html 127 | 128 | # Click-Once directory 129 | publish/ 130 | 131 | # Publish Web Output 132 | *.Publish.xml 133 | *.pubxml 134 | *.publishproj 135 | 136 | # NuGet Packages Directory 137 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 138 | #packages/ 139 | 140 | # Windows Azure Build Output 141 | csx 142 | *.build.csdef 143 | 144 | # Windows Store app package directory 145 | AppPackages/ 146 | 147 | # Others 148 | sql/ 149 | *.Cache 150 | ClientBin/ 151 | [Ss]tyle[Cc]op.* 152 | ~$* 153 | *~ 154 | *.dbmdl 155 | *.[Pp]ublish.xml 156 | *.pfx 157 | *.publishsettings 158 | 159 | # RIA/Silverlight projects 160 | Generated_Code/ 161 | 162 | # Backup & report files from converting an old project file to a newer 163 | # Visual Studio version. Backup files are not needed, because we have git ;-) 164 | _UpgradeReport_Files/ 165 | Backup*/ 166 | UpgradeLog*.XML 167 | UpgradeLog*.htm 168 | 169 | # SQL Server files 170 | App_Data/*.mdf 171 | App_Data/*.ldf 172 | 173 | ############# 174 | ## Windows detritus 175 | ############# 176 | 177 | # Windows image file caches 178 | Thumbs.db 179 | ehthumbs.db 180 | 181 | # Folder config file 182 | Desktop.ini 183 | 184 | # Recycle Bin used on file shares 185 | $RECYCLE.BIN/ 186 | 187 | # Mac crap 188 | .DS_Store 189 | 190 | 191 | ############# 192 | ## Python 193 | ############# 194 | 195 | *.py[cod] 196 | 197 | # Packages 198 | *.egg 199 | *.egg-info 200 | dist/ 201 | build/ 202 | eggs/ 203 | parts/ 204 | var/ 205 | sdist/ 206 | develop-eggs/ 207 | .installed.cfg 208 | 209 | # Installer logs 210 | pip-log.txt 211 | 212 | # Unit test / coverage reports 213 | .coverage 214 | .tox 215 | 216 | #Translations 217 | *.mo 218 | 219 | #Mr Developer 220 | .mr.developer.cfg 221 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Bispectrum.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/guis/bispectrum/Bispectrum.fig -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/biphaseWavMod.m: -------------------------------------------------------------------------------- 1 | 2 | function [biamp, biphase] = biphaseWavMod(sig1, sig2, fs, f1, f2, varargin) 3 | % Author: Aleksandra Pidde 4 | % a.pidde@lancaster.ac.uk, aleksandra.pidde@gmail.com 5 | 6 | % date: 31.12.2017 7 | % update: 8.01.2018 8 | % 9 | % calculating wavelet biphase and biamplitude 10 | % sig1, sig2: signals 11 | % fs: sampling frequency 12 | % f1, f2: pair of frequency to calculate biamplitude and biphase 13 | % 14 | % varargin (optional): 15 | % 'f0': tradeoff between the time and frequency resolutions, the higher, the 16 | % better frequency resolution, the lower the better time resolution, 17 | % default 1 18 | % 'wavelet': type of wavelet, {'morlet', 'modMorlet'}, default 'morlet' 19 | % 'cutEdges': cutting of the cone of influence, {true, false}, default 20 | % true 21 | % 'd': Gaussian decay in Morlet wavelet, according to 22 | % correction, default 2 23 | % 'p': normalization factor (Kaiser, A friendly guide to wavelets, 24 | % params from eq 3.6), default 1 25 | % OUTPUT 26 | % biamp: time-depandant biamplitude 27 | % biphase: time-depandant biphase 28 | 29 | wavelet = 'morlet'; 30 | f0 = 1; 31 | cutEdges = true; 32 | d = 2; 33 | p = 1; 34 | if nargin >= 5 + 2 35 | for i = 1 : 2 : nargin - 5 36 | switch varargin{i} 37 | case 'wavelet' 38 | wavelet = varargin{i + 1}; 39 | case 'f0' 40 | f0 = varargin{i + 1}; 41 | case 'cutEdges' 42 | cutEdges = varargin{i + 1}; 43 | case 'd' 44 | d = varargin{i + 1}; 45 | case 'p' 46 | p = varargin{i + 1}; 47 | otherwise 48 | disp('problem with the agrument') 49 | end 50 | end 51 | end 52 | 53 | auto = false; 54 | if compareMatrix(sig1, sig2) 55 | auto = true; 56 | end 57 | WT1 = wtAtfMod(sig1, fs, f1, 'f0', f0, 'wavelet', wavelet, 'cutEdges', cutEdges, 'p', p, 'd', d); 58 | if auto && f1 == f2 59 | WT2 = WT1; 60 | else 61 | WT2 = wtAtfMod(sig2, fs, f2, 'f0', f0, 'wavelet', wavelet, 'cutEdges', cutEdges, 'p', p, 'd', d); 62 | end 63 | f3 = f1 + f2; 64 | WT3 = wtAtfMod(sig2, fs, f3, 'f0', f0, 'wavelet', wavelet, 'cutEdges', cutEdges, 'p', p, 'd', d); 65 | 66 | xx = WT1 .* WT2 .* conj(WT3); 67 | biamp = abs(xx); 68 | biphase = unwrap(angle(xx)); 69 | %biphase = angle(xx); 70 | end 71 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/biphaseWavNew.m: -------------------------------------------------------------------------------- 1 | % update for MODA: 19.07.2018 2 | % code compatible with Dmytro Iatsenko's wt.m 3 | % author: Aleksandra Pidde aleksandra.pidde@gmail.com, 4 | % a.pidde@lancaster.ac.uk 5 | 6 | function [biamp, biphase] = biphaseWavNew(sig1, sig2, fs, fr, opt) 7 | % calculating wavelet biamplitude and biphase of two signal 8 | % 9 | % INPUT: 10 | % sig1, sig2: signals 11 | % fs: sampling frequency 12 | % fr: pair of frequencies, [f1, f2], f1 is from sig1, f2 from sig2 13 | % opt: structure of optimal parameters returned by wt.m 14 | % 15 | % OUTPUT: 16 | % biamp: wavelet biamplitude 17 | % biphase: wavelet biphase 18 | 19 | f1 = fr(1); 20 | f2 = fr(2); 21 | f3 = f1 + f2; 22 | wt1 = wtAtf2(sig1, fs, f1, opt); 23 | wt2 = wtAtf2(sig2, fs, f2, opt); 24 | wt3 = wtAtf2(sig2, fs, f3, opt); 25 | 26 | xx = wt1 .* wt2 .* conj(wt3); 27 | biamp = abs(xx); 28 | biphase = unwrap(angle(xx)); 29 | end 30 | 31 | 32 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/bispecWavMod.m: -------------------------------------------------------------------------------- 1 | 2 | function [Bisp, freqs, Norm, WT1, WT2] = bispecWavMod(sig1, sig2, fs,varargin) 3 | % Author: Aleksandra Pidde 4 | % a.pidde@lancaster.ac.uk, aleksandra.pidde@gmail.com 5 | % date: 30.12.2017 6 | % update: 8.01.2018 7 | % 8 | % calculating wavelet bispectrum 9 | % sig1, sig2: signals 10 | % fs: sampling frequency 11 | % 12 | % varargin (optional): 13 | % 'wavelet': type of wavelet, {'morlet', 'modMorlet'}, default 'morlet' 14 | % 'f0': tradeoff between the time and frequency resolutions, the higher, the 15 | % better frequency resolution, the lower the better time resolution, 16 | % default 1 17 | % 'fmin': minimal frequency [Hz], bigger than 1 / T, where T is T of 18 | % the signal, default is such to fit one length of the wavelet in 19 | % big scale 20 | % 'fmax': maximal frequency [Hz], smaller than Nyquist freguency: 21 | % fs / 2, default is fs / 2 22 | % 'nv': number of voices, frequency discretization, meaning the next 23 | % frequency equals previous one multiplied on [2^(1/nv)], 24 | % default 16 25 | % 'cutEdges': cutting of the cone of influence, {true, false}, default 26 | % true 27 | % 'd': Gaussian decay in Morlet wavelet, according to 28 | % correction, default 2 29 | % 'p': normalization factor (Kaiser, A friendly guide to wavelets, 30 | % params from eq 3.6), default 1 31 | % 32 | % OUTPUT 33 | % Bisp: bispectrum 34 | % freq: vector of frequencies 35 | % Norm: normalisation for bicoherence 36 | try 37 | 38 | bstype={'111';'222';'122';'211'}; 39 | N = length(sig1); sig1 = sig1(:); 40 | sig1 = detrend(sig1); 41 | sig2 = sig2(:); sig2 = detrend(sig2); 42 | T = N / fs; 43 | th = 0.001; % amplitude threshold for wavelet to be non-zero 44 | % default 45 | wavelet = 'morlet'; 46 | f0 = 1; 47 | cutEdges = true; 48 | fmin = {}; 49 | fmax = fs / 2; 50 | nv = 16; 51 | p = 1; 52 | d = 2; 53 | wbar=0; 54 | % if defined by user 55 | if nargin >= 2 + 3 56 | for i = 1 : 2 : nargin - 3 57 | switch varargin{i} 58 | case 'wavelet' 59 | wavelet = varargin{i + 1}; 60 | case 'f0' 61 | f0 = varargin{i + 1}; 62 | case 'cutEdges' 63 | cutEdges = varargin{i + 1}; 64 | case 'fmin' 65 | fmin = varargin{i + 1}; 66 | case 'fmax' 67 | fmax = varargin{i + 1}; 68 | case 'nv' 69 | nv = varargin{i + 1}; 70 | case 'd' 71 | d = varargin{i + 1}; 72 | case 'p' 73 | p = varargin{i + 1}; 74 | case 'handles' 75 | handles=varargin{i+1}; 76 | case 'hObject' 77 | hObject=varargin{i+1}; 78 | case 'num' 79 | numb=varargin{i+1}; 80 | case 'wbar' 81 | wbar=varargin{i+1}; 82 | otherwise 83 | disp('problem with the argument') 84 | end 85 | end 86 | end 87 | 88 | if wbar==1 89 | handles.h = waitbar(0,'Calculating bispectrum...',... 90 | 'CreateCancelBtn',... 91 | 'setappdata(gcbf,''canceling'',1)'); 92 | setappdata(handles.h,'canceling',0) 93 | guidata(hObject,handles); 94 | else 95 | end 96 | 97 | 98 | om0 = 2 * pi * f0; %just for convenience denote circular central frequency 99 | if isempty(fmin) 100 | fmin = 2 * f0 / T * sqrt(2) * sqrt(-log(sqrt(2 * pi) * th)); 101 | end 102 | 103 | if isnan(fmin) 104 | fmin = 2 * f0 / T * sqrt(2) * sqrt(-log(sqrt(2 * pi) * th)); 105 | end 106 | if strcmpi(wavelet, 'morlet') 107 | norm = @(om) (om0 / om)^(1-p); 108 | fwt = @(xi)(exp(-(1/2) * (om0-xi).^2) - exp(-(1/2) * (om0^2 + xi.^2))); 109 | len = @(om) 2 * (om0 / om) * sqrt(-2 * log(sqrt(2 * pi) * th)); 110 | 111 | elseif strcmpi(wavelet, 'modMorlet') 112 | % modified Morlet, eq. 19 from J. Jamsek, A. Stefanovska, and P. V. E. McClintock, PrE 76, 046221, 2007 113 | omMin = 2 * pi * fmin; omMax = 2 * pi * fmax; 114 | a = @(om) 2.^(1.8 * (om - omMin) / (omMax - omMin)); 115 | c = 3.9487 * pi^(-0.25); 116 | % I try to find the length of Morlet wavelet... 117 | A = @(om) 1/sqrt(2 * pi) * a(om) * c; 118 | len = @(om) 2 * (om0 / om) * sqrt(-d * log(th / A(om))); 119 | norm = @(om) 1 / len(om) * (om0 ./ om); 120 | fwt = @(xi) a(xi) .* c * sqrt(d/2) .* (exp(-(d/4) * (om0-xi).^2) - exp(-om0^2 * d / 4 - xi.^2 / 2)); 121 | if isempty(fmin) 122 | fmin = 2 * f0 / T * sqrt(2) * sqrt(-log(sqrt(2 * pi) * th)); 123 | end 124 | else 125 | error('Invalid wavelet name, Morlet or ModMorlet'); 126 | end 127 | 128 | auto = false; 129 | if compareMatrix(sig1, sig2) 130 | auto = true; 131 | end 132 | [WT1, freqs] = myWt(sig1, fs, 'f0', f0, 'fmin', fmin, 'fmax', fmax, 'wavelet', wavelet, 'nv', nv, 'cutEdges', cutEdges, 'p', p, 'd', d); 133 | if auto 134 | WT2 = WT1; 135 | else 136 | [WT2, freqs] = myWt(sig2, fs, 'f0', f0, 'fmin', fmin, 'fmax', fmax, 'wavelet', wavelet, 'nv', nv, 'cutEdges', cutEdges, 'p', p, 'd', d); 137 | end 138 | 139 | nf = length(freqs); %number of frequencies 140 | Bisp = NaN * zeros(nf, nf); 141 | Norm = ones(nf, nf); 142 | 143 | nq = ceil((N + 1) / 2); 144 | ff = [(0 : nq - 1), -fliplr(1 : N - nq)] * fs / N; 145 | ff = ff(:); 146 | 147 | fx = fft(sig2, N); 148 | fx(ff <= 0) = 0; 149 | 150 | for j = 1 : nf 151 | if wbar==1 152 | if getappdata(handles.h,'canceling') 153 | guidata(hObject,handles); 154 | break; 155 | end 156 | else 157 | end 158 | 159 | kstart = 1; 160 | if auto 161 | kstart = j; 162 | end 163 | for k = kstart : nf 164 | if wbar==1 165 | if getappdata(handles.h,'canceling') 166 | guidata(hObject,handles); 167 | break; 168 | end 169 | else 170 | end 171 | 172 | f3 = freqs(j) + freqs(k); 173 | bigger = max([j k]); 174 | idx3 = find(freqs >= f3, 1); 175 | if (f3 <= freqs(end)) && (freqs(idx3 - 1) > freqs(bigger)) 176 | WTdat = wtAtfMod(sig2, fs, f3, 'f0', f0, 'wavelet', wavelet, 'cutEdges', cutEdges, 'p', p, 'd', d); 177 | WTdat = WTdat(:).'; % make sure it is horizontal vector 178 | xx = WT1(j, :) .* WT2(k, :) .* conj(WTdat); 179 | ss = nanmean(xx); 180 | Bisp(j, k) = ss; 181 | 182 | norm1 = nanmean(abs(WT1(j, :) .* WT2(k, :)).^2); 183 | norm2 = nanmean(abs(WTdat).^2); 184 | a = sqrt(norm1 * norm2); 185 | Norm(j, k) = a; 186 | end 187 | end 188 | if wbar==1 189 | waitbar(j / length(freqs),handles.h,sprintf(['Calculating Bispectrum ',bstype{numb},' (%d/%d)'],j,length(freqs))); 190 | else 191 | end 192 | end 193 | if wbar==1 194 | delete(handles.h); 195 | else 196 | end 197 | 198 | 199 | 200 | catch e 201 | errordlg(e.message,'Error'); 202 | if wbar==1 203 | delete(handles.h); 204 | else 205 | end 206 | rethrow(e) 207 | end 208 | end 209 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/bispecWavNew.m: -------------------------------------------------------------------------------- 1 | % update for MODA 20.07.2018 2 | % code compatible with Dmytro Iatsenko's wt.m 3 | % author: Aleksandra Pidde a.pidde@gmail.com, a.pidde@lancaster.ac.uk 4 | 5 | function [Bisp, freq, opt, wt1, wt2] = bispecWavNew(sig1, sig2, fs, varargin) 6 | % function calculating wavelet bispectrum 7 | % 8 | % INPUT: 9 | % sig1, sig2: signals 10 | % fs: sampling frequency 11 | % optional: 12 | % opt: structure of optimal parameters returned by wt.m 13 | % 14 | % OUTPUT: 15 | % Bisp: bispectrum, 2 dim matrix of complex values 16 | % freq: frequencies 17 | % opt: structure of optimal parameters returned by wt.m 18 | 19 | try 20 | bstype={'111';'222';'122';'211'}; 21 | 22 | if nargin > 3 23 | if nargin == 4 && iscell(varargin{1}) 24 | in = varargin{1}; 25 | else 26 | in = varargin; 27 | end 28 | 29 | [wt1, freq, opt] = wt(sig1, fs, in{:}); 30 | [wt2, freq, opt] = wt(sig2, fs, in{:}); 31 | else 32 | [wt1, freq, opt] = wt(sig1, fs); 33 | [wt2, freq, opt] = wt(sig2, fs); 34 | end 35 | 36 | dt = 1 / fs; 37 | nfreq = length(freq); 38 | Bisp = NaN * zeros(nfreq, nfreq); 39 | auto = false; 40 | if compareMatrix(wt1, wt2) 41 | auto = true; 42 | end 43 | wbar=0; 44 | 45 | if nargin >= 2 + 3 46 | for i = 1 : 2 : nargin - 3 47 | switch varargin{i} 48 | 49 | case 'handles' 50 | handles=varargin{i+1}; 51 | case 'hObject' 52 | hObject=varargin{i+1}; 53 | case 'num' 54 | numb=varargin{i+1}; 55 | case 'wbar' 56 | wbar=varargin{i+1}; 57 | 58 | end 59 | end 60 | end 61 | 62 | if wbar==1 63 | handles.h = waitbar(0,'Calculating bispectrum...',... 64 | 'CreateCancelBtn',... 65 | 'setappdata(gcbf,''canceling'',1)'); 66 | setappdata(handles.h,'canceling',0) 67 | guidata(hObject,handles); 68 | else 69 | end 70 | 71 | for j = 1 : nfreq 72 | if wbar==1 73 | if getappdata(handles.h,'canceling') 74 | guidata(hObject,handles); 75 | break; 76 | end 77 | else 78 | end 79 | kstart = 1; 80 | if auto 81 | kstart = j; 82 | end 83 | 84 | if wbar==1 85 | if getappdata(handles.h,'canceling') 86 | guidata(hObject,handles); 87 | break; 88 | end 89 | else 90 | end 91 | for k = kstart : nfreq 92 | f3 = freq(j) + freq(k); 93 | bigger = max([j k]); 94 | idx3 = find(freq >= f3, 1); 95 | if (f3 <= freq(end)) && (freq(idx3 - 1) > freq(bigger)) 96 | WTdat = wtAtf2(sig2, fs, f3, opt); 97 | WTdat = WTdat(:).'; % make sure it is horizontal vector 98 | xx = wt1(j, :) .* wt2(k, :) .* conj(WTdat); 99 | %xx = TFR1(j, :) .* TFR2(k, :) * transpose(conj(TFR2(idx3, :))); 100 | ss = nanmean(xx); 101 | Bisp(j, k) = ss; 102 | end 103 | end 104 | if wbar==1 105 | waitbar(j / length(freq),handles.h,sprintf(['Calculating Bispectrum ',bstype{numb},' (%d/%d)'],j,length(freq))); 106 | else 107 | end 108 | end 109 | if wbar==1 110 | delete(handles.h); 111 | else 112 | end 113 | 114 | catch e 115 | errordlg(e.message,'Error'); 116 | if wbar==1 117 | delete(handles.h); 118 | else 119 | end 120 | rethrow(e) 121 | 122 | end -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/bispectrum_analysis.m: -------------------------------------------------------------------------------- 1 | function [amp1, amp2, avg_amp1, avg_amp2, pow1, pow2, avg_pow1, avg_pow2, bispxxx, bispppp, bispxpp, bisppxx, surrxxx, surrppp, surrxpp, surrpxx] = bispectrum_analysis(sig1, sig2, fmax, fmin, fc, fs, nv, ns, preprocess) 2 | 3 | bispxxx=[]; 4 | bispppp=[]; 5 | bispxpp=[]; 6 | bisppxx=[]; 7 | surrxxx=[]; 8 | surrppp=[]; 9 | surrxpp=[]; 10 | surrpxx=[]; 11 | 12 | if ~preprocess 13 | [bispxxx] = bispecWavNew(sig1,sig1, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'preprocess','off','handles',handles,'hObject',hObject,'num',1,'wbar',1); bispxxx=abs(bispxxx); 14 | [bispppp] = bispecWavNew(sig2,sig2, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'preprocess','off','handles',handles,'hObject',hObject,'num',2,'wbar',1); bispppp=abs(bispppp); 15 | [bispxpp,freqarr, wavopt,WT1, WT2] = bispecWavNew(sig1,sig2, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'preprocess','off','handles',handles,'hObject',hObject,'num',3,'wbar',1); bispxpp=abs(bispxpp); 16 | [bisppxx] = bispecWavNew(sig2,sig1, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'preprocess','off','handles',handles,'hObject',hObject,'num',4,'wbar',1); bisppxx=abs(bisppxx); 17 | 18 | if ns>0 19 | for j=1:ns 20 | surr1=wavsurrogate(sig1,'IAAFT2',1); 21 | surr2=wavsurrogate(sig2,'IAAFT2',1); 22 | 23 | surrxxx(:,:,j)=abs(bispecWavNew(surr1,surr1, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'preprocess','off','handles',handles,'hObject',hObject,'num',1)); 24 | surrppp(:,:,j)=abs(bispecWavNew(surr2,surr2, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'preprocess','off','handles',handles,'hObject',hObject,'num',2)); 25 | surrxpp(:,:,j)=abs(bispecWavNew(surr1,surr2, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'preprocess','off','handles',handles,'hObject',hObject,'num',3)); 26 | surrpxx(:,:,j)=abs(bispecWavNew(surr2,surr1, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'preprocess','off','handles',handles,'hObject',hObject,'num',4)); 27 | end 28 | end 29 | else 30 | [bispxxx] = bispecWavNew(sig1,sig1,fs,'handles',handles,'hObject',hObject,'f0',fc,'nv',nv,'fmin',fmin,'fmax',fmax,'num',1,'wbar',1); bispxxx=abs(bispxxx); 31 | [bispppp] = bispecWavNew(sig2,sig2,fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'handles',handles,'hObject',hObject,'num',2,'wbar',1); bispppp=abs(bispppp); 32 | [bispxpp,freqarr,wavopt,WT1, WT2] = bispecWavNew(sig1,sig2,fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'handles',handles,'hObject',hObject,'num',3,'wbar',1); bispxpp=abs(bispxpp); 33 | [bisppxx] = bispecWavNew(sig2,sig1,fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'handles',handles,'hObject',hObject,'num',4,'wbar',1); bisppxx=abs(bisppxx); 34 | 35 | if ns>0 36 | for j=1:ns 37 | surr1=wavsurrogate(sig1,'IAAFT2',1); 38 | surr2=wavsurrogate(sig2,'IAAFT2',1); 39 | 40 | surrxxx(:,:,j)=abs(bispecWavNew(surr1,surr1, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'handles',handles,'hObject',hObject,'num',1)); 41 | surrppp(:,:,j)=abs(bispecWavNew(surr2,surr2, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'handles',handles,'hObject',hObject,'num',2)); 42 | surrxpp(:,:,j)=abs(bispecWavNew(surr1,surr2, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'handles',handles,'hObject',hObject,'num',3)); 43 | surrpxx(:,:,j)=abs(bispecWavNew(surr2,surr1, fs,'fmin',fmin,'fmax',fmax,'f0',fc,'nv',nv,'handles',handles,'hObject',hObject,'num',4)); 44 | end 45 | end 46 | end 47 | 48 | amp1=abs(WT1); 49 | avg_amp1=nanmean(amp1,2); 50 | pow1=abs(WT1).^2; 51 | avg_pow1=nanmean(pow1,2); 52 | 53 | amp2=abs(WT2); 54 | avg_amp2=nanmean(amp2,2); 55 | pow2=abs(WT2).^2; 56 | avg_pow2=nanmean(pow2,2); 57 | 58 | end 59 | 60 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/compareMatrix.m: -------------------------------------------------------------------------------- 1 | % update for MODA 19.07.2018 2 | % author: Aleksandra Pidde a.pidde@gmail.com, a.pidde@lancaster.ac.uk 3 | 4 | function res = compareMatrix(A, B) 5 | % function helper compating 2 matrix, A and B 6 | nanA = isnan(A); nanB = isnan(B); 7 | res = isequal(nanA, nanB); 8 | 9 | infA = isinf(A); infB = isinf(B); 10 | res = res * isequal(infA, infB); 11 | 12 | idxA = nanA + infA; idxB = nanB + infB; 13 | res = res * isequal(A(~idxA), B(~idxB)); 14 | end 15 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/myWt.m: -------------------------------------------------------------------------------- 1 | 2 | function [WT, freqs] = myWt(sig, fs, varargin) 3 | % author: Aleksandra Pidde 4 | % a.pidde@lancaster.ac.uk, aleksandra.pidde@gmail.com 5 | % date: 30.12.2017 6 | % update: 8.01.2018 7 | % 8 | % calculating wavelets 9 | % INPUT 10 | % sig: signal 11 | % fs: sampling frequency [Hz] 12 | % 13 | % varargin (optional): 14 | % 'wavelet':type of wavelet, {'morlet', 'modMorlet'}, default 'morlet' 15 | % 'f0': tradeoff between the time and frequency resolutions, the higher, the 16 | % better frequency resolution, the lower the better time 17 | % resolution, default 1 18 | % 'cutEdges':cutting of the cone of influence, {true, false}, default true 19 | % 'fmin': minimal frequency [Hz], bigger than 1 / T, where T is T of the 20 | % signal, default is such to fit one length of the wavelet in 21 | % small scale 22 | % 'fmax': maximal frequency [Hz], smaller than Nyquist freguency: fs / 2, 23 | % default is fs / 2 24 | % 'nv': number of voices, frequency discretization, meaning the next 25 | % frequency equals previous one multiplied on [2^(1/nv)], default 26 | % 16 27 | % 'd': Gaussian decay in Morlet wavelet, according to 28 | % correction, default 2 29 | % 'p': normalization factor (Kaiser, A friendly guide to wavelets, 30 | % params from eq 3.6), default 1/2, preserving the energy 31 | % 32 | % OUTPUT 33 | % WT: wavelet transform 34 | % freq: frequency vector 35 | 36 | N = length(sig); sig = sig(:); 37 | sig = detrend(sig); 38 | T = N / fs; 39 | th = 0.001; % amplitude threshold for wavelet to be non-zero 40 | % default 41 | wavelet = 'morlet'; 42 | f0 = 1; 43 | cutEdges = true; 44 | fmin = {}; 45 | fmax = fs / 2; 46 | nv = 16; 47 | p = 0.5; 48 | d = 2; 49 | % if defined by user 50 | if nargin >= 2 + 2 51 | for i = 1 : 2 : nargin - 2 52 | switch varargin{i} 53 | case 'wavelet' 54 | wavelet = varargin{i + 1}; 55 | case 'f0' 56 | f0 = varargin{i + 1}; 57 | case 'cutEdges' 58 | cutEdges = varargin{i + 1}; 59 | case 'fmin' 60 | fmin = varargin{i + 1}; 61 | case 'fmax' 62 | fmax = varargin{i + 1}; 63 | case 'nv' 64 | nv = varargin{i + 1}; 65 | case 'd' 66 | d = varargin{i + 1}; 67 | case 'p' 68 | p = varargin{i + 1}; 69 | otherwise 70 | disp('problem with the agrument') 71 | end 72 | end 73 | end 74 | 75 | om0 = 2 * pi * f0; 76 | if strcmpi(wavelet, 'morlet') 77 | norm = @(om) (om0 / om)^(1-p); 78 | fwt = @(xi)(exp(-(1/2) * (om0-xi).^2) - exp(-(1/2) * (om0^2 + xi.^2))); 79 | len = @(om) 2 * (om0 / om) * sqrt(-2 * log(sqrt(2 * pi) * th)); 80 | if isempty(fmin) 81 | fmin = 2 * f0 / T * sqrt(2) * sqrt(-log(sqrt(2 * pi) * th)); 82 | end 83 | elseif strcmpi(wavelet, 'modMorlet') 84 | % modified Morlet, eq. 19 from J. Jamsek, A. Stefanovska, and P. V. E. McClintock, PrE 76, 046221, 2007 85 | omMin = 2 * pi / T; omMax = 2 * pi * fmax; 86 | a = @(om) 2.^(1.8 * (om - omMin) / (omMax - omMin)); 87 | c = 3.9487 * pi^(-0.25); 88 | % I try to find the length of Morlet wavelet... 89 | A = @(om) 1/sqrt(2 * pi) * a(om) * c; 90 | len = @(om) 2 * (om0 / om) * sqrt(-d * log(th / A(om))); 91 | norm = @(om) 1 / len(om) * (om0 ./ om); 92 | fwt = @(xi) a(xi) .* c * sqrt(d/2) .* (exp(-(d/4) * (om0-xi).^2) - exp(-om0^2 * d / 4 - xi.^2 / 2)); 93 | if isempty(fmin) 94 | fmin = 2 * f0 / T * sqrt(2) * sqrt(-log(sqrt(2 * pi) * th)); 95 | end 96 | else 97 | error('Invalid wavelet name, Morlet or ModMorlet'); 98 | end 99 | 100 | % frequencies 101 | freqs = 2.^((ceil(nv * log2(fmin)) : floor(nv * log2(fmax)))' / nv); 102 | nf = length(freqs); % number of frequencies 103 | %freqs = linspace(fmin, fmax, nf); %checkpoint what happens when generate for linear axis 104 | nq = ceil((N + 1) / 2); 105 | ff = [(0 : nq - 1), -fliplr(1 : N - nq)] * fs / N; 106 | ff = ff(:); 107 | 108 | fx = fft(sig, N); 109 | fx(ff <= 0) = 0; 110 | 111 | %% 112 | nor = zeros(1, nf); 113 | % wavelet transform 114 | WT = zeros(nf, N) * NaN; 115 | for sn = 1 : nf 116 | %cone of influence 117 | n1 = 0; n2 = n1; 118 | if cutEdges 119 | n1 = floor(fs * 0.5 * len(2 * pi * freqs(sn))); 120 | n2 = n1; 121 | end 122 | if n1 + n2 < N 123 | freqswf = ff * om0 / (2 * pi * freqs(sn)); % for the wavelet 124 | fw = conj(fwt(2 * pi * freqswf)); 125 | nanid = find(isnan(fw) | ~isfinite(fw)); 126 | if ~isempty(nanid) % to avoid NaNs due to numerics, e.g. sin(0)/0 127 | fw(nanid) = conj(fwt(2 * pi * freqswf(nanid) + 10^(-14))); 128 | nanid = isnan(fw) | ~isfinite(fw); fw(nanid) = 0; 129 | end 130 | conv = fx .* fw(:); % convolution in the frequency domain 131 | out = norm(2 * pi * freqs(sn)) * ifft(conv, N); % calculate WT at each time 132 | %cone of influence 133 | WT(sn, 1 + n1 : N - n2) = out(1 + n1 : N - n2); 134 | end 135 | end 136 | 137 | end 138 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/python/biphaseWavPython.m: -------------------------------------------------------------------------------- 1 | % Copy of biphaseWavNew to be used as a Python library. 2 | 3 | function [biamp, biphase] = biphaseWavPython(sig1, sig2, fs, f0, fr, opt) 4 | % calculating wavelet biamplitude and biphase of two signal 5 | % 6 | % INPUT: 7 | % sig1, sig2: signals 8 | % fs: sampling frequency 9 | % fr: pair of frequencies, [f1, f2], f1 is from sig1, f2 from sig2 10 | % opt: structure of optimal parameters returned by wt.m 11 | % 12 | % OUTPUT: 13 | % biamp: wavelet biamplitude 14 | % biphase: wavelet biphase 15 | 16 | q = 2*pi*f0; 17 | opt.fwt = @(xi)exp(-(q^2/2)*(log(xi).^2)); 18 | 19 | opt.PadLR = {}; 20 | opt.PadLR{1} = opt.PadLR1; 21 | opt.PadLR{2} = opt.PadLR2; 22 | 23 | opt.twf = {}; 24 | opt.twf{1} = complex(opt.twf1r, opt.twf1i); 25 | opt.twf{2} = complex(opt.twf2r, opt.twf2i); 26 | 27 | f1 = fr(1); 28 | f2 = fr(2); 29 | f3 = f1 + f2; 30 | 31 | wt1 = wtAtf2Python(sig1, fs, f1, opt); 32 | wt2 = wtAtf2Python(sig2, fs, f2, opt); 33 | wt3 = wtAtf2Python(sig2, fs, f3, opt); 34 | 35 | xx = wt1 .* wt2 .* conj(wt3); 36 | biamp = abs(xx); 37 | biphase = unwrap(angle(xx)); 38 | end -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/python/bispecWavPython.m: -------------------------------------------------------------------------------- 1 | % Just a copy of bispecWavNew which is modified to run 2 | % without errors when packaged as a Python library. 3 | 4 | function [Bisp, freq, wt1, wt2, opt] = bispecWavPython(sig1, sig2, fs, varargin) 5 | try 6 | 7 | bstype={'111';'222';'122';'211'}; 8 | if nargin == 4 9 | opt = varargin{1}; 10 | [wt1, freq, opt] = wt(sig1, fs, opt); 11 | [wt2, freq, opt] = wt(sig2, fs, opt); 12 | else 13 | [wt1, freq, opt] = wt(sig1, fs); 14 | [wt2, freq, opt] = wt(sig2, fs); 15 | end 16 | 17 | dt = 1 / fs; 18 | nfreq = length(freq); 19 | Bisp = NaN * zeros(nfreq, nfreq); 20 | auto = false; 21 | if compareMatrix(wt1, wt2) 22 | auto = true; 23 | end 24 | wbar=0; 25 | 26 | if nargin >= 2 + 3 27 | for i = 1 : 2 : nargin - 3 28 | switch varargin{i} 29 | 30 | case 'handles' 31 | handles=varargin{i+1}; 32 | case 'hObject' 33 | hObject=varargin{i+1}; 34 | case 'num' 35 | numb=varargin{i+1}; 36 | case 'wbar' 37 | wbar=varargin{i+1}; 38 | 39 | end 40 | end 41 | end 42 | 43 | if wbar==1 44 | handles.h = waitbar(0,'Calculating bispectrum...',... 45 | 'CreateCancelBtn',... 46 | 'setappdata(gcbf,''canceling'',1)'); 47 | setappdata(handles.h,'canceling',0) 48 | guidata(hObject,handles); 49 | else 50 | end 51 | 52 | for j = 1 : nfreq 53 | if wbar==1 54 | if getappdata(handles.h,'canceling') 55 | guidata(hObject,handles); 56 | break; 57 | end 58 | else 59 | end 60 | kstart = 1; 61 | if auto 62 | kstart = j; 63 | end 64 | 65 | if wbar==1 66 | if getappdata(handles.h,'canceling') 67 | guidata(hObject,handles); 68 | break; 69 | end 70 | else 71 | end 72 | for k = kstart : nfreq 73 | f3 = freq(j) + freq(k); 74 | bigger = max([j k]); 75 | idx3 = find(freq >= f3, 1); 76 | if (f3 <= freq(end)) && (freq(idx3 - 1) > freq(bigger)) 77 | WTdat = wtAtf2(sig2, fs, f3, opt); 78 | WTdat = WTdat(:).'; % make sure it is horizontal vector 79 | xx = wt1(j, :) .* wt2(k, :) .* conj(WTdat); 80 | %xx = TFR1(j, :) .* TFR2(k, :) * transpose(conj(TFR2(idx3, :))); 81 | ss = nanmean(xx); 82 | Bisp(j, k) = ss; 83 | end 84 | end 85 | if wbar==1 86 | waitbar(j / length(freq),handles.h,sprintf(['Calculating Bispectrum ',bstype{numb},' (%d/%d)'],j,length(freq))); 87 | else 88 | end 89 | end 90 | if wbar==1 91 | delete(handles.h); 92 | else 93 | 94 | new = struct(); 95 | new.nv = opt.nv; 96 | new.RelTo = opt.RelTol; 97 | new.Padding = opt.Padding; 98 | new.fmin = opt.fmin; 99 | new.fmax = opt.fmax; 100 | new.Preprocess = opt.Preprocess; 101 | new.CutEdges = opt.CutEdges; 102 | 103 | new.PadLR1 = opt.PadLR(1); 104 | new.PadLR2 = opt.PadLR(2); 105 | 106 | new.t1e = opt.wp.t1e; 107 | new.t2e = opt.wp.t2e; 108 | 109 | new.ompeak = opt.wp.ompeak; 110 | 111 | new.xi1 = opt.wp.xi1; 112 | new.xi2 = opt.wp.xi2; 113 | 114 | new.t1 = opt.wp.t1; 115 | new.t2 = opt.wp.t2; 116 | 117 | new.twf1 = opt.wp.twf(1); 118 | new.twf2 = opt.wp.twf(2); 119 | 120 | opt = new; 121 | end 122 | 123 | catch e 124 | display(e.message); 125 | if wbar==1 126 | delete(handles.h); 127 | else 128 | end 129 | rethrow(e) 130 | 131 | end 132 | 133 | 134 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/python/wtAtf2Python.m: -------------------------------------------------------------------------------- 1 | % update for MODA 19.07.2018 2 | % code compatible with Dmytro Iatsenko's wt.m 3 | % author: Aleksandra Pidde a.pidde@gmail.com, a.pidde@lancaster.ac.uk 4 | % mostly taken from Dmytro Iatsenko's wt.m code 5 | 6 | function wt = wtAtf2(sig, fs, fr, opt) 7 | % function calculating wavelet transform of signal sig at frequency fr 8 | % 9 | % INPUT: 10 | % sig1: signal 11 | % fs: sampling frequency 12 | % fr: frequency for each the wavelet is caluculated 13 | % opt: structure of optimal parameters returned by wt.m 14 | % 15 | % OUTPUT: 16 | % wt: wavelet transform at frequency fr 17 | 18 | p = 1; 19 | N = length(sig); sig = sig(:); 20 | PadMode = opt.Padding; 21 | L = N; fmin = opt.fmin; fmax = opt.fmax; 22 | 23 | % ======== Signal preprocessing: detrending, filtering and padding ========= 24 | % [dflag] determines to do detrending and filtering before or after padding 25 | 26 | dflag = 0; 27 | if ~iscell(PadMode) 28 | if ~ischar(PadMode) && ~isempty(PadMode(PadMode ~= 0)), dflag = 1; end 29 | if strcmpi(PadMode, 'predictive') && fmin < 5 * fs / L, dflag = 1; end 30 | else 31 | if ~ischar(PadMode{1}) && ~isempty(PadMode{1}(PadMode{1} ~= 0)), dflag = 1; end 32 | if ~ischar(PadMode{2}) && ~isempty(PadMode{2}(PadMode{2} ~= 0)), dflag = 1; end 33 | if strcmpi(PadMode{1}, 'predictive') && fmin < 5 * fs / L, dflag = 1; end 34 | if strcmpi(PadMode{2}, 'predictive') && fmin < 5 * fs / L, dflag = 1; end 35 | end 36 | 37 | % Detrend (subtract third-order polynomial fit) and filter first for usual padding 38 | 39 | if strcmpi(opt.Preprocess, 'on') && dflag == 0 40 | [sig, fx, ff] = preprocess(sig, L, fs, fmin, fmax); 41 | end 42 | padleft = opt.PadLR{1}; padright = opt.PadLR{2}; 43 | sig = [padleft; sig; padright]; 44 | NL = length(sig); 45 | 46 | %Detrend (subtract third-order polynomial fit) after padding for special cases 47 | if strcmpi(opt.Preprocess, 'on') && dflag == 1 48 | [sig, fx, ff] = preprocess(sig, NL, fs, 0, fs / 2); 49 | end 50 | 51 | %Filtering of the padded signal 52 | Nq = ceil((NL + 1) / 2); 53 | ff = [(0 : Nq - 1), -fliplr(1 : NL - Nq)] * fs / NL; ff = ff(:); % frequencies in Fourier transform 54 | fx = fft(sig, NL); fx(ff <= 0) = 0; % Fourier transform of a signal (set to zero at negative frequencies) 55 | if strcmpi(opt.Preprocess,'on') 56 | fx(ff <= max([fmin, fs / L]) | ff >= fmax) = 0; % filter signal in a chosen frequency domain 57 | end 58 | 59 | coib1 = ceil(abs(opt.t1e * fs * (opt.ompeak./(2 * pi * fr)))); 60 | coib2 = ceil(abs(opt.t2e * fs * (opt.ompeak./(2 * pi * fr)))); %cone of influence edges 61 | 62 | if (opt.t2e - opt.t1e) * opt.ompeak / (2 * pi * fmax) > L / fs 63 | coib1 = 0; coib2 = 0; 64 | end 65 | 66 | if coib1 == 0 && coib2 == 0 67 | n1 = floor((NL - L) / 2); n2 = ceil((NL - L) / 2); 68 | else 69 | n1 = floor((NL - L) * coib1 / (coib1 + coib2)); 70 | n2 = ceil((NL - L) * coib2 / (coib1 + coib2)); 71 | end 72 | %plot(sig, '--'); 73 | % wavelet transform 74 | wt = zeros(1, N) * NaN; 75 | 76 | freqwf = ff * opt.ompeak / (2 * pi * fr); %frequencies for the wavelet 77 | ii = find(freqwf > opt.xi1 / (2 * pi) & freqwf < opt.xi2 / (2 * pi)); %take into account only frequencies within the wavelet support 78 | if ~isempty(opt.fwt) 79 | fw = conj(opt.fwt(2 * pi * freqwf(ii))); 80 | nid = find(isnan(fw) | ~isfinite(fw)); 81 | if ~isempty(nid) %to avoid NaNs due to numerics, e.g. sin(0)/0 82 | fw(nid) = conj(opt.fwt(2 * pi * freqwf(ii(nid)) + 1e-14)); 83 | nid = isnan(fw) | ~isfinite(fw); fw(nid) = 0; 84 | end 85 | else 86 | twav = (1 / fs) * [-(1 : ceil((NL - 1) / 2)) + 1, NL + 1 -(ceil((NL - 1) / 2) + 1 : NL)]'; 87 | timewf = (2 * pi * fr / opt.ompeak) * twav; 88 | jj = find(timewf > opt.t1 & timewf < opt.t2); 89 | tw = zeros(NL, 1); %take into account only times within the wavelet support 90 | tw(jj) = conj(opt.twf(timewf(jj))); 91 | nid = find(isnan(tw) | ~isfinite(tw)); 92 | if ~isempty(nid) %to avoid NaNs due to numerics, e.g. sin(0)/0 93 | tw(nid) = conj(opt.twf(timewf(nid) + 1e-14)); 94 | nid = isnan(tw) | ~isfinite(tw); tw(nid) = 0; 95 | end 96 | fw = (1 / fs) * fft(tw); fw = fw(ii); 97 | end 98 | cc = zeros(NL, 1); cc(ii) = fx(ii) .* fw(:); %convolution in the frequency domain 99 | out = ((opt.ompeak / (2 * pi * fr))^(1-p)) * ifft(cc, NL); % calculate WT at each time 100 | wt(1 : L) = out(1 + n1 : NL - n2); 101 | 102 | if strcmpi(opt.CutEdges,'on') 103 | wt(1 : coib1) = nan; 104 | wt(end - coib2 : end) = nan; 105 | end 106 | end 107 | 108 | function [newSig, fx, ff] = preprocess(sig, N, fs, fmin, fmax) 109 | % Detrending 110 | X = (1 : length(sig))' / fs; XM = ones(length(X), 4); 111 | for pn = 1 : 3 112 | CX = X .^ pn; 113 | XM(:, pn + 1) = (CX - mean(CX)) / std(CX); 114 | end 115 | w = warning('off', 'all'); sig = sig - XM * (pinv(XM) * sig); warning(w); 116 | 117 | % Filtering 118 | fx = fft(sig, N); % Fourier transform of a signal 119 | Nq = ceil((N + 1) / 2); 120 | ff = [(0 : Nq - 1), -fliplr(1 : N - Nq)] * fs / N; ff = ff(:); % frequencies in Fourier transform 121 | fx(abs(ff) <= max([fmin, fs / N]) | abs(ff) >= fmax) = 0; % filter signal in a chosen frequency domain 122 | newSig = ifft(fx); 123 | end 124 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/surrogate.m: -------------------------------------------------------------------------------- 1 | function [surr,varargout] = surrogate(signal,N,varargin) 2 | %Calculates Surrogates for a given time series and yields matrix of signals 3 | [m,L]=size(signal); 4 | if L==1, signal=(signal(:))'; [m,L]=size(signal); end %correct if not string 5 | 6 | surr=zeros(N,L); 7 | 8 | if nargin>2 9 | method=varargin{1}; 10 | else 11 | method='RP'; 12 | end 13 | 14 | if strcmp(method,'RP') % Random Permutation surrogates 15 | for k=1:N 16 | surr(k,:)=signal(randperm(L)); 17 | end 18 | 19 | elseif strcmp(method,'FT') % FT surrogates 20 | ll=ceil(L/2); 21 | ftsig=fft(signal,L); 22 | for k=1:N 23 | surr(k,1)=ftsig(1); randph=2*pi*randn(1,ll-1); 24 | surr(k,2:ll)=ftsig(2:ll).*exp(1i*randph); 25 | surr(k,2+L-ll:L)=conj(fliplr(surr(k,2:ll))); 26 | 27 | surr(k,:)=real(ifft(surr(k,:),L)); 28 | end 29 | 30 | elseif strcmp(method,'AAFT') % AAFT surrogates 31 | ll=ceil(L/2); 32 | sigma=std(signal); 33 | [sortsig,sortind]=sort(signal); rankind(sortind)=1:L; 34 | rescrank=zeros(1,L); 35 | for k=1:N 36 | rgs=sort(randgen(1,L,0,sigma)); 37 | rescsig=rgs(rankind); 38 | 39 | ftresc=fft(rescsig,L); 40 | surr(k,1)=ftresc(1); randph=2*pi*randgen(1,ll-1); 41 | %surr(k,2:ll)=abs(ftresc(2:ll)).*exp(1i*randph); % should we randomize all phases, since there might be some bias? 42 | surr(k,2:ll)=ftresc(2:ll).*exp(1i*randph); 43 | surr(k,2+L-ll:L)=conj(fliplr(surr(k,2:ll))); 44 | 45 | surr(k,:)=real(ifft(surr(k,:),L)); 46 | 47 | [~,rescind]=sort(surr(k,:)); rescrank(rescind)=1:L; 48 | surr(k,:)=sortsig(rescrank); 49 | end 50 | 51 | elseif strcmp(method,'IAAFT2') % IAAFT2 (exact spectrum), PS first seed 52 | maxitn=1000; % maximum number of iterations 53 | [sortsig,sortind]=sort(signal); rankind(sortind)=1:L; 54 | ftsig=fft(signal,L); 55 | ovitn=0; 56 | for k=1:N 57 | surr(k,:)=signal(randperm(L)); 58 | 59 | itn=1; iterrank=rankind; olditrank=zeros(1,L); 60 | while (max(abs(olditrank-iterrank))~=0 & itn= fmax) = 0; % filter signal in a chosen frequency domain 57 | end 58 | 59 | coib1 = ceil(abs(opt.wp.t1e * fs * (opt.wp.ompeak./(2 * pi * fr)))); 60 | coib2 = ceil(abs(opt.wp.t2e * fs * (opt.wp.ompeak./(2 * pi * fr)))); %cone of influence edges 61 | 62 | if (opt.wp.t2e - opt.wp.t1e) * opt.wp.ompeak / (2 * pi * fmax) > L / fs 63 | coib1 = 0; coib2 = 0; 64 | end 65 | 66 | if coib1 == 0 && coib2 == 0 67 | n1 = floor((NL - L) / 2); n2 = ceil((NL - L) / 2); 68 | else 69 | n1 = floor((NL - L) * coib1 / (coib1 + coib2)); 70 | n2 = ceil((NL - L) * coib2 / (coib1 + coib2)); 71 | end 72 | %plot(sig, '--'); 73 | % wavelet transform 74 | wt = zeros(1, N) * NaN; 75 | 76 | freqwf = ff * opt.wp.ompeak / (2 * pi * fr); %frequencies for the wavelet 77 | ii = find(freqwf > opt.wp.xi1 / (2 * pi) & freqwf < opt.wp.xi2 / (2 * pi)); %take into account only frequencies within the wavelet support 78 | if ~isempty(opt.wp.fwt) 79 | fw = conj(opt.wp.fwt(2 * pi * freqwf(ii))); 80 | nid = find(isnan(fw) | ~isfinite(fw)); 81 | if ~isempty(nid) %to avoid NaNs due to numerics, e.g. sin(0)/0 82 | fw(nid) = conj(opt.wp.fwt(2 * pi * freqwf(ii(nid)) + 1e-14)); 83 | nid = isnan(fw) | ~isfinite(fw); fw(nid) = 0; 84 | end 85 | else 86 | twav = (1 / fs) * [-(1 : ceil((NL - 1) / 2)) + 1, NL + 1 -(ceil((NL - 1) / 2) + 1 : NL)]'; 87 | timewf = (2 * pi * fr / opt.wp.ompeak) * twav; 88 | jj = find(timewf > opt.wp.t1 & timewf < opt.wp.t2); 89 | tw = zeros(NL, 1); %take into account only times within the wavelet support 90 | tw(jj) = conj(opt.wp.twf(timewf(jj))); 91 | nid = find(isnan(tw) | ~isfinite(tw)); 92 | if ~isempty(nid) %to avoid NaNs due to numerics, e.g. sin(0)/0 93 | tw(nid) = conj(opt.wp.twf(timewf(nid) + 1e-14)); 94 | nid = isnan(tw) | ~isfinite(tw); tw(nid) = 0; 95 | end 96 | fw = (1 / fs) * fft(tw); fw = fw(ii); 97 | end 98 | cc = zeros(NL, 1); cc(ii) = fx(ii) .* fw(:); %convolution in the frequency domain 99 | out = ((opt.wp.ompeak / (2 * pi * fr))^(1-p)) * ifft(cc, NL); % calculate WT at each time 100 | wt(1 : L) = out(1 + n1 : NL - n2); 101 | 102 | if strcmpi(opt.CutEdges,'on') 103 | wt(1 : coib1) = nan; 104 | wt(end - coib2 : end) = nan; 105 | end 106 | end 107 | 108 | function [newSig, fx, ff] = preprocess(sig, N, fs, fmin, fmax) 109 | % Detrending 110 | X = (1 : length(sig))' / fs; XM = ones(length(X), 4); 111 | for pn = 1 : 3 112 | CX = X .^ pn; 113 | XM(:, pn + 1) = (CX - mean(CX)) / std(CX); 114 | end 115 | w = warning('off', 'all'); sig = sig - XM * (pinv(XM) * sig); warning(w); 116 | 117 | % Filtering 118 | fx = fft(sig, N); % Fourier transform of a signal 119 | Nq = ceil((N + 1) / 2); 120 | ff = [(0 : Nq - 1), -fliplr(1 : N - Nq)] * fs / N; ff = ff(:); % frequencies in Fourier transform 121 | fx(abs(ff) <= max([fmin, fs / N]) | abs(ff) >= fmax) = 0; % filter signal in a chosen frequency domain 122 | newSig = ifft(fx); 123 | end 124 | -------------------------------------------------------------------------------- /allguis/guis/bispectrum/Functions/wtAtfMod.m: -------------------------------------------------------------------------------- 1 | 2 | function wt = wtAtfMod(sig, fs, fr, varargin) 3 | % author: Aleksandra Pidde, a.pidde@lancaster.ac.uk, aleksandra.pidde@gmail.com 4 | % date: 30.12.2017 5 | % update: 8.01.2018 6 | % 7 | % calculating wavelets at certain frequency 8 | % INPUT 9 | % sig: signal 10 | % fs: sampling frequency [Hz] 11 | % fr: frequency for which wavelets are calculated 12 | % varargin (optional): 13 | % 'f0': tradeoff between the time and frequency resolutions, the higher, the 14 | % better frequency resolution, the lower the better time resolution, 15 | % default 1 16 | % 'wavelet': type of wavelet, {'morlet', 'modMorlet'}, default 'morlet' 17 | % 'cutEdges': cutting of the cone of influence, {true, false}, default 18 | % true 19 | % 'd': Gaussian decay in Morlet wavelet, according to 20 | % correction, default 2 21 | % 'p': normalization factor (Kaiser, A friendly guide to wavelets, 22 | % params from eq 3.6), default 0.5 23 | % 24 | % OUTPUT 25 | % WT: wavelet transform 26 | % freq: frequency vector 27 | 28 | wavelet = 'morlet'; 29 | f0 = 1; 30 | cutEdges = true; 31 | d = 2; 32 | p = 0.5; 33 | if nargin >= 2 + 3 34 | for i = 1 : 2 : nargin - 3 35 | switch varargin{i} 36 | case 'wavelet' 37 | wavelet = varargin{i + 1}; 38 | case 'f0' 39 | f0 = varargin{i + 1}; 40 | case 'cutEdges' 41 | cutEdges = varargin{i + 1}; 42 | case 'd' 43 | d = varargin{i + 1}; 44 | case 'p' 45 | p = varargin{i + 1}; 46 | otherwise 47 | disp('problem with the agrument') 48 | end 49 | end 50 | end 51 | 52 | N = length(sig); sig = sig(:); 53 | sig = detrend(sig); 54 | T = N / fs; 55 | th = 0.001; % amplitude threshold for wavelet to be non-zero 56 | om0 = 2 * pi * f0; %just for convenience denote circular central frequency 57 | 58 | if strcmpi(wavelet, 'morlet') 59 | norm = @(om) (om0 / om)^(1-p); 60 | fwt = @(xi)(exp(-(1/2) * (om0-xi).^2) - exp(-(1/2) * (om0^2 + xi.^2))); 61 | len = @(om) 2 * (om0 / om) * sqrt(-2 * log(sqrt(2 * pi) * th)); 62 | elseif strcmpi(wavelet, 'modMorlet') 63 | % modified Morlet, eq. 19 from J. Jamsek, A. Stefanovska, and P. V. E. McClintock, PrE 76, 046221, 2007 64 | omMin = 2 * pi / T; omMax = pi * fs; 65 | a = @(om) 2.^(1.8 * (om - omMin) / (omMax - omMin)); 66 | c = 3.9487 * pi^(-0.25); 67 | % I try to find the length of Morlet wavelet... 68 | A = @(om) 1/sqrt(2 * pi) * a(om) * c; 69 | len = @(om) 2 * (om0 / om) * sqrt(-d * log(th / A(om))); 70 | norm = @(om) 1 / len(om) * (om0 ./ om); 71 | fwt = @(xi) a(xi) .* c * sqrt(d/2) .* (exp(-(d/4) * (om0-xi).^2) - exp(-om0^2 * d / 4 - xi.^2 / 2)); 72 | else 73 | error('Invalid wavelet name, Morlet or ModMorlet'); 74 | end 75 | 76 | % frequencies 77 | nq = ceil((N + 1) / 2); 78 | ff = [(0 : nq - 1), -fliplr(1 : N - nq)] * fs / N; 79 | ff = ff(:); 80 | 81 | fx = fft(sig, N); 82 | fx(ff <= 0) = 0; 83 | 84 | wt = zeros(1, N) * NaN; 85 | % wavelet transform 86 | n1 = 0; n2 = n1; 87 | if cutEdges 88 | n1 = floor(fs * 0.5 * len(2 * pi * fr)); 89 | n2 = n1; 90 | end 91 | if n1 + n2 < N 92 | freqswf = ff * om0 / (2 * pi * fr); % for the wavelet 93 | fw = conj(fwt(2 * pi * freqswf)); 94 | nanid = find(isnan(fw) | ~isfinite(fw)); 95 | if ~isempty(nanid) % to avoid NaNs due to numerics, e.g. sin(0)/0 96 | fw(nanid) = conj(fwt(2 * pi * freqswf(nanid) + 10^(-14))); 97 | nanid = isnan(fw) | ~isfinite(fw); fw(nanid) = 0; 98 | end 99 | conv = fx .* fw(:); % convolution in the frequency domain 100 | out = norm(2 * pi * fr) * ifft(conv, N); 101 | wt(1 + n1 : N - n2) = out(1 + n1 : N - n2); % calculate WT at each time 102 | end 103 | end 104 | -------------------------------------------------------------------------------- /allguis/guis/coherence/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /allguis/guis/coherence/.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /allguis/guis/coherence/CoherenceMulti.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/guis/coherence/CoherenceMulti.fig -------------------------------------------------------------------------------- /allguis/guis/coherence/Functions/tlphcoh.m: -------------------------------------------------------------------------------- 1 | %----------------Time-localized wavelet phase coherence-------------------- 2 | % TPC = tlphcoh(WT1,WT2,freq,fs,Optional:numcycles) 3 | % calculates time-localized wavelet phase coherence TPC. 4 | % 5 | % Input: 6 | % WT1,WT2 - wavelet transforms of two signals 7 | % freq - frequencies used in wavelet transform 8 | % fs - sampling frequency of a signals from which WT1, WT2 were calculated 9 | % numcycles - number of cycles for calculating TPC (determines adaptive 10 | % window length, i.e. at 0.1 Hz it will be (1/0.1)*numcycles 11 | % seconds); default=10. 12 | % 13 | % Author: Dmytro Iatsenko (http://www.physics.lancs.ac.uk/research/nbmphysics/diats) 14 | %-------------------------------------------------------------------------- 15 | 16 | 17 | function TPC = tlphcoh(TFR1,TFR2,freq,fs,varargin) 18 | 19 | [NF,L]=size(TFR1); 20 | if nargin>4, wsize=varargin{1}; else wsize=10; end 21 | 22 | IPC=exp(1i*angle(TFR1.*conj(TFR2))); 23 | ZPC=IPC; ZPC(isnan(ZPC))=0; cumPC=[zeros(NF,1),cumsum(ZPC,2)]; 24 | TPC=zeros(NF,L)*NaN; 25 | for fn=1:NF 26 | cs=IPC(fn,:); cumcs=cumPC(fn,:); 27 | tn1=find(~isnan(cs),1,'first'); tn2=find(~isnan(cs),1,'last'); 28 | 29 | window=round((wsize/freq(fn))*fs); window=window+1-mod(window,2); hw=floor(window/2); 30 | 31 | if ~isempty(tn1+tn2) && window<=tn2-tn1 32 | locpc=abs(cumcs(tn1+window:tn2+1)-cumcs(tn1:tn2-window+1))/window; 33 | TPC(fn,tn1+hw:tn2-hw)=locpc; 34 | end 35 | end 36 | 37 | end 38 | 39 | -------------------------------------------------------------------------------- /allguis/guis/coherence/Functions/wphcoh.m: -------------------------------------------------------------------------------- 1 | % [phcoh,Optional:phdiff] = wphcoh(WT1,WT2) 2 | % returns time-averaged wavelet phase coherence between two signals; 3 | % WT1 and WT2 are wavelet transforms of these signals. 4 | % 5 | % Author: Dmytro Iatsenko (http://www.physics.lancs.ac.uk/research/nbmphysics/diats) 6 | %-------------------------------------------------------------------------- 7 | 8 | function [phcoh,varargout] = wphcoh(WT1,WT2) 9 | 10 | FN=min([size(WT1,1),size(WT2,1)]); 11 | WT1=WT1(1:FN,:); WT2=WT2(1:FN,:); 12 | phi1=angle(WT1); phi2=angle(WT2); 13 | phexp=exp(1i*(phi1-phi2)); 14 | 15 | phcoh=zeros(1,FN)*NaN; phdiff=zeros(1,FN)*NaN; 16 | for fn=1:FN 17 | cphexp=phexp(fn,:); cphexp=cphexp(~isnan(cphexp)); 18 | NL=length(find(WT1(fn,:)==0 & WT2(fn,:)==0)); 19 | CL=length(cphexp); 20 | if CL>0 21 | phph=mean(cphexp)-NL/CL; 22 | phcoh(fn)=abs(phph); 23 | phdiff(fn)=angle(phph); 24 | end 25 | end 26 | 27 | if nargout>1, varargout{1}=phdiff; end 28 | 29 | end 30 | 31 | -------------------------------------------------------------------------------- /allguis/guis/filtering/Filtering.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/guis/filtering/Filtering.fig -------------------------------------------------------------------------------- /allguis/guis/filtering/Functions/Fourier.m: -------------------------------------------------------------------------------- 1 | function [Y, f] = Fourier(x, fs) 2 | 3 | Fs = fs; % Sampling frequency 4 | T = 1/Fs; % Sample time 5 | L = length(x); % Length of signal 6 | y=x; 7 | 8 | NFFT = length(x); % Next power of 2 from length of y 9 | Y = fft(y,NFFT)/L; 10 | Y=Y(1:NFFT/2+1); 11 | Y=2*(abs(Y).^2); 12 | f = Fs/2* linspace(0,1,NFFT/2+1); 13 | 14 | %Plot single-sided amplitude spectrum. 15 | % figure 16 | % semilogx(f,abs(Y),'color',[0 0 0]) 17 | % 18 | % xlabel('Frequency [Hz]') 19 | % ylabel('FT Power') 20 | 21 | end -------------------------------------------------------------------------------- /allguis/guis/filtering/Functions/MODAridge_filter.m: -------------------------------------------------------------------------------- 1 | function handles=MODAridge_filter(hObject,eventdata,handles) 2 | 3 | list=get(handles.interval_list,'String'); 4 | if isempty(list) 5 | errordlg('Interval list is empty. Please select frequency bands for filtering','Error'); 6 | return; 7 | end 8 | set(handles.transform,'Enable','off') 9 | set(handles.filter_signal,'Enable','off') 10 | set(handles.ridgecalc,'Enable','off') 11 | 12 | %% Set up waitbar 13 | handles.h = waitbar(0,'Filtering...',... 14 | 'CreateCancelBtn',... 15 | 'setappdata(gcbf,''canceling'',1)'); 16 | setappdata(handles.h,'canceling',0) 17 | guidata(hObject,handles); 18 | 19 | try 20 | list=get(handles.interval_list,'String'); 21 | 22 | extype=handles.etype; 23 | 24 | if extype==2 %% If Butterworth filter is selected 25 | for j=1:size(handles.sig_cut,1) 26 | for k=1:size(list,1) 27 | fl=csv_to_mvar(list{k,1}); 28 | [handles.bands{j,k},~] = loop_butter(handles.sig_cut(j,:),fl,handles.sampling_freq); 29 | handles.extract_phase{j,k}=angle(hilbert(handles.bands{j,k})); 30 | handles.extract_amp{j,k}=abs(hilbert(handles.bands{j,k})); 31 | end 32 | end 33 | elseif extype==1 %% If ridge extraction is selected 34 | % Window type 35 | wtypes=get(handles.wind_type,'String'); 36 | wselect=get(handles.wind_type,'Value'); 37 | wtype=wtypes{wselect}; 38 | 39 | % Preprocessing input 40 | x=get(handles.preprocess,'String'); ind=get(handles.preprocess,'Value'); ppselect=x{ind}; 41 | 42 | % Cut edges input 43 | x=get(handles.cutedges,'String'); ind=get(handles.cutedges,'Value'); cutselect=x{ind}; 44 | for j=1:size(handles.sig_cut,1) 45 | for k=1:size(list,1) 46 | fl=csv_to_mvar(list{k,1}); 47 | 48 | if(~isfield(handles, "fc")) 49 | msg = "An error has occurred. Please re-calculate the transform before proceeding."; 50 | errordlg(msg); 51 | error(msg); 52 | end 53 | 54 | if(isnan(handles.fc)) 55 | if handles.calc_type == 1 56 | [WT,freqarr,wopt]=wt(handles.sig_cut(j,:),handles.sampling_freq,'fmin',fl(1),'fmax',fl(2),'CutEdges','off',... 57 | 'Preprocess',ppselect,'Wavelet',wtype); 58 | else 59 | [WT,freqarr,wopt]=wft(handles.sig_cut(j,:),handles.sampling_freq,'fmin',fl(1),'fmax',fl(2),'CutEdges','off',... 60 | 'Preprocess',ppselect,'Window',wtype); 61 | end 62 | else 63 | if handles.calc_type == 1 64 | [WT,freqarr,wopt]=wt(handles.sig_cut(j,:),handles.sampling_freq,'fmin',fl(1),'fmax',fl(2),'CutEdges','off',... 65 | 'Preprocess',ppselect,'Wavelet',wtype,'f0',handles.fc); 66 | else 67 | [WT,freqarr,wopt]=wft(handles.sig_cut(j,:),handles.sampling_freq,'fmin',fl(1),'fmax',fl(2),'CutEdges','off',... 68 | 'Preprocess',ppselect,'Window',wtype,'f0',handles.fc); 69 | end 70 | end 71 | 72 | %Pre allocate for the cell structures 73 | tfsupp = ecurve(WT,freqarr,wopt); 74 | 75 | % This section relates to using "ridge" or "direct" reconstruction. 76 | % 77 | % Comments from Dymtro Iatsenko, paraphrased: 78 | % 79 | % [As far as I recall], the direct method for frequency is inferred directly from exact component reconstruction. 80 | % 81 | % Thus, in case of signal being a(t)cos(phi(t)) with slowly varying amplitude and frequency, 82 | % it will give exact amplitude, phase and frequency of this component, while the ridge method will not. 83 | % 84 | % Overall, the direct method is superior for signals where components are relatively clear; 85 | % however, with lots of noise and interferences the ridge method is more robust. 86 | 87 | % TO SWITCH FROM "direct" TO "ridge" RECONSTRUCTION, CHANGE 'direct' TO 'ridge' ON THE NEXT LINE. 88 | [handles.bands_iamp{j,k},handles.bands_iphi{j,k},handles.bands_freq{j,k}] = rectfr(tfsupp,WT,freqarr,wopt,'direct'); 89 | 90 | handles.recon{j,k} = handles.bands_iamp{j,k}.*cos(handles.bands_iphi{j,k}); 91 | handles.bands_iphi{j,k} = mod(handles.bands_iphi{j,k},2*pi); 92 | end 93 | 94 | waitbar(j/size(handles.sig_cut,1),handles.h) 95 | end 96 | 97 | % Check if negative frequencies are present in the results. 98 | shown_error = false; 99 | for i=1:size(handles.bands_freq, 1) 100 | for j=1:size(handles.bands_freq, 2) 101 | freq = handles.bands_freq{i,j}; 102 | 103 | negative = find(freq < 0); 104 | if ~isempty(negative) 105 | msg = "Error: Negative frequencies are present in the result. This is an artefact of the direct reconstruction algorithm." + ... 106 | newline + newline + ... 107 | "To address this issue, please try one or more of the following:" + newline + ... 108 | "1) Switching to the 'Lognorm' wavelet." + newline + ... 109 | "2) Using a narrower frequency interval." + newline + ... 110 | "3) Using a higher frequency resolution." + ... 111 | newline + newline + ... 112 | "For more information, please check the User Guide."; 113 | 114 | title = "Error"; 115 | see_docs = "Open User Guide"; 116 | dismiss = "Dismiss"; 117 | 118 | % Show question dialog. 119 | answer = questdlg(... 120 | msg, ... 121 | title, ... 122 | see_docs, ... 123 | dismiss, ... 124 | dismiss ... 125 | ); 126 | 127 | if answer == see_docs 128 | % Launch web browser with link to the relevant 129 | % section of the User Guide. 130 | web("https://github.com/luphysics/MODA/blob/master/docs/user-guide.md#negative-frequencies"); 131 | end 132 | 133 | shown_error = true; 134 | break; 135 | end 136 | end 137 | 138 | % If an error was shown, break the outer loop. 139 | if shown_error, break; end 140 | end 141 | 142 | else 143 | 144 | end 145 | set(handles.display_type,'Enable','on'); 146 | set(handles.display_type,'Value',2); 147 | delete(handles.h); 148 | drawnow; 149 | guidata(hObject,handles); 150 | 151 | set(handles.transform,'Enable','on') 152 | set(handles.filter_signal,'Enable','on') 153 | set(handles.ridgecalc,'Enable','on') 154 | 155 | set(handles.save_filtered_sig_plot,'Enable','on') 156 | set(handles.save_ridge_plot,'Enable','on') 157 | set(handles.save_phase_plot,'Enable','on') 158 | set(handles.All_filt_plot,'Enable','on') 159 | set(handles.save_csv,'Enable','on') 160 | set(handles.save_mat,'Enable','on') 161 | set(handles.save_session,'Enable','on') 162 | 163 | 164 | catch e 165 | errordlg(e.message,'Error') 166 | set(handles.transform,'Enable','on') 167 | set(handles.filter_signal,'Enable','on') 168 | set(handles.ridgecalc,'Enable','on') 169 | delete(handles.h) 170 | rethrow(e) 171 | 172 | end -------------------------------------------------------------------------------- /allguis/guis/filtering/Functions/bandpass_butter.m: -------------------------------------------------------------------------------- 1 | function [d] = bandpass_butter(c,or,flp,fhi,fs) 2 | % 3 | % [d]=bandpass(c,flp) 4 | % 5 | % bandpass a time series with a 2nd order butterworth filter 6 | % 7 | % c = input time series 8 | % or-order for the filter 9 | % flp = lowpass corner frequency of filter 10 | % fhi = hipass corner frequency 11 | % fs = sampling frequency 12 | % 13 | n=or; % 2nd order butterworth filter 14 | fnq=1/2*fs; % Nyquist frequency 15 | Wn=[flp/fnq fhi/fnq]; % butterworth bandpass non-dimensional frequency 16 | [b,a]=butter(n,Wn); % construct the filter 17 | d=filtfilt(b,a,c); % zero phase filter the data 18 | return; -------------------------------------------------------------------------------- /allguis/guis/filtering/Functions/loop_butter.m: -------------------------------------------------------------------------------- 1 | %function looping butterworth filter till reaching the maximum order 2 | % author: Valentina Ticcinelli 3 | %output: 4 | %s_out= filtered signal 5 | %or= optimal order 6 | 7 | %input: 8 | %s_in= signal to be filtered 9 | %band=[f_min f_max] passing band 10 | %fs= sample frequency 11 | 12 | function [s_out,or]=loop_butter(s_in,band,fs) 13 | 14 | or=1; 15 | s_out=bandpass_butter(s_in,or,band(1),band(2), fs); 16 | 17 | max_out=max(abs(s_out)); 18 | 19 | while max(abs(s_out))<10*max_out 20 | or=or+1; 21 | s_out=bandpass_butter(s_in,or,band(1),band(2), fs); 22 | end 23 | or=or-2; 24 | 25 | if or<1 26 | or=1; 27 | else 28 | end 29 | s_out=bandpass_butter(s_in,or,band(1),band(2), fs); 30 | 31 | 32 | function [d]=bandpass_butter(c,n,flp,fhi,fs) 33 | 34 | % [d]=bandpass(c,flp) 35 | % 36 | % bandpass a time series with a nth order butterworth filter 37 | % 38 | % c = input time series 39 | % n= order for the filter 40 | % flp = lowpass corner frequency of filter 41 | % fhi = hipass corner frequency 42 | % fs = sampling frequency 43 | 44 | 45 | fnq=1/2*fs; % Nyquist frequency 46 | Wn=[flp/fnq fhi/fnq]; % butterworth bandpass non-dimensional frequency 47 | [b,a]=butter(n,Wn); % construct the filter 48 | d=filtfilt(b,a,c); % zero phase filter the data 49 | 50 | 51 | -------------------------------------------------------------------------------- /allguis/guis/filtering/Functions/ridge_extraction.m: -------------------------------------------------------------------------------- 1 | function [transform, freq, iamp, iphi, ifreq, recon] = ridge_extraction(calc_type, signal, fs, interval1, interval2, cut_edges, preprocess, w_type) 2 | 3 | 4 | if calc_type == 1 5 | [WT,freqarr,wopt]=wt(signal,fs,'fmin',interval1,'fmax',interval2,'CutEdges','off',... 6 | 'Preprocess',preprocess,'Wavelet',w_type); 7 | else 8 | [WT,freqarr,wopt]=wft(signal,fs,'fmin',interval1,'fmax',interval2,'CutEdges','off',... 9 | 'Preprocess',preprocess,'Window',w_type); 10 | end 11 | 12 | tfsupp = ecurve(WT,freqarr,wopt); 13 | 14 | [iamp,iphi,ifreq] = rectfr(tfsupp,WT,freqarr,wopt,'direct'); 15 | 16 | recon = iamp.*cos(iphi); 17 | iphi = mod(iphi,2*pi); 18 | 19 | transform = WT; 20 | freq = freqarr; 21 | 22 | 23 | -------------------------------------------------------------------------------- /allguis/guis/tfa/Functions/testwt.m: -------------------------------------------------------------------------------- 1 | fs = 20; 2 | t = 0:1/fs:50-1/fs; 3 | 4 | signal = cos(2*pi*3*t + .75 * sin(2*pi*t/5)); 5 | 6 | result = wt(signal, fs); -------------------------------------------------------------------------------- /allguis/guis/tfa/Functions/wtwrapper.m: -------------------------------------------------------------------------------- 1 | 2 | fs=handles.sampling_freq; 3 | fc=handles.fc; 4 | if(isnan(fmax)&& isnan(fmin)) 5 | if(isnan(fc)) 6 | if handles.calc_type == 1 7 | [WT,handles.freqarr,handles.wopt]=wt(handles.sig_cut(p,:),fs,'CutEdges',cutselect,... 8 | 'Preprocess',ppselect,'Wavelet',wtype,'Padding',0); 9 | else 10 | [WT,handles.freqarr,handles.wopt]=wft(handles.sig_cut(p,:),fs,'CutEdges',cutselect,... 11 | 'Preprocess',ppselect,'Window',wtype,'Padding',0); 12 | end 13 | else 14 | if handles.calc_type == 1 15 | [WT,handles.freqarr,handles.wopt]=wt(handles.sig_cut(p,:),fs,'CutEdges',cutselect,... 16 | 'Preprocess',ppselect,'Wavelet',wtype,'f0',fc,'Padding',0); 17 | else 18 | [WT,handles.freqarr,handles.wopt]=wft(handles.sig_cut(p,:),fs,'CutEdges',cutselect,... 19 | 'Preprocess',ppselect,'Window',wtype,'f0',fc,'Padding',0); 20 | end 21 | end 22 | elseif(isnan(fmax)) 23 | if(isnan(fc)) 24 | if handles.calc_type == 1 25 | [WT,handles.freqarr,handles.wopt]=wt(handles.sig_cut(p,:),fs,'fmin',fmin,'CutEdges',cutselect,... 26 | 'Preprocess',ppselect,'Wavelet',wtype,'Padding',0); 27 | else 28 | [WT,handles.freqarr,handles.wopt]=wft(handles.sig_cut(p,:),fs,'fmin',fmin,'CutEdges',cutselect,... 29 | 'Preprocess',ppselect,'Window',wtype,'Padding',0); 30 | end 31 | else 32 | if handles.calc_type == 1 33 | [WT,handles.freqarr,handles.wopt]=wt(handles.sig_cut(p,:),fs,'fmin',fmin,'CutEdges',cutselect,... 34 | 'Preprocess',ppselect,'Wavelet',wtype,'f0',fc,'Padding',0); 35 | else 36 | [WT,handles.freqarr,handles.wopt]=wft(handles.sig_cut(p,:),fs,'fmin',fmin,'CutEdges',cutselect,... 37 | 'Preprocess',ppselect,'Window',wtype,'f0',fc,'Padding',0); 38 | end 39 | end 40 | elseif(isnan(fmin)) 41 | if(isnan(fc)) 42 | if handles.calc_type == 1 43 | [WT,handles.freqarr,handles.wopt]=wt(handles.sig_cut(p,:),fs,'fmax',fmax,'CutEdges',cutselect,... 44 | 'Preprocess',ppselect,'Wavelet',wtype,'Padding',0); 45 | else 46 | [WT,handles.freqarr,handles.wopt]=wft(handles.sig_cut(p,:),fs,'fmax',fmax,'CutEdges',cutselect,... 47 | 'Preprocess',ppselect,'Window',wtype,'Padding',0); 48 | end 49 | else 50 | if handles.calc_type == 1 51 | [WT,handles.freqarr,handles.wopt]=wt(handles.sig_cut(p,:),fs,'fmax',fmax,'CutEdges',cutselect,... 52 | 'Preprocess',ppselect,'Wavelet',wtype,'f0',fc,'Padding',0); 53 | else 54 | [WT,handles.freqarr,handles.wopt]=wft(handles.sig_cut(p,:),fs,'fmax',fmax,'CutEdges',cutselect,... 55 | 'Preprocess',ppselect,'Window',wtype,'f0',fc,'Padding',0); 56 | end 57 | end 58 | else 59 | if(isnan(fc)) 60 | if handles.calc_type == 1 61 | [WT,handles.freqarr,handles.wopt]=wt(handles.sig_cut(p,:),fs,'fmin',fmin,'fmax',fmax,'CutEdges',cutselect,... 62 | 'Preprocess',ppselect,'Wavelet',wtype,'Padding',0); 63 | else 64 | [WT,handles.freqarr,handles.wopt]=wft(handles.sig_cut(p,:),fs,'fmin',fmin,'fmax',fmax,'CutEdges',cutselect,... 65 | 'Preprocess',ppselect,'Window',wtype,'Padding',0); 66 | end 67 | else 68 | if handles.calc_type == 1 69 | [WT,handles.freqarr,handles.wopt]=wt(handles.sig_cut(p,:),fs,'fmin',fmin,'fmax',fmax,'CutEdges',cutselect,... 70 | 'Preprocess',ppselect,'Wavelet',wtype,'f0',fc,'Padding',0); 71 | else 72 | [WT,handles.freqarr,handles.wopt]=wft(handles.sig_cut(p,:),fs,'fmin',fmin,'fmax',fmax,'CutEdges',cutselect,... 73 | 'Preprocess',ppselect,'Window',wtype,'f0',fc,'Padding',0); 74 | end 75 | end 76 | end -------------------------------------------------------------------------------- /allguis/guis/tfa/TimeFrequencyAnalysis.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/guis/tfa/TimeFrequencyAnalysis.fig -------------------------------------------------------------------------------- /allguis/guis/tfa/TimeFrequencyAnalysis_temp.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/guis/tfa/TimeFrequencyAnalysis_temp.fig -------------------------------------------------------------------------------- /allguis/images/MODAbanner3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 30 | 34 | 35 | 45 | 49 | 50 | 53 | 60 | 61 | 71 | 75 | 76 | 79 | 86 | 87 | 90 | 97 | 98 | 99 | 124 | 126 | 127 | 129 | image/svg+xml 130 | 132 | 133 | 134 | 135 | 136 | 141 | 148 | 151 | 155 | 162 | 167 | 175 | 184 | 193 | 202 | 203 | 204 | MODA v1.0 Nonlinear and Biomedical Physics Group 235 | 236 | -------------------------------------------------------------------------------- /allguis/images/MODAbanner4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/MODAbanner4.pdf -------------------------------------------------------------------------------- /allguis/images/MODAbanner4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/MODAbanner4.png -------------------------------------------------------------------------------- /allguis/images/MODAbanner4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 30 | 34 | 35 | 45 | 49 | 50 | 53 | 60 | 61 | 71 | 75 | 76 | 79 | 86 | 87 | 90 | 97 | 98 | 99 | 124 | 126 | 127 | 129 | image/svg+xml 130 | 132 | 133 | 134 | 135 | 136 | 141 | 148 | 151 | 155 | 162 | 167 | 175 | 184 | 193 | 202 | 203 | 204 | MODA v1.01 Nonlinear and Biomedical Physics Group 235 | 236 | -------------------------------------------------------------------------------- /allguis/images/MODAbanner5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/MODAbanner5.pdf -------------------------------------------------------------------------------- /allguis/images/MODAbanner5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/MODAbanner5.png -------------------------------------------------------------------------------- /allguis/images/frontbanner.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/frontbanner.pdf -------------------------------------------------------------------------------- /allguis/images/frontbanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/frontbanner.png -------------------------------------------------------------------------------- /allguis/images/logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/logo.pdf -------------------------------------------------------------------------------- /allguis/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/logo.png -------------------------------------------------------------------------------- /allguis/images/logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/logo2.png -------------------------------------------------------------------------------- /allguis/images/physicslogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/physicslogo.png -------------------------------------------------------------------------------- /allguis/images/physicslogoBW.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/physicslogoBW.png -------------------------------------------------------------------------------- /allguis/images/splashscreen.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/splashscreen.pdf -------------------------------------------------------------------------------- /allguis/images/splashscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/allguis/images/splashscreen.png -------------------------------------------------------------------------------- /docs/developer-guide.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Table of Contents 4 | 5 | - [Developer Guide](#developer-guide) 6 | - [Additional requirements](#additional-requirements) 7 | - [Downloading MODA](#downloading-moda) 8 | - [Installing Git hooks](#installing-git-hooks) 9 | 10 | 11 | 12 | # Developer Guide 13 | 14 | This guide is aimed at developers wishing to modify or contribute to the program. 15 | 16 | ## Additional requirements 17 | 18 | In addition to the [requirements](/README.md#requirements) listed in the User Guide, you'll also need to [install Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). 19 | 20 | ## Downloading MODA 21 | 22 | - Open a terminal in a desired folder and run `git clone https://github.com/luphysics/MODA.git`. 23 | - The code will download as a folder named `MODA`. 24 | 25 | ## Installing Git hooks 26 | 27 | Git hooks are used to automatically perform tasks when a commit is made. MODA uses `doctoc` to add the table of contents to markdown files. 28 | 29 | Commit your current work, if there are changes. Then open a terminal in the `MODA` folder and run: 30 | 31 | ``` 32 | pip install pre-commit --user # Installs the pre-commit tool. 33 | python -m pre-commit install # Adds the Git hooks to the repository. 34 | ``` 35 | 36 | On Windows, also run `git config core.safecrlf false` in the `MODA` folder. This prevents a circular problem where Git cannot commit because it converts line endings to CRLF but `doctoc` converts line endings back to LF. 37 | 38 | Now that the Git hooks are installed, they will automatically run every time a commit changes relevant files. 39 | 40 | > :warning: When a pre-commit hook changes files, you'll need to add files and commit again. -------------------------------------------------------------------------------- /docs/images/change_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/docs/images/change_folder.png -------------------------------------------------------------------------------- /docs/images/data_orientation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/docs/images/data_orientation.png -------------------------------------------------------------------------------- /docs/images/launcher_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/docs/images/launcher_window.png -------------------------------------------------------------------------------- /docs/images/sampling_frequency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/docs/images/sampling_frequency.png -------------------------------------------------------------------------------- /docs/images/timefrequency_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/docs/images/timefrequency_empty.png -------------------------------------------------------------------------------- /docs/images/xlim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/docs/images/xlim.png -------------------------------------------------------------------------------- /docs/images/zoom_signal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/docs/images/zoom_signal.png -------------------------------------------------------------------------------- /docs/user-guide.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Table of Contents 4 | 5 | - [User Guide](#user-guide) 6 | - [Requirements](#requirements) 7 | - [Downloading MODA](#downloading-moda) 8 | - [Running MODA](#running-moda) 9 | - [Importing time-series](#importing-time-series) 10 | - [Example - Time-Frequency Analysis](#example---time-frequency-analysis) 11 | - [Truncating signals](#truncating-signals) 12 | - [Plotting and saving](#plotting-and-saving) 13 | - [Large arrays and downsampling](#large-arrays-and-downsampling) 14 | 15 | 16 | 17 | # User Guide 18 | 19 | This guide is aimed at users wishing to set up and use MODA. The [User Manual](/User%20Manual.pdf) provides a more in-depth explanation of MODA's functionality. 20 | 21 | If you're interested in modifying or contributing to the program, you may find the [Developer Guide](/docs/developer-guide.md) useful. 22 | 23 | ## Requirements 24 | 25 | MATLAB R2017a or higher is required, but newer versions are recommended. 26 | 27 | The following MATLAB toolboxes are needed: 28 | - Signal Processing Toolbox 29 | - Statistics and Machine Learning Toolbox 30 | - Wavelet Toolbox 31 | 32 | You can check which toolboxes are currently installed by running the `ver` command in the MATLAB Command Window. 33 | 34 | ## Downloading MODA 35 | 36 | - [Click here](https://github.com/luphysics/MODA/zipball/master) to download the code as a .zip file. 37 | - Extract the zip file to a desired location. 38 | - For simplicity of instructions, rename the folder to `MODA`. 39 | 40 | ## Running MODA 41 | 42 | In your file explorer, double-click `MODA.m` inside the `MODA` folder to open it with MATLAB. After the MATLAB window opens, press `F5` or click the "Run" button to start MODA. 43 | 44 | > **Note:** You may need to click inside the section displaying the contents of `MODA.m` for the "Run" button to appear. 45 | 46 | If the following dialog appears, click "Change Folder": 47 | 48 | ![Screenshot of the dialog stating that MODA.m is not in the current MATLAB path.](/docs/images/change_folder.png) 49 | 50 | The launcher window will then open: 51 | 52 | ![Screenshot of MODA's launcher window.](/docs/images/launcher_window.png) 53 | 54 | ## Importing time-series 55 | 56 | In MODA, a time-series is a series of recorded values, where the sampling frequency - the frequency at which the recordings were made - is known. 57 | 58 | MODA can analyse multiple signals, provided that all signals have the same duration and sampling frequency. 59 | 60 | To import time-series into MODA, they must be saved in a compatible format: 61 | 62 | - The file type must be a `.mat` file or `.csv` file. 63 | - The file must contain a **single array, whose entries are all a single real number**. Each row or column of the array corresponds to a different time-series. 64 | - For windows which inspect pairs of signals (for example, dynamical Bayesian inference), the number of time-series should be even. *If there are an odd number of time-series, the last one will be removed and pairs will be formed from the remaining time-series.* 65 | - For wavelet bispectrum analysis, there must be only two time-series; this is because the bispectrum computations take a prohibitively long time. 66 | 67 | > **Note:** The sampling frequency is entered in the user interface, rather than specified in the file. 68 | 69 | **If the array loaded into MODA is extremely large, it may run slowly or crash.** A potential way to overcome this is to downsample the signals. 70 | 71 | ## Example - Time-Frequency Analysis 72 | 73 | When MODA opens, try clicking "Time-Frequency Analysis". After the window opens, go to `File` -> `Load time series` in the top left of the window. Using the file browser dialog, select a `.csv` or `.mat` file. 74 | 75 | > **Tip:** There are some example signals in the `example_sigs` folder. Try `example_sigs/6signals_10Hz.mat` (a row-wise signal). 76 | 77 | After the file is selected, a dialog will appear: 78 | 79 | ![Screenshot of the sampling frequency dialog.](/docs/images/sampling_frequency.png) 80 | 81 | After entering the sampling frequency in Hz (for example, "10"), another dialog will appear: 82 | 83 | ![Screenshot of the data orientation dialog.](/docs/images/data_orientation.png) 84 | 85 | This dialog asks whether the orientation of the data is row-wise or column-wise. 86 | 87 | --- 88 | 89 | #### Row-wise data 90 | 91 | With row-wise data, **each row contains one signal**. 92 | 93 | ``` 94 | | Signal 1, Value 1 | Signal 1, Value 2 | Signal 1, Value 3 | 95 | | Signal 2, Value 1 | Signal 2, Value 2 | Signal 2, Value 3 | 96 | | Signal 3, Value 1 | Signal 3, Value 2 | Signal 3, Value 3 | 97 | | Signal 4, Value 1 | Signal 4, Value 2 | Signal 4, Value 3 | 98 | ``` 99 | 100 | #### Column-wise data 101 | 102 | With column-wise data, **each column contains one signal**. 103 | 104 | ``` 105 | | Signal 1, Value 1 | Signal 2, Value 1 | Signal 3, Value 1 | 106 | | Signal 1, Value 2 | Signal 2, Value 2 | Signal 3, Value 2 | 107 | | Signal 1, Value 3 | Signal 2, Value 3 | Signal 3, Value 3 | 108 | | Signal 1, Value 4 | Signal 2, Value 4 | Signal 3, Value 4 | 109 | ``` 110 | 111 | --- 112 | 113 | After selecting the orientation, the data will be loaded and the first signal will be plotted at the top of the window. 114 | 115 | > **Note:** If the wrong orientation is selected, MODA may freeze because it interprets the data as a very large number of short signals. 116 | 117 | ![Screenshot of the time-frequency window after data is loaded.](/docs/images/timefrequency_empty.png) 118 | 119 | The imported signals are listed in the "Select data" section which, in the screenshot, is outlined in red. If the window's functionality demands that signals are processed as pairs, then each item in the list will represent a particular signal pair. 120 | 121 | When a signal or signal pair is selected, it (and its associated results, if any have been calculated) will be plotted. 122 | 123 | ## Truncating signals 124 | 125 | You may wish to **analyse only a portion of the recorded signal(s).** When the signals have been imported, you can do this by zoom-in magnifying glass and then using a click-and-drag action on the signal plot, to zoom to a rectangular region. 126 | 127 | ![Screenshot demonstrating the click-and-drag action to zoom to a region.](/docs/images/zoom_signal.png) 128 | 129 | > **Tip:** When selecting a portion of the signal, the signal will zoom to the horizontal boundaries of the selection; the vertical zoom will be reset. 130 | 131 | Alternatively, it is possible to set the by entering values in the "Xlim" field and clicking the "Refresh" button. 132 | 133 | ![Screenshot demonstrating the "Xlim" field.](/docs/images/xlim.png) 134 | 135 | After the signal has been truncated, the plot of the main results will not change until the calculations are repeated. 136 | 137 | > **Note:** For results involving frequency or time-frequency analysis, **the minumum frequency for which results can be displayed** increases as the signal is truncated. 138 | 139 | ## Plotting and saving 140 | 141 | **To save one of the graphs currently displayed** in the window, click `Plot` in the toolbar (to the right of `File`) and then select the appropriate option; this will open the plot in a new window as a MATLAB figure. 142 | 143 | This has some benefits: 144 | 145 | - The figure can be saved in a variety of formats. 146 | - All of MATLAB's features for analysing and manipulating a figure are available. 147 | - It will not be overwritten with the results of a new calculation. 148 | 149 | When saving figures, the following formats are recommended: 150 | 151 | - For a plot displaying a function of a single variable, a vector image format such as `.svg`, `.pdf` or `.eps`. 152 | - For a plot displaying a function of two variables, a scalar image format such as `.png`. 153 | 154 | ### Saving the current session 155 | 156 | To save the current session, click `Save`->`Save session` in the toolbar. This will save the current session as a `.mat` file, allowing you to return to it later by using `File`->`Load previous session`. 157 | 158 | ### Saving data 159 | 160 | Many of the actual values displayed in the plots can be saved as files by clicking `Save`->`Save as .mat` or `Save`->`Save as .csv` in the toolbar. 161 | 162 | `.mat` files can be loaded and interpreted in MATLAB or Python; `.csv` files are useful for Microsoft Excel. 163 | 164 | > :warning: When saving as a .csv file, avoid changing the file extension in the filename, or changing the file type in the "Save as type" dropdown. 165 | 166 | Some numerical values will be saved as NaN ("not a number"), which represents that a value has not been computed. In time-frequency analysis, meaningful results cannot be found very close to the start/end of the signal; if "cut edges" is enabled, these values will be saved as NaN. 167 | 168 | > :warning: When saving data from Ridge Extraction & Filtering for the purpose of loading into Dynamical Bayesian Inference, results must be saved as a `.mat` file. 169 | 170 | > **Note:** Files created by MODA are often very large; files may not save immediately, and opening a partially saved file could corrupt it. 171 | 172 | ## Large arrays and downsampling 173 | 174 | If an extremely large array is loaded into MODA, it could run very slowly or crash. 175 | 176 | Arrays may be overly large for the following reasons: 177 | 178 | 1. The number of signals stored is large. 179 | 2. The signals were measured over a very long time. 180 | 3. The signals were measured with a very high sampling frequency. 181 | 182 | Issue (1) can be solved by splitting up the array into multiple files, each containing fewer signals, and analysing each file individually. 183 | 184 | Issue (2) can be solved by splitting up the time interval over which the signals were measured into smaller intervals (preferably with a small overlap, since time-frequency analysis cannot be performed too close to the start/end of a signal), saving as smaller arrays, and analysing each array. 185 | 186 | If the sampling frequency is many times higher (e.g. ~10 times higher) than the largest potential frequency of interest within the signals, issue (3) can be addressed by **downsampling**. -------------------------------------------------------------------------------- /example_sigs/1signal_10Hz.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/1signal_10Hz.mat -------------------------------------------------------------------------------- /example_sigs/2signals_10Hz.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/2signals_10Hz.mat -------------------------------------------------------------------------------- /example_sigs/6signals_10Hz.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/6signals_10Hz.mat -------------------------------------------------------------------------------- /example_sigs/IEEEsigs/IEEEex_10Hz.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/IEEEsigs/IEEEex_10Hz.mat -------------------------------------------------------------------------------- /example_sigs/IEEEsigs/xp_100Hz.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/IEEEsigs/xp_100Hz.mat -------------------------------------------------------------------------------- /example_sigs/IEEEsigs/xp_10Hz.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/IEEEsigs/xp_10Hz.mat -------------------------------------------------------------------------------- /example_sigs/signals/X_0.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/X_0.mat -------------------------------------------------------------------------------- /example_sigs/signals/X_05.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/X_05.mat -------------------------------------------------------------------------------- /example_sigs/signals/X_12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/X_12.mat -------------------------------------------------------------------------------- /example_sigs/signals/fm_square_200Hz.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/fm_square_200Hz.mat -------------------------------------------------------------------------------- /example_sigs/signals/freq_mod_200Hz.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/freq_mod_200Hz.mat -------------------------------------------------------------------------------- /example_sigs/signals/load_first.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/load_first.mat -------------------------------------------------------------------------------- /example_sigs/signals/load_second.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/load_second.mat -------------------------------------------------------------------------------- /example_sigs/signals/noisy.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/noisy.mat -------------------------------------------------------------------------------- /example_sigs/signals/noisySIN.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/noisySIN.mat -------------------------------------------------------------------------------- /example_sigs/signals/noisyyy.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/signals/noisyyy.mat -------------------------------------------------------------------------------- /example_sigs/x.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luphysics/MODA/400ae6b8ea8310a24bce02558e3bb242f27bf558/example_sigs/x.mat -------------------------------------------------------------------------------- /scripts/fontsize.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python script which modifies the font sizes of all MODA's plots directly in the code. 3 | 4 | This is the origin of these lines of code in MODA source files: 5 | globalfontsize = 12; % Do not edit this line manually. See scripts/fontsize.py. 6 | 7 | To modify the font sizes in MODA to a new value X, open a terinal in the MODA folder and run: 8 | python scripts/fontsize.py X 9 | 10 | For example, for a font size of 12: 11 | python scripts/fontsize.py 12 12 | 13 | Note: On macOS/Linux you may need to use `python3` instead of `python`. 14 | """ 15 | 16 | import os 17 | from os import path 18 | from pathlib import Path 19 | import sys 20 | from typing import List 21 | 22 | assert sys.version_info >= (3, 6), "Please run with Python 3.6 or above." 23 | 24 | args = sys.argv[1:] 25 | if not args: 26 | print("ERROR: Font size must be supplied as an argument. For example, run 'python fontsize.py 12' for a font size of 12.") 27 | sys.exit(1) 28 | 29 | # Set working directory to MODA folder. 30 | here = path.abspath(path.dirname(__file__)) 31 | os.chdir(Path(here).parent) 32 | 33 | gfs = "globalfontsize" 34 | comment = "Do not edit this line manually. See scripts/fontsize.py." 35 | 36 | 37 | def readlines(filename: str) -> List[str]: 38 | with open(filename, "r") as f: 39 | lines = f.readlines() 40 | 41 | return lines 42 | 43 | 44 | def mutate_lines(filename: str, lines: List[str]) -> List[str]: 45 | lines = lines.copy() 46 | for index, item in enumerate(lines.copy()): 47 | if item.strip().startswith(gfs): 48 | indent = get_indentation(lines[index + 1 :]) 49 | new = f"{indent}{gfs} = {fontsize}; % {comment}\n" 50 | 51 | lines[index] = new 52 | print(f"{filename}: editing line {index+1}.") 53 | 54 | return lines 55 | 56 | 57 | def get_indentation(lines: List[str]) -> str: 58 | for l in lines: 59 | if l.strip(): 60 | return " " * (len(l) - len(l.lstrip())) 61 | return "" 62 | 63 | 64 | def write_lines(filename: str, lines: List[str]) -> None: 65 | with open(filename, "w") as f: 66 | f.writelines(lines) 67 | 68 | 69 | if __name__ == "__main__": 70 | fontsize = int(args[0]) 71 | 72 | for filepath in Path(".").rglob("*.m"): 73 | filename = filepath.absolute() 74 | 75 | lines = readlines(filename) 76 | mutated = mutate_lines(path.split(filename)[1], lines) 77 | 78 | if lines != mutated: 79 | write_lines(filename, mutated) 80 | 81 | print(f"Fonts updated to size {fontsize}.") 82 | --------------------------------------------------------------------------------