Browse Source

파일 업로드 ''

Hio-Been Han 8 months ago
parent
commit
74dc6e7a43

+ 26 - 0
subfunc/clean_coordinates.m

@@ -0,0 +1,26 @@
+function xy_clean = clean_coordinates(xy, sigma)
+if nargin ==1, sigma = 2.56; end
+xy_clean = xy;
+nan_list = isnan(xy);
+speed = [0, mean(abs(diff(xy(1,:))) + abs(diff(xy(2,:))))];
+speed_threshold = mean(speed, 'omitnan')+sigma*std(speed, 'omitnan');
+outliers = find(speed>speed_threshold);
+
+% interpolate empty spots
+xy_clean(:,outliers-1) = nan;
+xy_clean(:,outliers) = nan;
+xy_clean(:,outliers+1) = nan;
+
+% interpolate empty spots
+xy_clean(1,:) = interp_nan(xy_clean(1,:));
+xy_clean(2,:) = interp_nan(xy_clean(2,:));
+end
+
+%% subfunction
+function y = interp_nan(x)
+nanx = isnan(x);
+t   = 1:numel(x);
+y = x;
+y(nanx) = interp1(t(~nanx), x(~nanx), t(nanx));
+end
+

BIN
subfunc/cmap.mat


+ 35 - 0
subfunc/deleteOutliers.m

@@ -0,0 +1,35 @@
+
+function [ dat_clean, nOutliers, idx ] = deleteOutliers( dat, sdCrit )
+% function dat = _deleteOutliers(dat, sdCrit)
+% this function returns data vector without outliers.
+% It automatically detect outliers by applying M+SD or M-SD threshold,
+% making outliers with NaN data format. 
+
+if nargin < 2
+    sdCrit = 3;
+end
+
+l = length(dat);
+m = nanmean( dat );
+sd = nanstd( dat );
+dat_clean = dat;
+
+[ idx_upper ] = find( dat > m+ sd*sdCrit );
+[ idx_lower ] = find( dat < m- sd*sdCrit );
+
+idx = [ idx_lower; idx_upper ]';
+if min(size(idx)) > 1 % Matrix orientation
+    idx = [idx_lower, idx_upper ];
+end
+
+nOutliers = length(idx);
+% disp([ 'hb_deleteOutliers.m >> Outlier N : ' num2str(nOutliers) ...
+%     ' out of ' num2str( l )...
+%     ' (' num2str( nOutliers/l*100 ) ' %) ']);
+
+if nOutliers > 0
+    for oIdx = idx
+        dat_clean(oIdx) = nan;
+    end
+end
+

+ 85 - 0
subfunc/get_spectrogram.m

@@ -0,0 +1,85 @@
+function [spec_d, spec_t, spec_f] = get_spectrogram( x, t, win_size, t_resolution )
+% Usage: [spec_d, spec_t, spec_f] = get_spectrogram( x, t, win_size, t_resolution )
+% 
+% Calculating amplitude spectrogram from signal x and time-vector t. 
+% 
+% -- input form --
+% x: Raw EEG signal (1-D vector)
+% y: Time vector (in millisecond resolution)
+% win_size: Size of sliding moving window (default: 2^10)
+% t_resolution: Jump size of sliding moving window (unit: sec, default: 100 msec)
+% 
+% 2019-09-10
+% 
+
+%% Default condition
+if nargin < 5
+    t_resolution = .1;
+end; if nargin < 4
+    win_size = 2^10;
+end
+
+srate = round( 1/nanmean(diff(t)) );
+t_fft = [t(1)+(((win_size*.5)+1)/srate), t(end)-(((win_size*.5)+1)/srate)];
+t_vec = linspace( t_fft(1), t_fft(end), (diff(t_fft)/t_resolution) +1);
+
+%% Sliding window index bank
+idx_collection = single([]);
+for tIdx = [1, length(t_vec)]
+    idx_collection(tIdx,:) = ...
+        [max(find( t<(t_vec(tIdx)))) - win_size*.5,...
+        (max(find( t<(t_vec(tIdx)))) + win_size*.5-1) ];
+end
+idx_collection(:,1) = linspace( idx_collection(1,1), idx_collection(end,1), length(t_vec) );
+idx_collection(:,2) = linspace( idx_collection(1,2), idx_collection(end,2), length(t_vec) );
+idx_collection = round(idx_collection);
+
+short = find( ~[diff(idx_collection')' == (win_size-1)]);
+idx_collection(short,2) = idx_collection(short,2)+1;
+try hann = hanning( idx_collection(1,2)-idx_collection(1,1)+1 )';
+catch hann = ones([1, win_size]); end
+ 
+%%
+spec_d = [];
+spec_t = [];
+for tIdx = 1:length(t_vec)
+    % (1) Indexing
+%     idx = max(find( t<(t_vec(tIdx)))) - win_size*.5 :...
+%         max(find( t<(t_vec(tIdx))))   + win_size*.5 -1 ;
+%     actual_t = t(idx);
+%     if tIdx==1, han=hanning(length(idx))'; end
+
+    idx_list = idx_collection(tIdx,1):idx_collection(tIdx,2);
+    d = hann .* x(idx_list(1:length(hann))); % to prevent 1-2 point mismatch
+
+    [fft_d,spec_f]= fft_half(d, srate);
+    spec_d( size(spec_d,1)+1 , :) = fft_d;
+    spec_t( length(spec_t)+1 ) = mean(t(idx_list(1:length(hann))));
+end
+spec_d = abs(spec_d);
+
+end
+
+%% Subfunctions
+function [s,f]=fft_half(x,Fs)
+N=(length(x)); k=0:N-1; T=N/Fs; f=k/T;
+cutOff = ceil(N/2); f = f(1:cutOff);
+nTrials = size(x, 1);
+if nTrials == 1
+    s = fft(x)/N*2; % normalize the data
+    s = s(1:cutOff); % Single trial FFT
+else
+    s = [];
+    for trialIdx = 1:nTrials
+        s_temp = fft(x(trialIdx,:))/N*2;
+        s_temp = s_temp(1:cutOff); % Single trial FFT
+        s = [s; s_temp];
+    end
+end
+end
+function [idx,short] = hb_findIdx( range, fullData )
+short=false;
+idx = max(find( fullData < range(1)))+1:max(find(fullData<range(2)));
+if length(idx)==0, idx = 1:max(find(fullData<range(2))); end
+if range(2) > fullData(end), short=1; end
+end

+ 20 - 0
subfunc/hb_findIdx.m

@@ -0,0 +1,20 @@
+function [idx,short] = hb_findIdx( range, fullData )
+% function idx = hb_findIdx( range, fullData )
+
+short=false;
+idx = max(find( fullData < range(1)))+1:max(find(fullData<range(2)));
+
+if length(idx)==0
+%     idx
+    idx = 1:max(find(fullData<range(2)));
+end
+
+if range(2) > fullData(end)
+    short=1;
+%     disp(['Requested range: .. ' num2str( range(2)) ]);
+%     disp(['Actual range: .. ' num2str(fullData(end)) ]);
+%     disp(['Short: ' num2str( short) ]); 
+end
+
+return
+

+ 7 - 0
subfunc/interp_nan.m

@@ -0,0 +1,7 @@
+function y = interp_nan(x)
+nanx = isnan(x);
+t   = 1:numel(x);
+y = x;
+y(nanx) = interp1(t(~nanx), x(~nanx), t(nanx));
+end
+

+ 64 - 0
subfunc/parse_video_rgb.m

@@ -0,0 +1,64 @@
+function parse_video_rgb()
+%
+% Parsing video (*.mp4/*.avi) file(s) into image (*.jpg) files
+% Written by Hio-Been Han, 2023-08-23
+%
+%% (1) Get file info & set save directory
+% [file_list, vid_directory] = uigetfile('*.*','MultiSelect','on');
+vid_directory_single = './data_BIDS/stimuli/video/Single/';
+vid_directory_group = './data_BIDS/stimuli/video/Group/';
+if ~isdir('./data_BIDS/stimuli/video_parsed'), mkdir('./data_BIDS/stimuli/video_parsed'); end
+write_directory_single = './data_BIDS/stimuli/video_parsed/Single/';
+write_directory_group = './data_BIDS/stimuli/video_parsed/Group/';
+if ~isdir(write_directory_single), mkdir(write_directory_single); end
+if ~isdir(write_directory_group), mkdir(write_directory_group); end
+
+file_counter = 1;
+file_list = cell([3,64+8]);
+% Single
+for mouse = 1:8
+    for day = 1:2
+        for trial = 1:4
+            file_list{1,file_counter} = vid_directory_single;
+            file_list{2,file_counter} = sprintf('Day%d-Trial%d-Mouse%d.avi',day,trial,mouse);
+            file_list{3,file_counter} = write_directory_single;
+            file_counter = file_counter + 1;
+        end
+    end
+end
+% Group
+for day = 1:2
+    for trial = 1:4
+        file_list{1,file_counter} = vid_directory_group;
+        file_list{2,file_counter} = sprintf('Day%d-Trial%d-Group.avi',day,trial);
+        file_list{3,file_counter} = write_directory_group;
+        file_counter = file_counter + 1;
+    end
+end
+
+%% (2) Parse & save video into JPEG files
+save_format = '.jpg';
+for fileIdx = 1:length(file_list)
+    
+    % Set save directory
+    vid_directory = file_list{1,fileIdx};
+    fname = file_list{2,fileIdx};
+    img_directory = file_list{3,fileIdx};
+    uniqname = fname(1:end-4);
+    vidname = [vid_directory fname];
+    save_directory = [img_directory uniqname '/'];
+    if ~isdir(save_directory), mkdir(save_directory); end
+    
+    % Read frames
+    v = VideoReader( [ vidname ]);
+    nFrames = v.Duration * v.FrameRate;
+    for frameIdx = 1:7200
+        if v.hasFrame
+            frame = v.readFrame();
+            % Save frame
+            imgname_write = [num2str(sprintf('frame-%06d',frameIdx))...
+                '-' uniqname save_format];
+            imwrite(frame , [ save_directory imgname_write ] )
+        end
+    end
+end

+ 55 - 0
subfunc/plot_multichan.m

@@ -0,0 +1,55 @@
+function plot_multichan( x, y, interval, normalize )
+% Simple MATLAB function for plot multi-channel time-series data
+% 
+% Usage:
+%    plot_multichan( y )    % <- y: signal
+%    plot_multichan( x, y ) % <- x: time
+% 
+% Example: 
+%    y = randn([20, 2000]); 
+%    plot_multichan(y);
+%
+% Written by Hio-Been han, hiobeen.han@kaist.ac.kr, 2020-03-07
+% 
+
+% parse arguments
+if nargin==1, y=x; x = 1:length(y); end
+nChan = size(y,1);
+if nChan > size(y,2),  y = y'; nChan = size(y,1); end
+if nargin < 4, normalize = 0; end
+if normalize
+    stds = nanstd( y, 0, 2 );
+    for chIdx = 1:size(y,1), y(chIdx,:) = nanmean(stds) * (y(chIdx,:) / stds(chIdx)); end
+end
+if nargin < 3
+    interval = nanmean(range(y, 2)) * nChan / 5;
+end
+y_center = linspace( -interval, interval, nChan );
+
+% set colormap
+color_template =...
+   [843 088 153;
+    992 750 280;
+    400 200 030;
+    573 716 350;
+    055 538 083]*.001;
+c_space = repmat( color_template, [ ceil( nChan/size(color_template,1)), 1]);
+% c_space=imresize(colormap('lines'),[nChan,3],'nearest');
+
+% main plot
+chanlab = {}; chanlab_pos = [];
+lw = 1;
+for chanIdx = 1:nChan
+    shift = y_center(chanIdx) + nanmean( y( chanIdx, : ), 2);
+    plot( x, y( chanIdx, : ) - shift, 'Color', c_space( chanIdx,: ) , 'LineWidth', lw); 
+    chanIdx_reverse = nChan-chanIdx+1;
+    chanlab{chanIdx} = sprintf( 'Ch %02d', chanIdx_reverse);
+    chanlab_pos(chanIdx) =  y_center(chanIdx) ;
+    if chanIdx ==1, hold on; end
+end
+hold off;
+
+% enhance visibility
+set(gca, 'YTick', chanlab_pos, 'YTickLabel', chanlab,...
+    'Clipping', 'on', 'Box', 'off', 'LineWidth', 2);
+ylim([-1 1]*interval*2);