From c769f7f72cdabc58ab78b2e99f028048032b0eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 10 Mar 2023 16:47:40 +0100 Subject: [PATCH 001/201] Changed commenting style --- Jesus/DE_Jittering.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 0c6c7cb..bd2b51d 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -455,10 +455,12 @@ consVars = {'relativeSpkTmsStruct', 'firstSpkStruct', ... 'SpontaneousStruct', 'configStructure'}; rspMF = matfile(fullfile(dataDir, relSpkFN)); -% relSpkFN =... -% sprintf('%s RW%.2f - %.2f ms SW%.2f - %.2f ms VW%.2f - %.2f ms %s (%s) exportSpkTms.mat',... -% expName, responseWindow*1e3, spontaneousWindow*1e3,... -% timeLapse*1e3, Conditions(chCond).name, filtStr); +%{ +relSpkFN =... + sprintf('%s RW%.2f - %.2f ms SW%.2f - %.2f ms VW%.2f - %.2f ms %s (%s) exportSpkTms.mat',... + expName, responseWindow*1e3, spontaneousWindow*1e3,... + timeLapse*1e3, Conditions(chCond).name, filtStr); +%} if ~exist(relSpkFN,'file') || any(~contains(who(rspMF), consVars)) rst = arrayfun(@(x) getRasterFromStack(discStack, ~delayFlags(:,x), ... filterIdx(3:end), timeLapse, fs, true, true), 1:size(delayFlags,2), ... From cf1ea18fd9949cf6fa4776c019ce99179a26c63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 16 Mar 2023 18:36:53 +0100 Subject: [PATCH 002/201] Figure folder organisation --- Jesus/DE_Jittering.m | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index bd2b51d..c324082 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -9,9 +9,9 @@ end %% Loading data % Creating the figure directory -figureDir = fullfile(dataDir,'Figures\'); -if ~exist(figureDir, "dir") - if ~mkdir(figureDir) +FigureDir = fullfile(dataDir,'Figures\'); +if ~exist(FigureDir, "dir") + if ~mkdir(FigureDir) error("Could not create figure directory!\n") end end @@ -282,16 +282,17 @@ end %% Creating ephys figure folder subFigDir = sprintf("Ephys %s %s %s", VW_key, RW_key, SW_key); -subFigDir = fullfile(figureDir, subFigDir); +subFigDir = fullfile(FigureDir, subFigDir); +ephFigDir = subFigDir; metaNameFlag = false; if ~exist(subFigDir, "dir") if ~mkdir(subFigDir) fprintf(1, "Couldn't create %s!\n", subFigDir) fprintf(1, "Keeping metadata in figure file names.\n") metaNameFlag = true; + ephFigDir = FigureDir; end end -figureDir = subFigDir; %% Constructing the stack out of the user's choice % discStack - dicrete stack has a logical nature % cst - continuous stack has a numerical nature @@ -375,7 +376,7 @@ if metaNameFlag stFigSubfix = stFigSubfix + " " + RW_key + " " + SW_key; end -stFigFN = fullfile(figureDir, "Stat " + cmpCondNames + stFigSubfix); +stFigFN = fullfile(ephFigDir, "Stat " + cmpCondNames + stFigSubfix); cmpCondNames_aux([snglSubs, cmbSubs]) = stFigFN; stFigFN = cmpCondNames_aux; if exist(resFP,"file") && all(arrayfun(@(x) exist(x, "file"), stFigFN)) @@ -524,7 +525,9 @@ psthFN = psthFN + " " + filtStr; end % PSTH construction -psthFP = fullfile(figureDir, psthFN); +psthFP = fullfile(ephFigDir, psthFN); +[PSTH, trig] = arrayfun(@(x) getPSTH(discStack(filterIdx,:,:), ... + timeLapse, ~delayFlags(:,x), binSz, fs), 1:Nccond, fnOpts{:}); if any(arrayfun(@(x) ~exist(x+".fig","file"), psthFP)) [PSTH, trig] = arrayfun(@(x) ... getPSTH(discStack(filterIdx,:,:), timeLapse, ~delayFlags(:,x), ... @@ -550,7 +553,7 @@ ephysPttrn = 'Z-score all-units PSTH %s Ntrials%s'; ephysName = sprintf(ephysPttrn, sprintf('%s ', consCondNames{:}), ... sprintf(' %d', Na)); -ephysFile = fullfile(figureDir, ephysName); +ephysFile = fullfile(ephFigDir, ephysName); if ~exist(ephysFile, 'file') [ppFig, PSTHall] = compareCondPSTHs(cat(3,PSTH{:}), Na, binSz, ... timeLapse, consCondNames); @@ -570,7 +573,7 @@ logPSTH.Normalization, Nccond, Nbin); if Nccond > 1 lmiFN = sprintf("LogMI %d-conditions NB%d", Nccond, Nbin); - lmiFP = fullfile(figureDir, lmiFN); + lmiFP = fullfile(ephFigDir, lmiFN); end if filtFlag lpFN = lpFN + " (" + filtStr + ")"; @@ -578,7 +581,7 @@ lmiFP = lmiFP + " (" + filtStr + ")"; end end -lpFP = fullfile(figureDir, lpFN); +lpFP = fullfile(ephFigDir, lpFN); if ~exist(lpFP+".fig", "file") logFigs = plotLogPSTH(logPSTH); saveFigure(logFigs(1), lpFP, true) if numel(logFigs) > 1 @@ -645,7 +648,7 @@ pObj = findobj(respFig, "Type", "Patch"); arrayfun(@(x) set(x, "EdgeColor", "none"), pObj); arrayfun(@(x) set(pObj(x), "FaceColor", clrMap(x+2,:)), 1:length(pObj)) -propPieFileName = fullfile(figureDir,... +propPieFileName = fullfile(ephFigDir,... sprintf("Whisker responsive proportion pie %s (%dC, %dR)",... C_key, [Ntn-Nrn, Nrn])); saveFigure(respFig, propPieFileName, 1); @@ -657,7 +660,7 @@ pObj = findobj(potFig, "Type", "Patch"); arrayfun(@(x) set(x, "EdgeColor", "none"), pObj); arrayfun(@(x) set(pObj(x), "FaceColor", clrMap(x,:)), 1:length(pObj)) - modPropPieFigFileName = fullfile(figureDir,... + modPropPieFigFileName = fullfile(ephFigDir,... sprintf("Modulation proportions pie %s (%dR, %dP, %dD)",... C_key, Nrn - Nrsn, Nrsp, Nrsn - Nrsp)); saveFigure(potFig, modPropPieFigFileName, 1) @@ -667,7 +670,7 @@ title("Modulation index distribution"); xlabel("MI"); ylabel("Cluster proportion"); lgnd = legend("show"); set(lgnd, "Box", "off", "Location", "best") - saveFigure(MIFig, fullfile(figureDir,... + saveFigure(MIFig, fullfile(ephFigDir,... "Modulation index dist evoked & after induction "+C_key), 1) end %% Get significantly different clusters @@ -798,7 +801,7 @@ rasFigName = sprintf('%s R-%scl_%sVW%.1f-%.1f ms', expName,... sprintf('%s ', rasCondNames{:}), sprintf('%s ', pclID{clSel}),... timeLapse*1e3); - rasFigPath = fullfile(figureDir, rasFigName); + rasFigPath = fullfile(ephFigDir, rasFigName); arrayfun(@(x) set(x,'Color','none'), ax); saveFigure(rasFig, rasFigPath, 1); clearvars ax rasFig @@ -890,7 +893,7 @@ behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); behRes = analyseBehaviour(behDir, 'Condition', possNames(behChCond), ... - 'PairedFlags', delayFlags, 'FigureDirectory', figureDir, ... + 'PairedFlags', delayFlags, 'FigureDirectory', FigureDir, ... 'ConditionsNames', cellstr(consCondNames)); end end From 2eeb0f7e7395c3a56debef85205dacf851cf7fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 16 Mar 2023 18:37:09 +0100 Subject: [PATCH 003/201] Sequential logic bug fix --- Jesus/DE_Jittering.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index c324082..4a83a1c 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -529,9 +529,6 @@ [PSTH, trig] = arrayfun(@(x) getPSTH(discStack(filterIdx,:,:), ... timeLapse, ~delayFlags(:,x), binSz, fs), 1:Nccond, fnOpts{:}); if any(arrayfun(@(x) ~exist(x+".fig","file"), psthFP)) - [PSTH, trig] = arrayfun(@(x) ... - getPSTH(discStack(filterIdx,:,:), timeLapse, ~delayFlags(:,x), ... - binSz, fs), 1:Nccond, fnOpts{:}); if exist('cst', 'var') && ~isempty(cst) % Take into account covariance for signals. stims = arrayfun(@(x) mean(cst(:,:,delayFlags(:,x)),3), 1:Nccond, ... From d3ad986752c0c10ddb25326c8ca7f7a5030ab388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 16 Mar 2023 18:37:22 +0100 Subject: [PATCH 004/201] Removing commented old, dead code --- Jesus/DE_Jittering.m | 304 +------------------------------------------ 1 file changed, 1 insertion(+), 303 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 4a83a1c..9e5fab5 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -683,29 +683,6 @@ fprintf(1, 'You can always get the waveforms later\n') end -%% Addition mean signals to the Conditions variable (Unused) -%{ -if ~isfield(Conditions,'Stimulus') ||... - any(arrayfun(@(x) isempty(x.Stimulus), Conditions(consideredConditions))) - fprintf(1,'Writting the stimulus raw signal into Conditions variable:\n') - whFlag = contains(trigNames, whStim, 'IgnoreCase', 1); - lrFlag = contains(trigNames, cxStim, 'IgnoreCase', 1); - cdel = 1; - for cc = consideredConditions - fprintf(1,'- %s\n', Conditions(cc).name) - Conditions(cc).Stimulus = struct(... - 'Mechanical',reshape(mean(cst(whFlag,:,delayFlags(:,cdel)),3),... - 1,Nt),'Laser',reshape(mean(cst(lrFlag,:,delayFlags(:,cdel)),3),... - 1,Nt),'TimeAxis',(0:Nt-1)/fs + timeLapse(1)); - cdel = cdel + 1; - end - save(fullfile(dataDir,[expName,'analysis.mat']),'Conditions','-append') -end -%} - -%% Standard Deviations of First Spikes After Each Trigger per Unit -% firstSpikes(relativeSpkTmsStruct, gclID, dataDir); - %% Rasters from interesting clusters rasAns = questdlg('Plot rasters?','Raster plot','Yes','No','Yes'); if strcmpi(rasAns,'Yes') @@ -893,283 +870,4 @@ 'PairedFlags', delayFlags, 'FigureDirectory', FigureDir, ... 'ConditionsNames', cellstr(consCondNames)); end -end -%{ - -afPttrn = "ArduinoTriggers*.mat"; -rfPttrn = "RollerSpeed*.mat"; -axOpts = {'Box','off','Color','none'}; -lgOpts = cat(2, axOpts{1:2}, {'Location','best'}); -flds = dir(getParentDir(dataDir,1)); -pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), flds); -flds(pointFlag) = []; -behFoldFlag = arrayfun(@(x) any(strcmpi(x.name, 'Behaviour')), flds); -if any(behFoldFlag) && sum(behFoldFlag) == 1 - % If only one folder named Behaviour exists, chances are that this is - % an awake experiment. - behDir = fullfile(flds(behFoldFlag).folder,flds(behFoldFlag).name); - fprintf(1, "Found %s!\n", behDir) - promptStrings = {'Viewing window (time lapse) [s]:','Response window [s]'}; - defInputs = {'-0.25, 0.5', '0.005, 0.4'}; - answ = inputdlg(promptStrings,'Behaviour parameters', [1, 30], defInputs); - if isempty(answ) - fprintf(1,'Cancelling...\n') - return - else - bvWin = str2num(answ{1}); %#ok<*ST2NM> - if numel(bvWin) ~= 2 - bvWin = str2num(inputdlg('Please provide the time window [s]:',... - 'Time window',[1, 30], '-0.1, 0.1')); - if isnan(bvWin) || isempty(bvWin) - fprintf(1,'Cancelling...') - return - end - end - brWin = str2num(answ{2}); - end - if isempty(dir(fullfile(behDir, afPttrn))) - readAndCorrectArdTrigs(behDir); - end - - fprintf(1,'Time window: %.2f - %.2f ms\n',bvWin*1e3) - fprintf(1,'Response window: %.2f - %.2f ms\n',brWin*1e3) - % Roller speed - rfFiles = dir(fullfile(behDir, rfPttrn)); - if isempty(rfFiles) - [~, vf, rollTx, fr, Texp] = createRollerSpeed(behDir); - rfFiles = dir(fullfile(behDir, rfPttrn)); - end - if numel(rfFiles) == 1 - rfName = fullfile(rfFiles.folder, rfFiles.name); - load(rfName) - try - % Encoder steps Radius^2 - en2cm = ((2*pi)/((2^15)-1))*((14.85/2)^2)*rollFs; - fr = rollFs; - catch - try - % Encoder steps Radius^2 - en2cm = ((2*pi)/((2^15)-1))*((14.85/2)^2)*fr; - catch - en2cm = ((2*pi)/((2^15)-1))*((14.85/2)^2)*fsRoll; - fr = fsRoll; - end - end - end - % Triggers - getFilePath = @(x) fullfile(x.folder, x.name); - atVar = {'atTimes', 'atNames', 'itTimes', 'itNames'}; - afFiles = dir(fullfile(behDir,afPttrn)); - if ~isempty(afFiles) - atV = arrayfun(@(x) load(getFilePath(x), atVar{:}), afFiles); - Nrecs = length(atV); - atT = arrayfun(@(x, z) cellfun(@(y, a) y+a, ... - x.atTimes, repmat(z,1,length(x.atTimes)), fnOpts{:}), atV', ... - num2cell([0, Texp(1:end-1)]), fnOpts{:}); - trig_per_recording = cellfun(@(x) size(x,2), atT); - [max_trigs, record_most_trigs] = max(trig_per_recording); - record_trig_cont_ID = arrayfun(@(x) ... - contains(atV(record_most_trigs).atNames, x.atNames), ... - atV(1:Nrecs), fnOpts{:}); outCell = cell(Nrecs, max_trigs); - for cr = 1:Nrecs - outCell(cr,record_trig_cont_ID{cr}) = atT{cr}; - end - atTimes = arrayfun(@(x) cat(1, outCell{:,x}), 1:size(outCell,2), ... - fnOpts{:}); - atNames = atV(1).atNames; - end - - lSub = arrayfun(@(x) contains(Conditions(chCond).name, x), atNames); - [~, vStack] = getStacks(false, round(atTimes{lSub} * fr), 'on', bvWin,... - fr, fr, [], vf*en2cm); [~, Nbt, Nba] = size(vStack); - tmdl = fit_poly([1,Nbt], bvWin, 1); - behTx = ((1:Nbt)'.^[1,0])*tmdl; - % Spontaneous flag - bsFlag = behTx <= 0; brFlag = behTx < brWin; - brFlag = xor(brFlag(:,1),brFlag(:,2)); - sSig = squeeze(std(vStack(:,bsFlag,:), [], 2)); - sMed = squeeze(median(vStack(:,bsFlag,:), 2)); - tMed = squeeze(median(vStack, 2)); - - % A bit arbitrary threshold, but enough to remove running trials - sigTh = 2.5; sMedTh = 0.2; tMedTh = 1; - thrshStr = sprintf("TH s%.2f sp_m%.2f t_m%.2f", sigTh, sMedTh, tMedTh); - excFlag = sSig > sigTh | abs(sMed) > sMedTh | abs(tMed) > tMedTh; - ptOpts = {"Color", 0.7*ones(1,3), "LineWidth", 0.2;... - "Color", "k", "LineWidth", 1.5}; - spTh = {0.1:0.1:3}; % Speed threshold - gp = zeros(Nccond, 1, 'single'); - rsPttrn = "%s roller speed VW%.2f - %.2f s RM%.2f - %.2f ms EX%d %s"; - pfPttrn = "%s move probability %.2f RW%.2f - %.2f ms EX%d %s"; - rsSgnls = cell(Nccond, 1); mvFlags = cell(Nccond,1); mvpt = mvFlags; - qSgnls = rsSgnls; - mat2ptch = @(x) [x(1:end,:)*[1;1]; x(end:-1:1,:)*[1;-1]]; - getThreshCross = @(x) sum(x)/size(x,1); - xdf = arrayfun(@(x) ~excFlag & delayFlags(:,x), 1:Nccond, ... - fnOpts{:}); xdf = cat(2, xdf{:}); - - for ccond = 1:Nccond - sIdx = xdf(:,ccond); - % % Plot speed signals - fig = figure("Color", "w"); - Nex = sum(xor(sIdx, delayFlags(:,ccond))); - rsFigName = sprintf(rsPttrn,consCondNames{ccond}, bvWin,... - brWin*1e3, Nex, thrshStr); - % Plot all trials - plot(behTx, squeeze(vStack(:,:,sIdx)), ptOpts{1,:}); hold on; - % Plot mean of trials - % Standard deviation - %rsSgnls{ccond} = [squeeze(mean(vStack(:,:,sIdx),3))',... - %squeeze(std(vStack(:,:,sIdx),1,3))']; - % S.E.M. - rsSgnls{ccond} = [squeeze(mean(vStack(:,:,sIdx),3))',... - squeeze(std(vStack(:,:,sIdx),1,3))'./sqrt(sum(sIdx))]; - qSgnls{ccond} = squeeze(quantile(vStack(:,:,sIdx),3,3)); - lObj = plot(behTx, rsSgnls{ccond}(:,1), ptOpts{2,:}); - lgnd = legend(lObj,string(consCondNames{ccond})); - set(lgnd, "Box", "off", "Location", "best") - set(gca, axOpts{:}) - title(['Roller speed ',consCondNames{ccond}]) - xlabel("Time [s]"); ylabel("Roller speed [cm/s]"); xlim(bvWin) - saveFigure(fig, fullfile(figureDir, rsFigName), 1) - % Probability plots - mvpt{ccond} = getMaxAbsPerTrial(squeeze(vStack(:,:,sIdx)), ... - brWin, behTx); - mvFlags{ccond} = compareMaxWithThresh(mvpt{ccond}, spTh); - gp(ccond) = getAUC(mvFlags{ccond}); - pfName = sprintf(pfPttrn, consCondNames{ccond}, gp(ccond),... - brWin*1e3, Nex, thrshStr); - fig = plotThetaProgress(mvFlags(ccond), spTh,... - string(consCondNames{ccond})); - xlabel("Roller speed \theta [cm/s]"); - title(sprintf("Trial proportion crossing \\theta: %.3f", gp(ccond))) - saveFigure(fig, fullfile(figureDir, pfName), 1) - end - clMap = lines(Nccond); - phOpts = {'EdgeColor', 'none', 'FaceAlpha', 0.25, 'FaceColor'}; - % Plotting mean speed signals together - fig = figure("Color", "w"); axs = axes("Parent", fig, "NextPlot", "add"); - arrayfun(@(x) patch(axs, behTx([1:end, end:-1:1]),... - mat2ptch(rsSgnls{x}), 1, phOpts{:}, clMap(x,:)), 1:Nccond); hold on - lObj = arrayfun(@(x) plot(axs, behTx, rsSgnls{x}(:,1), "Color", clMap(x,:),... - "LineWidth", 1.5, "DisplayName", consCondNames{x}), 1:Nccond); - xlabel(axs, "Time [s]"); xlim(axs, bvWin); ylabel(axs, "Roller speed [cm/s]") - set(axs, axOpts{:}); title(axs, "Roller speed for all conditions") - lgnd = legend(axs, lObj); set(lgnd, lgOpts{:}) - rsPttrn = "Mean roller speed %s VW%.2f - %.2f s RM%.2f - %.2f ms EX%s %s SEM"; - Nex = Na - sum(xdf); - rsFigName = sprintf(rsPttrn, sprintf('%s ', consCondNames{:}), bvWin,... - brWin*1e3, sprintf('%d ', Nex), thrshStr); - saveFigure(fig, fullfile(figureDir, rsFigName), 1) - - % Plotting median speed signals together - q2patch = @(x) [x(:,1);x(end:-1:1,3)]; - fig = figure("Color", "w"); axs = axes("Parent", fig, "NextPlot", "add"); - arrayfun(@(x) patch(axs, behTx([1:end, end:-1:1]),... - q2patch(qSgnls{x}), 1, phOpts{:}, clMap(x,:)), 1:Nccond); hold on - lObj = arrayfun(@(x) plot(axs, behTx, qSgnls{x}(:,2), "Color", clMap(x,:),... - "LineWidth", 1.5, "DisplayName", consCondNames{x}), 1:Nccond); - xlabel(axs, "Time [s]"); xlim(axs, bvWin); ylabel(axs, "Roller speed [cm/s]") - set(axs, axOpts{:}); title(axs, "Roller speed for all conditions") - lgnd = legend(axs, lObj); set(lgnd, lgOpts{:}) - rsPttrn = "Median roller speed %s VW%.2f - %.2f s RM%.2f - %.2f ms EX%s %s IQR"; - rsFigName = sprintf(rsPttrn, sprintf('%s ', consCondNames{:}), bvWin,... - brWin*1e3, sprintf('%d ', Nex), thrshStr); - saveFigure(fig, fullfile(figureDir, rsFigName), 1) - - % Plotting movement threshold crossings - fig = figure("Color", "w"); axs = axes("Parent", fig, "NextPlot", "add"); - mvSgnls = cellfun(getThreshCross, mvFlags, fnOpts{:}); - mvSgnls = cat(1, mvSgnls{:}); mvSgnls = mvSgnls'; - plot(axs, spTh{1}, mvSgnls); - ccnGP = cellfun(@(x, y) [x, sprintf(' AUC%.3f',y)], consCondNames', ... - num2cell(gp), fnOpts{:}); - lgnd = legend(axs, ccnGP); set(axs, axOpts{:}) - set(lgnd, lgOpts{:}); ylim(axs, [0,1]) - xlabel(axs, "Roller speed \theta [cm/s]"); ylabel(axs, "Trial proportion") - title(axs, "Trial proportion crossing \theta") - pfPttrn = "Move probability %sRW%.2f - %.2f ms %s"; - pfName = sprintf(pfPttrn, sprintf('%s ', ccnGP{:}), brWin*1e3, thrshStr); - saveFigure(fig, fullfile(figureDir, pfName), 1) - - % Plotting maximum speed for all considered trials - fig = figure; axs = axes('Parent', fig, 'NextPlot', 'add'); - arrayfun(@(x) boxchart(x*ones(size(mvpt{x},1),1), mvpt{x}, 'Notch', 'on'), ... - 1:size(mvpt,1)) - xticks(axs, 1:size(mvpt,1)); xticklabels(axs, consCondNames) - try - ylim(axs, [0, round(1.05*(max(cellfun(@(x) quantile(x, 0.75) + ... - 1.5*iqr(x), mvpt))),1)]); - catch - ylim(axs, 'auto') - end - ylabel(axs, "Roller speed [cm/s]") - arrayfun(@(x) text(x, median(mvpt{x}), sprintf("%.2f",median(mvpt{x})), ... - "HorizontalAlignment", "center", "VerticalAlignment", "bottom"), ... - 1:Nccond, fnOpts{:}); - title(axs, "Roller speed distribution") - rsdPttrn = "Roller speed dist %sVW%.2f - %.2f ms RM%.2f - %.2f ms EX%s%s"; - rsdFigName = sprintf(rsdPttrn, sprintf('%s ', consCondNames{:}), bvWin*1e3,... - brWin*1e3, sprintf('%d ', Nex), thrshStr); - saveFigure(fig, fullfile(figureDir, rsdFigName), 1) - - % Tests for movement - prms = nchoosek(1:Nccond,2); - getDistTravel = @(x) squeeze(sum(abs(vStack(:,brFlag,xdf(:,x))),2)); - dstTrav = arrayfun(getDistTravel, 1:Nccond, fnOpts{:}); - [pd, hd, statsd] = arrayfun(@(x) ranksum(dstTrav{prms(x,1)}, ... - dstTrav{prms(x,2)}), 1:size(prms,1), fnOpts{:}); - [pm, hm, statsm] = arrayfun(@(x) ranksum(mvpt{prms(x,1)}, ... - mvpt{prms(x,2)}), 1:size(prms,1), fnOpts{:}); - resPttrn = "Results %s%sVW%.2f - %.2f ms RW%.2f - %.2f ms EX%s%s.mat"; - resName = sprintf(resPttrn, sprintf("%d ", hd{:}), ... - sprintf('%s ',consCondNames{:}), bvWin*1e3, brWin*1e3, ... - sprintf('%d ', Nex), thrshStr); - save(fullfile(behDir, resName), "gp", "dstTrav", "ccnGP", "mvpt", "xdf", ... - "vStack", "spTh", "sigTh", "sMedTh", "tMedTh", "brWin", "bvWin", "prms") - - % Behaviour signals - behResBase = "BehaveSignals"; - expDate = getDates(string(rfFiles.name), "RollerSpeed"); - behResName = sprintf("%s%s.mat",behResBase, expDate); - behResPath = fullfile(behDir, behResName); - if ~exist(behResName,'file') - timeAxis_speed = (0:length(vf)-1)'/fr; - time_drift_mdl = fit_poly(atTimes{lSub}, Conditions(chCond).Triggers(:,1)/fs, 1); - timeAxis_speed_corrected = timeAxis_speed.^[1,0] * time_drift_mdl; - timeAxis_speed = (0:1/fr:timeAxis_speed_corrected(end))'; - vels = interp1(timeAxis_speed_corrected, vf*en2cm, timeAxis_speed); - save(behResPath, "vels", "timeAxis_speed", "fr") - - dlcFiles = dir(fullfile(behDir, "*filtered.csv")); - dlcFile = []; - if ~isempty(dlcFiles) - if numel(dlcFiles)==1 - dlcFile = dlcFiles.name; - end - else - dlcFiles = dir(fullfile(behDir, "roller*DLC_resnet50_AwakenSCJul20shuffle1_1030000.csv")); - if ~isempty(dlcFiles) - if numel(dlcFiles) == 1 - dlcFile = dlcFiles.name; - end - else - fprintf(1, "No DLC applied on the videos yet!\n") - fprintf(1, "Unable to get behavioural signals!\n") - end - end - if ~isempty(dlcFile) - dlcTable = readDLCData(fullfile(behDir, dlcFile)); - [a_bodyParts, refStruct] = getBehaviourSignals(dlcTable); - nose = a_bodyParts{:,"nose"} - mean(a_bodyParts{:,"nose"}); - % Right whiskers - rw = mean(a_bodyParts{:,{'rw1', 'rw2', 'rw3', 'rw4'}}, 2); - rw = rw - mean(rw); - % Left whiskers - lw = mean(a_bodyParts{:,{'lw1', 'lw2', 'lw3', 'lw4'}},2); - lw = lw - mean(lw); - save(behResPath,"rw","lw","nose","-append") - end - end -end -%} \ No newline at end of file +end \ No newline at end of file From d34166438788cae43f9f3e30800b9f2f8460d9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 29 Mar 2023 14:32:57 +0200 Subject: [PATCH 005/201] Added the behavioural index --- Jesus/DE_Jittering.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 9e5fab5..8068888 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -866,8 +866,15 @@ if strcmpi(answ,'Yes') behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); - behRes = analyseBehaviour(behDir, 'Condition', possNames(behChCond), ... + [behRes, behFigDir] = analyseBehaviour(behDir, 'Condition', possNames(behChCond), ... 'PairedFlags', delayFlags, 'FigureDirectory', FigureDir, ... 'ConditionsNames', cellstr(consCondNames)); + biFigPttrn = "BehIndex%s"; + biFigPttrn = sprintf(biFigPttrn, sprintf(" %s (%%.3f)", consCondNames)); + [pAreas, ~, behAreaFig] = createBehaviourIndex(behRes); + behRes = arrayfun(@(bs, ba) setfield(bs,'BehIndex', ba), behRes, pAreas); + + biFN = sprintf(biFigPttrn, pAreas); + saveFigure(behAreaFig, fullfile(behFigDir, biFN), true); end end \ No newline at end of file From cdd541f905178ba242ef4b4496e520ec458c2ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 5 Apr 2023 18:13:27 +0200 Subject: [PATCH 006/201] Maximum value per trial --- Emilio/AKK/getMaxAbsPerTrial.m | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Emilio/AKK/getMaxAbsPerTrial.m b/Emilio/AKK/getMaxAbsPerTrial.m index 10e4d56..217082e 100644 --- a/Emilio/AKK/getMaxAbsPerTrial.m +++ b/Emilio/AKK/getMaxAbsPerTrial.m @@ -1,4 +1,4 @@ -function [mavpt] = getMaxAbsPerTrial(inStack, responseWindow, timeAxis) +function [mavpt, mxT] = getMaxAbsPerTrial(inStack, responseWindow, timeAxis) %GETMAXABSPERTRIAL gets as the name suggests, the maximum absolute %amplitude per trial in the given input stack % Detailed explanation goes here, later. @@ -22,7 +22,9 @@ responseFlags = timeAxis >= responseWindow; responseFlags = xor(responseFlags(:,1), responseFlags(:,2)); -mavpt = max(abs(inStack(responseFlags, :)-median(inStack,1))); -mavpt = mavpt(:); -end - +% mavpt = max(abs(inStack(responseFlags, :)-median(inStack,1))); +[~, ps] = max(abs(inStack(responseFlags,:) - median(inStack(timeAxis<0,:),1))); +mavpt = arrayfun(@(mp, tr) ... + inStack(find(responseFlags,1,'first')+mp-1, tr), ps(:), (1:Ntg)'); +mxT = timeAxis(ps+find(responseFlags,1,"first")-1); +end \ No newline at end of file From 57b970fe8aa01fbb0dccdee743dd70055180a189 Mon Sep 17 00:00:00 2001 From: jesusmartin-cortecero <53047456+jesusmartin-cortecero@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:39:07 +0200 Subject: [PATCH 007/201] tesstanonimousfunction --- Jesus/arrayfun_examples_sum_mean.m | 515 +++++++++++++++++++++++++++++ Jesus/whiskerScBehavior.m | 2 +- 2 files changed, 516 insertions(+), 1 deletion(-) create mode 100644 Jesus/arrayfun_examples_sum_mean.m diff --git a/Jesus/arrayfun_examples_sum_mean.m b/Jesus/arrayfun_examples_sum_mean.m new file mode 100644 index 0000000..2a721fc --- /dev/null +++ b/Jesus/arrayfun_examples_sum_mean.m @@ -0,0 +1,515 @@ +% introduction to anonymous functions + + out = arrayfun(@(var2) arrayfun(@(var1) sum(x(var1,var2,1:2:end),3), 1:size(x,1)), 1:size(x,2),'UniformOutput',false) + out = arrayfun(@(var2) arrayfun(@(var1) sum(x(var1,var2,1:2:end),3), 1:size(x,1), 'UniformOutput', false), 1:size(x,2), 'UniformOutput', false) + + +out = cat(1, out{:}); +out + +out = + + 2 3 4 5 6 7 8 9 10 11 + 3 4 5 6 7 8 9 10 11 12 + 4 5 6 7 8 9 10 11 12 13 + 5 6 7 8 9 10 11 12 13 14 + 6 7 8 9 10 11 12 13 14 15 + 7 8 9 10 11 12 13 14 15 16 + 8 9 10 11 12 13 14 15 16 17 + 9 10 11 12 13 14 15 16 17 18 + 10 11 12 13 14 15 16 17 18 19 + 11 12 13 14 15 16 17 18 19 20 + 12 13 14 15 16 17 18 19 20 21 + 13 14 15 16 17 18 19 20 21 22 + +out = arrayfun(@(var2) arrayfun(@(var1) var1 + var2, 1:size(x,1)), 1:size(x,2), 'UniformOutput', false); +out = arrayfun(@(var2) arrayfun(@(var1) x(var1) + x(var2), 1:size(x,1)), 1:size(x,2), 'UniformOutput', false); + arrayfun(@(var2) arrayfun(@(var1) x(var1) + x(var2), 1:size(x,1)), 1:size(x,2), 'UniformOutput', false); +x + +x(:,:,1) = + + 43 54 78 52 26 92 18 27 65 46 59 55 + 10 66 43 95 23 1 73 77 68 67 55 65 + 60 41 10 64 67 47 48 19 64 78 87 55 + 48 82 27 96 85 43 16 29 95 36 27 73 + 70 72 16 25 35 47 35 10 21 67 32 53 + 70 97 29 68 79 78 61 58 71 42 12 100 + 64 54 45 29 68 33 20 69 24 85 94 22 + 4 33 53 68 1 79 74 55 12 84 65 11 + 7 11 46 70 61 48 25 43 61 26 48 11 + 32 62 88 7 39 4 92 65 46 62 64 7 + + +x(:,:,2) = + + 41 70 35 74 83 80 52 54 86 62 74 77 + 45 10 15 40 43 95 89 9 57 99 59 59 + 37 53 59 69 89 33 59 12 93 53 25 93 + 77 54 27 71 40 68 16 14 70 48 67 59 + 63 87 5 45 77 44 20 68 59 81 9 2 + 78 49 76 2 40 84 41 50 82 23 63 13 + 94 40 25 34 81 77 75 19 88 50 67 87 + 98 68 45 43 76 17 83 50 99 91 73 49 + 20 75 69 28 38 87 79 15 1 58 90 85 + 14 53 36 20 22 99 32 6 87 85 99 21 + + +x(:,:,3) = + + 56 15 13 95 74 14 56 99 18 92 90 46 + 63 19 50 9 7 4 86 54 36 11 8 11 + 4 5 86 11 87 94 35 71 6 75 25 100 + 62 64 88 15 94 31 45 100 53 74 6 34 + 37 29 28 17 99 30 6 29 34 57 45 30 + 5 54 21 63 86 34 18 42 18 19 2 7 + 49 70 57 58 79 47 67 47 21 60 90 30 + 20 50 65 6 52 65 34 77 91 30 20 5 + 13 54 42 94 18 3 90 82 68 14 10 51 + 21 45 21 73 40 85 12 11 47 22 31 77 + +arrayfun(@(var2) arrayfun(@(var1) x(var1) + x(var2), 1:size(x,1)), 1:size(x,2), 'UniformOutput', false); +out = arrayfun(@(var2) arrayfun(@(var1) x(var1) + x(var2), 1:size(x,1)), 1:size(x,2), 'UniformOutput', false); +out = arrayfun(@(var2) arrayfun(@(var1) x(var1) + x(var2), 1:size(x,1)), 1:size(x,2), 'UniformOutput', false); +out = arrayfun(@(var2) arrayfun(@(var1) x(var1) + x(var2), 1:size(x,1)), 1:size(x,2), 'UniformOutput', false); +out = arrayfun(@(var2) arrayfun(@(var1) x(var1) + x(var2), 1:size(x,1)), 1:size(x,2), 'UniformOutput', false) + +out = + + 1×12 cell array + + Columns 1 through 7 + + {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} + + Columns 8 through 12 + + {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} + +out = arrayfun(@(var2) arrayfun(@(var1) mean(x(var1,var2,:),3), 1:size(x,1)), 1:size(x,2), 'UniformOutput', false) + +out = + + 1×12 cell array + + Columns 1 through 7 + + {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} + + Columns 8 through 12 + + {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} + +out = cat(1, out{:}); +out = cat(1, out{:}) +Brace indexing is not supported for variables of this type. + +out + +out = + + 46.6667 39.3333 33.6667 62.3333 56.6667 51.0000 69.0000 40.6667 13.3333 22.3333 + 46.3333 31.6667 33.0000 66.6667 62.6667 66.6667 54.6667 50.3333 46.6667 53.3333 + 42.0000 36.0000 51.6667 47.3333 16.3333 42.0000 42.3333 54.3333 52.3333 48.3333 + 73.6667 48.0000 48.0000 60.6667 29.0000 44.3333 40.3333 39.0000 64.0000 33.3333 + 61.0000 24.3333 81.0000 73.0000 70.3333 68.3333 76.0000 43.0000 39.0000 33.6667 + 62.0000 33.3333 58.0000 47.3333 40.3333 65.3333 52.3333 53.6667 46.0000 62.6667 + 42.0000 82.6667 47.3333 25.6667 20.3333 40.0000 54.0000 63.6667 64.6667 45.3333 + 60.0000 46.6667 34.0000 47.6667 35.6667 50.0000 45.0000 60.6667 46.6667 27.3333 + 56.3333 53.6667 54.3333 72.6667 38.0000 57.0000 44.3333 67.3333 43.3333 60.0000 + 66.6667 59.0000 68.6667 52.6667 68.3333 28.0000 65.0000 68.3333 32.6667 56.3333 + 74.3333 40.6667 45.6667 33.3333 28.6667 25.6667 83.6667 52.6667 49.3333 64.6667 + 59.3333 45.0000 82.6667 55.3333 28.3333 40.0000 46.3333 21.6667 49.0000 35.0000 + +x + +x(:,:,1) = + + 43 54 78 52 26 92 18 27 65 46 59 55 + 10 66 43 95 23 1 73 77 68 67 55 65 + 60 41 10 64 67 47 48 19 64 78 87 55 + 48 82 27 96 85 43 16 29 95 36 27 73 + 70 72 16 25 35 47 35 10 21 67 32 53 + 70 97 29 68 79 78 61 58 71 42 12 100 + 64 54 45 29 68 33 20 69 24 85 94 22 + 4 33 53 68 1 79 74 55 12 84 65 11 + 7 11 46 70 61 48 25 43 61 26 48 11 + 32 62 88 7 39 4 92 65 46 62 64 7 + + +x(:,:,2) = + + 41 70 35 74 83 80 52 54 86 62 74 77 + 45 10 15 40 43 95 89 9 57 99 59 59 + 37 53 59 69 89 33 59 12 93 53 25 93 + 77 54 27 71 40 68 16 14 70 48 67 59 + 63 87 5 45 77 44 20 68 59 81 9 2 + 78 49 76 2 40 84 41 50 82 23 63 13 + 94 40 25 34 81 77 75 19 88 50 67 87 + 98 68 45 43 76 17 83 50 99 91 73 49 + 20 75 69 28 38 87 79 15 1 58 90 85 + 14 53 36 20 22 99 32 6 87 85 99 21 + + +x(:,:,3) = + + 56 15 13 95 74 14 56 99 18 92 90 46 + 63 19 50 9 7 4 86 54 36 11 8 11 + 4 5 86 11 87 94 35 71 6 75 25 100 + 62 64 88 15 94 31 45 100 53 74 6 34 + 37 29 28 17 99 30 6 29 34 57 45 30 + 5 54 21 63 86 34 18 42 18 19 2 7 + 49 70 57 58 79 47 67 47 21 60 90 30 + 20 50 65 6 52 65 34 77 91 30 20 5 + 13 54 42 94 18 3 90 82 68 14 10 51 + 21 45 21 73 40 85 12 11 47 22 31 77 + +x>50 + + 10×12×3 logical array + +ans(:,:,1) = + + 0 1 1 1 0 1 0 0 1 0 1 1 + 0 1 0 1 0 0 1 1 1 1 1 1 + 1 0 0 1 1 0 0 0 1 1 1 1 + 0 1 0 1 1 0 0 0 1 0 0 1 + 1 1 0 0 0 0 0 0 0 1 0 1 + 1 1 0 1 1 1 1 1 1 0 0 1 + 1 1 0 0 1 0 0 1 0 1 1 0 + 0 0 1 1 0 1 1 1 0 1 1 0 + 0 0 0 1 1 0 0 0 1 0 0 0 + 0 1 1 0 0 0 1 1 0 1 1 0 + + +ans(:,:,2) = + + 0 1 0 1 1 1 1 1 1 1 1 1 + 0 0 0 0 0 1 1 0 1 1 1 1 + 0 1 1 1 1 0 1 0 1 1 0 1 + 1 1 0 1 0 1 0 0 1 0 1 1 + 1 1 0 0 1 0 0 1 1 1 0 0 + 1 0 1 0 0 1 0 0 1 0 1 0 + 1 0 0 0 1 1 1 0 1 0 1 1 + 1 1 0 0 1 0 1 0 1 1 1 0 + 0 1 1 0 0 1 1 0 0 1 1 1 + 0 1 0 0 0 1 0 0 1 1 1 0 + + +ans(:,:,3) = + + 1 0 0 1 1 0 1 1 0 1 1 0 + 1 0 0 0 0 0 1 1 0 0 0 0 + 0 0 1 0 1 1 0 1 0 1 0 1 + 1 1 1 0 1 0 0 1 1 1 0 0 + 0 0 0 0 1 0 0 0 0 1 0 0 + 0 1 0 1 1 0 0 0 0 0 0 0 + 0 1 1 1 1 0 1 0 0 1 1 0 + 0 0 1 0 1 1 0 1 1 0 0 0 + 0 1 0 1 0 0 1 1 1 0 0 1 + 0 0 0 1 0 1 0 0 0 0 0 1 + +arrayfun(@(varEm) varEm>50, x(:,:,:)) + + 10×12×3 logical array + +ans(:,:,1) = + + 0 1 1 1 0 1 0 0 1 0 1 1 + 0 1 0 1 0 0 1 1 1 1 1 1 + 1 0 0 1 1 0 0 0 1 1 1 1 + 0 1 0 1 1 0 0 0 1 0 0 1 + 1 1 0 0 0 0 0 0 0 1 0 1 + 1 1 0 1 1 1 1 1 1 0 0 1 + 1 1 0 0 1 0 0 1 0 1 1 0 + 0 0 1 1 0 1 1 1 0 1 1 0 + 0 0 0 1 1 0 0 0 1 0 0 0 + 0 1 1 0 0 0 1 1 0 1 1 0 + + +ans(:,:,2) = + + 0 1 0 1 1 1 1 1 1 1 1 1 + 0 0 0 0 0 1 1 0 1 1 1 1 + 0 1 1 1 1 0 1 0 1 1 0 1 + 1 1 0 1 0 1 0 0 1 0 1 1 + 1 1 0 0 1 0 0 1 1 1 0 0 + 1 0 1 0 0 1 0 0 1 0 1 0 + 1 0 0 0 1 1 1 0 1 0 1 1 + 1 1 0 0 1 0 1 0 1 1 1 0 + 0 1 1 0 0 1 1 0 0 1 1 1 + 0 1 0 0 0 1 0 0 1 1 1 0 + + +ans(:,:,3) = + + 1 0 0 1 1 0 1 1 0 1 1 0 + 1 0 0 0 0 0 1 1 0 0 0 0 + 0 0 1 0 1 1 0 1 0 1 0 1 + 1 1 1 0 1 0 0 1 1 1 0 0 + 0 0 0 0 1 0 0 0 0 1 0 0 + 0 1 0 1 1 0 0 0 0 0 0 0 + 0 1 1 1 1 0 1 0 0 1 1 0 + 0 0 1 0 1 1 0 1 1 0 0 0 + 0 1 0 1 0 0 1 1 1 0 0 1 + 0 0 0 1 0 1 0 0 0 0 0 1 + +out = arrayfun(@(var2) arrayfun(@(var1) x(var1,var2,:) > 50, 1:size(x,1)), 1:size(x,2), 'UniformOutput', false) +Error using arrayfun +Non-scalar in Uniform output, at index 1, output 1. +Set 'UniformOutput' to false. + +Error in (var2)arrayfun(@(var1)x(var1,var2,:)>50,1:size(x,1)) + +out = arrayfun(@(var2) arrayfun(@(var1) x(var1,var2,:) > 50, 1:size(x,1), 'UniformOutput', false), 1:size(x,2), 'UniformOutput', false) + +out = + + 1×12 cell array + + Columns 1 through 8 + + {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} + + Columns 9 through 12 + + {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} + +out = cat(1, out{:}) + +out = + + 12×10 cell array + + Columns 1 through 6 + + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + + Columns 7 through 10 + + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} {1×1×3 logical} + +x + +x(:,:,1) = + + 43 54 78 52 26 92 18 27 65 46 59 55 + 10 66 43 95 23 1 73 77 68 67 55 65 + 60 41 10 64 67 47 48 19 64 78 87 55 + 48 82 27 96 85 43 16 29 95 36 27 73 + 70 72 16 25 35 47 35 10 21 67 32 53 + 70 97 29 68 79 78 61 58 71 42 12 100 + 64 54 45 29 68 33 20 69 24 85 94 22 + 4 33 53 68 1 79 74 55 12 84 65 11 + 7 11 46 70 61 48 25 43 61 26 48 11 + 32 62 88 7 39 4 92 65 46 62 64 7 + + +x(:,:,2) = + + 41 70 35 74 83 80 52 54 86 62 74 77 + 45 10 15 40 43 95 89 9 57 99 59 59 + 37 53 59 69 89 33 59 12 93 53 25 93 + 77 54 27 71 40 68 16 14 70 48 67 59 + 63 87 5 45 77 44 20 68 59 81 9 2 + 78 49 76 2 40 84 41 50 82 23 63 13 + 94 40 25 34 81 77 75 19 88 50 67 87 + 98 68 45 43 76 17 83 50 99 91 73 49 + 20 75 69 28 38 87 79 15 1 58 90 85 + 14 53 36 20 22 99 32 6 87 85 99 21 + + +x(:,:,3) = + + 56 15 13 95 74 14 56 99 18 92 90 46 + 63 19 50 9 7 4 86 54 36 11 8 11 + 4 5 86 11 87 94 35 71 6 75 25 100 + 62 64 88 15 94 31 45 100 53 74 6 34 + 37 29 28 17 99 30 6 29 34 57 45 30 + 5 54 21 63 86 34 18 42 18 19 2 7 + 49 70 57 58 79 47 67 47 21 60 90 30 + 20 50 65 6 52 65 34 77 91 30 20 5 + 13 54 42 94 18 3 90 82 68 14 10 51 + 21 45 21 73 40 85 12 11 47 22 31 77 + +x=randi(100,10,12,5) + +x(:,:,1) = + + 64 75 70 55 69 75 79 49 12 11 68 10 + 9 2 56 49 14 24 37 16 79 94 43 1 + 9 5 40 90 73 74 21 79 30 19 46 43 + 78 67 7 80 12 98 9 11 61 27 61 66 + 91 61 79 74 12 87 78 30 97 80 6 73 + 54 53 34 6 65 9 21 24 44 49 32 54 + 11 73 61 8 33 37 39 54 70 77 78 11 + 83 71 75 9 66 37 56 10 76 40 70 64 + 34 79 11 80 75 69 23 41 44 28 13 13 + 30 29 13 95 59 60 65 11 66 4 14 14 + + +x(:,:,2) = + + 10 56 99 16 60 13 76 17 81 3 76 32 + 15 19 18 39 34 3 75 67 75 93 23 82 + 17 22 26 17 30 30 75 90 13 66 7 79 + 20 8 40 76 46 32 11 52 53 94 77 86 + 32 92 8 88 43 66 69 71 33 17 68 51 + 32 71 69 36 36 96 47 16 55 93 72 64 + 22 56 41 69 56 94 22 96 40 80 65 96 + 26 32 99 30 75 46 10 55 42 58 42 45 + 90 17 41 54 43 25 83 68 19 45 40 7 + 71 63 63 84 43 77 18 4 26 26 82 87 + + +x(:,:,3) = + + 64 19 23 63 28 99 14 95 42 36 79 23 + 36 73 38 3 25 7 22 68 61 98 70 27 + 100 38 9 92 46 94 19 99 76 35 1 68 + 23 85 65 81 23 2 5 77 59 89 85 48 + 66 74 19 75 81 69 11 34 56 46 93 63 + 61 58 5 82 99 79 62 67 59 42 78 24 + 39 18 73 39 3 54 94 25 52 22 5 18 + 15 96 35 62 54 89 36 30 9 13 38 83 + 3 27 67 58 9 90 42 69 72 31 71 77 + 43 93 39 54 81 63 99 53 100 73 73 94 + + +x(:,:,4) = + + 11 32 51 72 84 50 29 72 51 59 41 94 + 19 18 44 62 33 70 24 86 49 68 13 40 + 10 34 100 35 56 98 72 29 88 37 27 5 + 49 22 82 94 98 33 63 74 36 63 26 35 + 20 52 49 13 55 84 60 14 45 82 34 74 + 90 91 90 74 34 74 67 84 97 2 16 80 + 10 63 14 65 62 96 5 14 5 9 35 55 + 5 11 40 84 37 4 35 59 98 98 13 69 + 56 40 93 40 76 36 46 37 19 66 89 90 + 78 6 92 75 42 67 25 81 67 24 10 6 + + +x(:,:,5) = + + 31 29 51 3 95 83 41 39 46 28 58 12 + 5 55 65 56 55 85 67 46 21 72 33 82 + 20 99 31 31 73 38 94 25 90 29 46 33 + 73 72 14 94 58 60 82 79 77 90 72 25 + 73 84 48 99 3 88 49 89 89 83 89 35 + 88 44 37 29 45 94 76 92 29 40 73 38 + 59 48 79 81 65 67 42 56 68 50 2 55 + 8 57 79 90 53 21 98 60 67 70 68 57 + 93 27 67 60 38 66 99 15 13 84 44 40 + 81 75 14 89 94 8 87 90 41 61 44 40 + +out = arrayfun(@(var2) arrayfun(@(var1) sum(x(var1,var2,1:2:end),3), 1:size(x,1), 'UniformOutput', false), 1:size(x,2), 'UniformOutput', false) + +out = + + 1×12 cell array + + {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} {1×10 cell} + +out = arrayfun(@(var2) arrayfun(@(var1) sum(x(var1,var2,1:2:end),3), 1:size(x,1)), 1:size(x,2)) +Error using arrayfun +Non-scalar in Uniform output, at index 1, output 1. +Set 'UniformOutput' to false. + +out = arrayfun(@(var2) arrayfun(@(var1) sum(x(var1,var2,1:2:end),3), 1:size(x,1)), 1:size(x,2),'UniformOutput',false) + +out = + + 1×12 cell array + + {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} + +out = cat(2, out{:}) + +out = + + Columns 1 through 35 + + 159 50 129 174 230 203 109 106 130 154 123 130 142 224 219 155 139 224 133 197 144 159 80 86 146 76 213 189 145 66 121 108 213 255 248 + + Columns 36 through 70 + + 117 128 161 198 238 192 94 192 93 96 209 101 173 122 234 257 116 206 160 244 182 158 147 225 131 134 126 134 96 138 159 175 190 164 251 + + Columns 71 through 105 + + 183 130 203 167 153 183 135 100 125 154 100 161 196 197 242 132 190 152 129 207 75 264 83 206 209 131 149 123 143 138 205 146 93 218 188 + + Columns 106 through 120 + + 183 85 176 128 131 45 110 144 139 171 116 84 204 130 148 + +out = cat(1, out{:}) +Brace indexing is not supported for variables of this type. + +out = arrayfun(@(var2) arrayfun(@(var1) sum(x(var1,var2,1:2:end),3), 1:size(x,1)), 1:size(x,2),'UniformOutput',false) + +out = + + 1×12 cell array + + {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} {1×10 double} + +out = cat(1, out{:}) + +out = + + 159 50 129 174 230 203 109 106 130 154 + 123 130 142 224 219 155 139 224 133 197 + 144 159 80 86 146 76 213 189 145 66 + 121 108 213 255 248 117 128 161 198 238 + 192 94 192 93 96 209 101 173 122 234 + 257 116 206 160 244 182 158 147 225 131 + 134 126 134 96 138 159 175 190 164 251 + 183 130 203 167 153 183 135 100 125 154 + 100 161 196 197 242 132 190 152 129 207 + 75 264 83 206 209 131 149 123 143 138 + 205 146 93 218 188 183 85 176 128 131 + 45 110 144 139 171 116 84 204 130 148 + +size(out) + +ans = + + 12 10 + +size(x) + +ans = + + 10 12 5 + +size(out) + +ans = + + 12 10 + +out = arrayfun(@(var2) arrayfun(@(var1) sum(x(var1,var2,1:2:end),3), 1:size(x,1), 'UniformOutput', false), 1:size(x,2), 'UniformOutput', false) \ No newline at end of file diff --git a/Jesus/whiskerScBehavior.m b/Jesus/whiskerScBehavior.m index 455959a..dfa2afc 100644 --- a/Jesus/whiskerScBehavior.m +++ b/Jesus/whiskerScBehavior.m @@ -20,7 +20,7 @@ zz=[AsocPos1 AsocPos1]; zsczz(1:size(AsocPos1,1),i)=AsocPos1;%zscore(AsocPos1); AsocPosAll(:,i)=AsocPos1; -sp=[deeplabcut.speed deeplabcut.speed]; +%sp=[deeplabcut.speed deeplabcut.speed]; %idj1=AsocPos1>2; end figure From 02f8231649f8875f62cf0e2f148ae448253af73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 12 Apr 2023 18:42:41 +0200 Subject: [PATCH 008/201] Maximum distance from the median --- Emilio/AKK/getMaxAbsPerTrial.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Emilio/AKK/getMaxAbsPerTrial.m b/Emilio/AKK/getMaxAbsPerTrial.m index 217082e..0ba1c99 100644 --- a/Emilio/AKK/getMaxAbsPerTrial.m +++ b/Emilio/AKK/getMaxAbsPerTrial.m @@ -23,8 +23,9 @@ responseFlags = xor(responseFlags(:,1), responseFlags(:,2)); % mavpt = max(abs(inStack(responseFlags, :)-median(inStack,1))); -[~, ps] = max(abs(inStack(responseFlags,:) - median(inStack(timeAxis<0,:),1))); -mavpt = arrayfun(@(mp, tr) ... - inStack(find(responseFlags,1,'first')+mp-1, tr), ps(:), (1:Ntg)'); +[mavpt, ps] = max(abs(inStack(responseFlags,:) - ... + median(inStack(timeAxis<0,:),1))); +% mavpt = arrayfun(@(mp, tr) ... +% inStack(find(responseFlags,1,'first')+mp-1, tr), ps(:), (1:Ntg)'); mxT = timeAxis(ps+find(responseFlags,1,"first")-1); end \ No newline at end of file From 780a4526353fc400e469172bc7013f7eaf791e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 13 Apr 2023 18:29:53 +0200 Subject: [PATCH 009/201] Saving the behIndex in the figure --- Jesus/DE_Jittering.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 8068888..fe2e8fa 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -873,6 +873,7 @@ biFigPttrn = sprintf(biFigPttrn, sprintf(" %s (%%.3f)", consCondNames)); [pAreas, ~, behAreaFig] = createBehaviourIndex(behRes); behRes = arrayfun(@(bs, ba) setfield(bs,'BehIndex', ba), behRes, pAreas); + set(behAreaFig, 'UserData', behRes) biFN = sprintf(biFigPttrn, pAreas); saveFigure(behAreaFig, fullfile(behFigDir, biFN), true); From 2cbf4a09708d3b3311f75bdb5d81d2aa950e83e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 20 Apr 2023 13:27:10 +0200 Subject: [PATCH 010/201] Create muscimol_analysis.m --- Emilio/muscimol_analysis.m | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Emilio/muscimol_analysis.m diff --git a/Emilio/muscimol_analysis.m b/Emilio/muscimol_analysis.m new file mode 100644 index 0000000..ddff129 --- /dev/null +++ b/Emilio/muscimol_analysis.m @@ -0,0 +1,28 @@ +fullName = @(x) string(fullfile(x.folder, x.name)); +fnOpts = {'UniformOutput', false}; +%% +expDir = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch2_ephys\MC\WT13\211119_C"; +behDirs = dir(fullfile(expDir, "Beh*")); behDir = fullName(behDirs); +%% +ephDirs = dir(fullfile(expDir, "ephys_*")); ephDir = fullName(ephDirs); +condFiles = dir(fullfile(ephDir, "*analysis.mat")); +load(fullName(condFiles), "Conditions", "fs") +%% +ccSub = find(arrayfun(@(c) contains(c.name, ["Control Puff", "Delay"], ... + "IgnoreCase", true), Conditions)); + +pairedStim = arrayfun(@(x) Conditions(1).Triggers(:,1) == ... + Conditions(x).Triggers(:,1)', ccSub, fnOpts{:}); +pairedStim = cellfun(@(x) any(x, 2), pairedStim, fnOpts{:}); +pairedStim = cat(2, pairedStim{:}); +consCondNames = arrayfun(@(x) string(x.name), Conditions(ccSub)); +%% +[behRes, behFigDir] = analyseBehaviour(behDir, 'PairedFlags', pairedStim, ... + 'ConditionsNames', cellstr(consCondNames)); +biFigPttrn = "BehIndex%s"; +biFigPttrn = sprintf(biFigPttrn, sprintf(" %s (%%.3f)", consCondNames)); +[pAreas, ~, behAreaFig] = createBehaviourIndex(behRes); +behRes = arrayfun(@(bs, ba) setfield(bs,'BehIndex', ba), behRes, pAreas); +set(behAreaFig, 'UserData', behRes) +biFN = sprintf(biFigPttrn, pAreas); +saveFigure(behAreaFig, fullfile(behFigDir, biFN), true); \ No newline at end of file From 3069c8e81fb2f170351202ca063ad50b78afe348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 25 Apr 2023 14:48:03 +0200 Subject: [PATCH 011/201] Create poolBehIndices.m --- Emilio/poolBehIndices.m | 57 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Emilio/poolBehIndices.m diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m new file mode 100644 index 0000000..cc0c58f --- /dev/null +++ b/Emilio/poolBehIndices.m @@ -0,0 +1,57 @@ +%#ok<*AGROW,*SAGROW> +fnOpts = {'UniformOutput', false}; +expandName = @(x) fullfile(x.folder, x.name); + +batchDir = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch11_ephys.MC"; + +animalDirs = dir(batchDir); +pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), animalDirs); +nonAnFlag = arrayfun(@(x) isempty(regexp(x.name, ... + '[a-zA-Z]+[0-9]+\S','match')), animalDirs); +animalDirs(pointFlag | nonAnFlag) = []; +oldMouse = ""; +mc = 0; mice = []; +for cad = animalDirs(:)' + currMouse = cad.name; + if string(oldMouse) ~= string(currMouse) + oldMouse = currMouse; + mice = [mice; struct('Name', currMouse, 'Sessions',[])]; + mc = mc + 1; + sc = 0; oldSess = ""; + end + sessDirs = getSubFolds(expandName(cad)); + % Just date sessions + onlyDateSessFlag = regexp(arrayfun(@(x) string(x.name), sessDirs), ... + '[0-9]{6}', 'match'); + sessDirs(isempty(onlyDateSessFlag)) = []; + for csd = sessDirs(:)' + currSess = csd.name; + behFigDir = recursiveFolderSearch(expandName(csd),... + "Beh V-0.25 - 0.50 s R5.00 - 400.00 ms"); + behIdxFiles = dir(fullfile(behFigDir, "BehIndex*.fig")); + if numel(behIdxFiles) == 1 + behIdxFig = openfig(expandName(behIdxFiles), 'invisible'); + elseif numel(behIdxFiles) > 1 + fprintf(1, "Found more than 1 file! Taking the first.\n") + behIdxFig = openfig(expandName(behIdxFiles(1)), 'invisible'); + else + fprintf(1, "Found no BehIndex figure!\n") + continue + end + behRes = get(behIdxFig, 'UserData'); close(behIdxFig) + consCondNames = arrayfun(@(x) string(x.ConditionName), behRes); + ctrFlag = contains(consCondNames, 'control','IgnoreCase',true); + mscFlag = contains(consCondNames, 'muscimol','IgnoreCase',true); + if string(oldSess) ~= string(currSess) + oldSess = currSess; auxStruct = struct('Date', currSess, ... + 'Control', behRes(ctrFlag).BehIndex, ... + 'Muscimol', behRes(mscFlag).BehIndex); + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + sc = sc + 1; + end + end +end \ No newline at end of file From 5fc574e1d133d75fdf37a93005c60edf68000442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 8 May 2023 18:17:24 +0200 Subject: [PATCH 012/201] Pooling behaviour results Added the recursive search for the animal folders. --- Emilio/poolBehIndices.m | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index cc0c58f..554cf98 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -1,29 +1,36 @@ %#ok<*AGROW,*SAGROW> +%% Auxiliary variables and functions fnOpts = {'UniformOutput', false}; expandName = @(x) fullfile(x.folder, x.name); - +animalPattern = '[A-Za-z]+\d{2,}'; +rsOpts = {animalPattern, 'SearchType', 'expression'}; +ctOpts = {'IgnoreCase', true}; +%% Assuming 1 level of animal organisation i.e. +% BatchX/FolderA/Animal001 +% BatchX/FolderB/Animal002 batchDir = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch11_ephys.MC"; +childFolders = dir(batchDir); -animalDirs = dir(batchDir); -pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), animalDirs); -nonAnFlag = arrayfun(@(x) isempty(regexp(x.name, ... - '[a-zA-Z]+[0-9]+\S','match')), animalDirs); -animalDirs(pointFlag | nonAnFlag) = []; +pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), childFolders); +childFolders(pointFlag) = []; +animalFolders = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... + rsOpts{:}), childFolders, fnOpts{:}); animalFolders = cat(1, animalFolders{:}); +%% Looping animals oldMouse = ""; mc = 0; mice = []; -for cad = animalDirs(:)' - currMouse = cad.name; +for cad = animalFolders(:)' + [~, currMouse] = fileparts(cad); if string(oldMouse) ~= string(currMouse) oldMouse = currMouse; mice = [mice; struct('Name', currMouse, 'Sessions',[])]; mc = mc + 1; sc = 0; oldSess = ""; end - sessDirs = getSubFolds(expandName(cad)); + sessDirs = getSubFolds(cad); % Just date sessions - onlyDateSessFlag = regexp(arrayfun(@(x) string(x.name), sessDirs), ... - '[0-9]{6}', 'match'); - sessDirs(isempty(onlyDateSessFlag)) = []; + onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... + 'match')), sessDirs, fnOpts{:}); + sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; for csd = sessDirs(:)' currSess = csd.name; behFigDir = recursiveFolderSearch(expandName(csd),... @@ -40,12 +47,13 @@ end behRes = get(behIdxFig, 'UserData'); close(behIdxFig) consCondNames = arrayfun(@(x) string(x.ConditionName), behRes); - ctrFlag = contains(consCondNames, 'control','IgnoreCase',true); - mscFlag = contains(consCondNames, 'muscimol','IgnoreCase',true); + % TODO: fix the condition names and run the loop + ctrFlag = contains(consCondNames, 'control', ctOpts{:}); + delFlag = contains(consCondNames, 'delay', ctOpts{:}); if string(oldSess) ~= string(currSess) oldSess = currSess; auxStruct = struct('Date', currSess, ... 'Control', behRes(ctrFlag).BehIndex, ... - 'Muscimol', behRes(mscFlag).BehIndex); + 'Muscimol', behRes(delFlag).BehIndex); if ~isfield(mice, 'Sessions') mice(mc).Sessions = auxStruct; else From b5d48c6b5875cdf1403106259b8558dad3166d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 9 May 2023 17:31:28 +0200 Subject: [PATCH 013/201] More than one behRes for the session --- Emilio/poolBehIndices.m | 46 ++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 554cf98..e89a7fd 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -5,6 +5,7 @@ animalPattern = '[A-Za-z]+\d{2,}'; rsOpts = {animalPattern, 'SearchType', 'expression'}; ctOpts = {'IgnoreCase', true}; +lsOpts = {'L\d+.\d+', 'match'}; %% Assuming 1 level of animal organisation i.e. % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 @@ -32,28 +33,53 @@ 'match')), sessDirs, fnOpts{:}); sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; for csd = sessDirs(:)' - currSess = csd.name; - behFigDir = recursiveFolderSearch(expandName(csd),... + ephDir = expandName(dir(fullfile(expandName(csd), 'ephys*'))); + if isempty(ephDir) + fprintf(1, "This session didn't have ephys!\n") + fprintf(1, "Skipping\n") + continue + end + currSess = char(regexp(csd.name, '\d{6}', 'match')); + behFigDir = recursiveFolderSearch(ephDir,... "Beh V-0.25 - 0.50 s R5.00 - 400.00 ms"); behIdxFiles = dir(fullfile(behFigDir, "BehIndex*.fig")); - if numel(behIdxFiles) == 1 - behIdxFig = openfig(expandName(behIdxFiles), 'invisible'); - elseif numel(behIdxFiles) > 1 - fprintf(1, "Found more than 1 file! Taking the first.\n") - behIdxFig = openfig(expandName(behIdxFiles(1)), 'invisible'); - else + behIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... + behIdxFiles); + behRes = arrayfun(@(x) get(x, 'UserData'), behIdxFig, fnOpts{:}); + brSz = cellfun(@numel, behRes); c = 1; + if numel(behIdxFiles) > 1 + fprintf(1, "Found more than 1 file! Estimating the correct\n") + Ncond = arrayfun(@(m) arrayfun(@(s) numel(fieldnames(s))-1, ... + m.Sessions), mice, fnOpts{:}); Ncond = cat(1, Ncond{:}); + [~, whr] = min(Ncond - brSz',[],"all"); + if std(brSz) + [~, c] = ind2sub([numel(Ncond), numel(brSz)], whr); + else + posCCN = cellfun(@(bc) arrayfun(@(bs) ... + string(bs.ConditionName), bc), behRes, fnOpts{:}); + c = cellfun(@(nms) any(contains(nms, 'delay', ctOpts{:})), posCCN); + end + fprintf(1, "Chose the following conditions:\n") + fprintf(1, " - %s\n", arrayfun(@(x) string(x.ConditionName), ... + behRes{c})) + elseif isempty(behIdxFig) fprintf(1, "Found no BehIndex figure!\n") continue end - behRes = get(behIdxFig, 'UserData'); close(behIdxFig) + behRes = behRes{c}; + arrayfun(@close, behIdxFig) consCondNames = arrayfun(@(x) string(x.ConditionName), behRes); % TODO: fix the condition names and run the loop ctrFlag = contains(consCondNames, 'control', ctOpts{:}); delFlag = contains(consCondNames, 'delay', ctOpts{:}); + frqFlag = ~cellfun(@isempty,regexp(consCondNames, lsOpts{:})); if string(oldSess) ~= string(currSess) oldSess = currSess; auxStruct = struct('Date', currSess, ... 'Control', behRes(ctrFlag).BehIndex, ... - 'Muscimol', behRes(delFlag).BehIndex); + 'Laser_continuous', behRes(xor(delFlag,frqFlag)).BehIndex); + if any(frqFlag) + auxStruct.Laser_freq = behRes(frqFlag).BehIndex; + end if ~isfield(mice, 'Sessions') mice(mc).Sessions = auxStruct; else From b44ba55253f756038d27d6e85a6b518e3dec0ac8 Mon Sep 17 00:00:00 2001 From: Ross Folkard Date: Thu, 11 May 2023 18:27:53 +0200 Subject: [PATCH 014/201] Create PoolDifMech.m --- Ross/PoolDifMech.m | 255 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 Ross/PoolDifMech.m diff --git a/Ross/PoolDifMech.m b/Ross/PoolDifMech.m new file mode 100644 index 0000000..82b1ebe --- /dev/null +++ b/Ross/PoolDifMech.m @@ -0,0 +1,255 @@ +%% PoolDifMech + +clear +close all +clc +%% +dataDirs = { + '\\lsdf02.urz.uni-heidelberg.de\sd19b001\PainData\Corrected_Channel_Map\VPL\1.8.22\KS3__Nblocks2__9_9__0pt9__20\' + '\\lsdf02.urz.uni-heidelberg.de\sd19b001\PainData\Corrected_Channel_Map\VPL\4.8.22\KS3__Nblocks2__9_9__0pt9__20\' + '\\lsdf02.urz.uni-heidelberg.de\sd19b001\PainData\Corrected_Channel_Map\VPL\8.8.22\DifMech\VPL_E1_KS3__Nblocks2__9_9__0pt9__20\' + }; + +selUnitDirs = { + '\\lsdf02.urz.uni-heidelberg.de\sd19b001\PainData\Corrected_Channel_Map\VPL\1.8.22\KS3__Nblocks2__9_9__0pt9__20\m51_ECE_Processing_-10-to-10\PopulationAnalysis\SelectedUnitData.mat' + '\\lsdf02.urz.uni-heidelberg.de\sd19b001\PainData\Corrected_Channel_Map\VPL\4.8.22\KS3__Nblocks2__9_9__0pt9__20\m50_ECE_Processing_-10-to-10\PopulationAnalysis\SelectedUnitData.mat' + '\\lsdf02.urz.uni-heidelberg.de\sd19b001\PainData\Corrected_Channel_Map\VPL\8.8.22\DifMech\VPL_E1_KS3__Nblocks2__9_9__0pt9__20\m53_VPL_E1_DifMech_ECE_Processing_-10-to-10\PopulationAnalysis\SelectedUnitData.mat' + }; + + +%% variables to be collected + +discStacks = []; +csts = []; +Data = []; + +%% collecting trial numbers early +chCond = 1; +nExpts = size(dataDirs, 1); +trialnumbers = []; +for cexpt = 1:nExpts + dataDir = dataDirs{cexpt}; + Conditions = dir([dataDir, '*analysis*.mat']); + [r, ~] = size(Conditions); + if r ~= 1 + fprintf(['multiple or no analysis files in directory...\n' ... + 'choose one \n']) + return + end + load([dataDir, Conditions.name]); + trialnumbers = [trialnumbers, size(Conditions(1).Triggers,chCond)]; +end + +constrials = min(trialnumbers); +%% User controlling variables +% Time lapse, bin size, and spontaneous and response windows +promptStrings = {'Viewing window (time lapse) [s]:','Response window [s]',... + 'Bin size [s]:'}; +defInputs = {'-2, 6', '0.1, 5', '0.01'}; +answ = inputdlg(promptStrings,'Inputs', [1, 30],defInputs); +if isempty(answ) + fprintf(1,'Cancelling...\n'); + return +else + timeLapse = str2num(answ{1}); %#ok<*ST2NM> + if numel(timeLapse) ~= 2 + timeLapse = str2num(inputdlg('Please provide the time window [s]:',... + 'Time window',[1, 30], '-0.1, 0.1')); + if isnan(timeLapse) || isempty(timeLapse) + fprintf(1,'Cancelling...') + return + end + end + responseWindow = str2num(answ{2}); + binSz = str2double(answ(3)); +end +fprintf(1,'Time window: %.2f - %.2f ms\n',timeLapse(1)*1e3, timeLapse(2)*1e3) +fprintf(1,'Response window: %.2f - %.2f ms\n',responseWindow(1)*1e3, responseWindow(2)*1e3) +fprintf(1,'Bin size: %.3f ms\n', binSz*1e3) +sponAns = questdlg('Mirror the spontaneous window?','Spontaneous window',... + 'Yes','No','Yes'); +spontaneousWindow = -flip(responseWindow); +if strcmpi(sponAns,'No') + spontPrompt = "Time before the trigger in [s] (e.g. -0.8, -0.6 s)"; + sponDef = string(sprintf('%.3f, %.3f',spontaneousWindow(1),... + spontaneousWindow(2))); + sponStr = inputdlg(spontPrompt, 'Inputs',[1,30],sponDef); + if ~isempty(sponStr) + spontAux = str2num(sponStr{1}); + if length(spontAux) ~= 2 || spontAux(1) > spontAux(2) || ... + spontAux(1) < timeLapse(1) + fprintf(1, 'The given input was not valid.\n') + fprintf(1, 'Keeping the mirror version!\n') + else + spontaneousWindow = spontAux; + end + end +end +fprintf(1,'Spontaneous window: %.2f to %.2f ms before the trigger\n',... + spontaneousWindow(1)*1e3, spontaneousWindow(2)*1e3) + + + + +%% loading variables for a given experiment - Starting the for-loop + +for cexpt = 1:nExpts + dataDir = dataDirs{cexpt}; + selUnits = selUnitDirs{cexpt}; + + Conditions = dir([dataDir, '*analysis*.mat']); + [r, ~] = size(Conditions); + if r ~= 1 + fprintf(['multiple or no analysis files in directory...\n' ... + 'choose one \n']) + return + end + load([dataDir, Conditions.name]); + + % homogenising trial numbers + Conditions(chCond).Triggers = Conditions(chCond).Triggers(1:constrials,:); + + + sortedData = dir([dataDir, '*all_channels*.mat']); + [r, ~] = size(sortedData); + if r ~= 1 + fprintf(['multiple or no all_channels files in directory...\n' ... + 'choose one \n']) + return + end + load([dataDir, sortedData.name]); + + clInfo = getClusterInfo([dataDir filesep 'cluster_info.tsv']); + + expID = dir([dataDir, '*expParams*.mat']); + [r, ~] = size(expID); + if r ~= 1 + fprintf(['multiple or no expParams files in directory...\n']) + return + end + load([dataDir, expID.name], 'expID'); + + load(selUnits, 'unit_ids') + + + %% renaming units to avoid confusion + + + for i = 1:length(sortedData) + sortedData{i,1} = [expID, '_unit_', sortedData{i,1}]; + end + + for i = 1:height(clInfo) + clInfo.id{i,1} = [expID, '_unit_', clInfo.id{i,1}]; + clInfo.Properties.RowNames{i,1} = clInfo.id{i,1}; + end + + for i = 1:length(unit_ids) + unit_ids{i} = [expID, '_unit_', unit_ids{i,1}]; + end + + + + %% global variables + + goods = find(ismember(sortedData(:,1), unit_ids)); + + Triggers.MechStim = Triggers.MechStim * -1; + + % Number of total samples + Ns = min(structfun(@numel,Triggers)); + % Total duration of the recording + Nt = Ns/fs; + + gclID = sortedData(goods,1); + % Logical spike trace for the first good cluster + spkLog = StepWaveform.subs2idx(round(sortedData{goods(1),2}*fs),Ns); + % Subscript column vectors for the rest good clusters + spkSubs = cellfun(@(x) round(x.*fs),sortedData(goods(2:end),2),... + 'UniformOutput',false); + % Number of good clusters + Ncl = numel(goods); + % Redefining the stimulus signals from the low amplitude to logical values + whStim = {'piezo','whisker','mech','audio'}; + cxStim = {'laser','light'}; + lfpRec = {'lfp','s1','cortex','s1lfp'}; + trigNames = fieldnames(Triggers); + numTrigNames = numel(trigNames); + ctn = 1; + continuousSignals = cell(numTrigNames,1); + continuousNameSub = zeros(size(trigNames)); + while ctn <= numTrigNames + if contains(trigNames{ctn},whStim,'IgnoreCase',true) + continuousSignals{ctn} = Triggers.(trigNames{ctn}); + continuousNameSub(ctn) = ctn; + end + if contains(trigNames{ctn},cxStim,'IgnoreCase',true) + continuousSignals{ctn} = Triggers.(trigNames{ctn}); + continuousNameSub(ctn) = ctn; + end + if contains(trigNames{ctn},lfpRec,'IgnoreCase',true) + continuousSignals{ctn} = Triggers.(trigNames{ctn}); + continuousNameSub(ctn) = ctn; + end + ctn = ctn + 1; + end + continuousSignals(continuousNameSub == 0) = []; + continuousNameSub(continuousNameSub == 0) = []; + trigNames = trigNames(continuousNameSub); + + + + Data = [Data; clInfo(:,1:13)]; + + %% Constructing the stack out of the user's choice + + + onOffStr = 'on'; + + % discStack - dicrete stack has a logical nature + % cst - continuous stack has a numerical nature + % Both of these stacks have the same number of time samples and trigger + % points. They differ only in the number of considered events. + + [discStack, cst] = getStacks(spkLog,Conditions(chCond).Triggers,onOffStr,... + timeLapse,fs,fs,spkSubs,continuousSignals); + nTrials = size(discStack, 3); + if cexpt == 1 + nTrialsStacks = size(discStack, 3); + end + + + tic + while nTrials > nTrialsStacks + discStack(:,:,end) = []; + end + toc + + + tic + while nTrials < nTrialsStacks + discStacks(:,:,end) = []; + end + toc + + discStacks = cat(1, discStacks, discStack); + csts = cat(3, csts, cst); +end + +discStack = discStacks; clear discStacks +[Ne, Nt, NTa] = size(discStacks); +% Computing the time axis for the stack +tx = (0:Nt - 1)/fs + timeLapse(1); + + +consideredConditions = find(~ismember(1:length(Conditions), chCond)); + +%% Boolean flags +delayFlags = false(NTa,Nccond); +counter2 = 1; +for ccond = consideredConditions + delayFlags(:,counter2) = ismember(Conditions(chCond).Triggers(:,1),... + Conditions(ccond).Triggers(:,1)); + counter2 = counter2 + 1; +end +Na = sum(delayFlags,1); \ No newline at end of file From bef5be56a5b31cf8aa22599b1d03b1815baa2cba Mon Sep 17 00:00:00 2001 From: Ross Folkard Date: Fri, 12 May 2023 10:52:34 +0200 Subject: [PATCH 015/201] Homogenising DiscStack and cst across experiments --- Ross/PoolDifMech.m | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Ross/PoolDifMech.m b/Ross/PoolDifMech.m index 82b1ebe..0239f0c 100644 --- a/Ross/PoolDifMech.m +++ b/Ross/PoolDifMech.m @@ -213,27 +213,29 @@ [discStack, cst] = getStacks(spkLog,Conditions(chCond).Triggers,onOffStr,... timeLapse,fs,fs,spkSubs,continuousSignals); - nTrials = size(discStack, 3); if cexpt == 1 - nTrialsStacks = size(discStack, 3); + nTriggerscst = size(cst, 1); end - tic - while nTrials > nTrialsStacks - discStack(:,:,end) = []; + + while size(cst, 1) > nTriggerscst + cst(end,:,:) = []; end - toc - tic - while nTrials < nTrialsStacks - discStacks(:,:,end) = []; + + + while size(cst, 1) < nTriggerscst + csts(end,:,:) = []; end - toc + + tic discStacks = cat(1, discStacks, discStack); - csts = cat(3, csts, cst); + toc + csts = cat(1, csts, cst); + end discStack = discStacks; clear discStacks From 58eaead0d5efb7271768a40e3477bdb9765c39c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 12 May 2023 18:17:26 +0200 Subject: [PATCH 016/201] Generalised result pooling --- Emilio/poolBehIndices.m | 150 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 137 insertions(+), 13 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index e89a7fd..0b84144 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -2,10 +2,12 @@ %% Auxiliary variables and functions fnOpts = {'UniformOutput', false}; expandName = @(x) fullfile(x.folder, x.name); -animalPattern = '[A-Za-z]+\d{2,}'; +animalPattern = '[A-Za-z]+\d{1,}'; rsOpts = {animalPattern, 'SearchType', 'expression'}; ctOpts = {'IgnoreCase', true}; lsOpts = {'L\d+.\d+', 'match'}; +behFF = "Beh V-0.25 - 0.50 s R5.00 - 400.00 ms"; +tblOpts = {'VariableNames', {'Conditions', 'BehaviourIndices'}}; %% Assuming 1 level of animal organisation i.e. % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 @@ -13,7 +15,8 @@ childFolders = dir(batchDir); pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), childFolders); -childFolders(pointFlag) = []; +fileFlag = ~[childFolders.isdir]'; +childFolders(pointFlag | fileFlag) = []; animalFolders = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... rsOpts{:}), childFolders, fnOpts{:}); animalFolders = cat(1, animalFolders{:}); %% Looping animals @@ -33,20 +36,81 @@ 'match')), sessDirs, fnOpts{:}); sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; for csd = sessDirs(:)' - ephDir = expandName(dir(fullfile(expandName(csd), 'ephys*'))); + curDir = expandName(csd); + currSess = char(regexp(csd.name, '\d{6}', 'match')); + childFolders = getSubFolds(curDir); + sessOrgDirs = arrayfun(@(d) string(d.name), childFolders); + sessOrgDirs(contains(sessOrgDirs, {'behaviour', 'ephys', 'figures'}, ... + ctOpts{:})) = []; + behFigDir = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... + behFF), childFolders, fnOpts{:}); behFigDir = cat(1, behFigDir{:}); + %{ if isempty(ephDir) fprintf(1, "This session didn't have ephys!\n") fprintf(1, "Skipping\n") continue + else + behFigDir = recursiveFolderSearch(ephDir,... + "Beh V-0.25 - 0.50 s R5.00 - 400.00 ms"); end - currSess = char(regexp(csd.name, '\d{6}', 'match')); - behFigDir = recursiveFolderSearch(ephDir,... - "Beh V-0.25 - 0.50 s R5.00 - 400.00 ms"); - behIdxFiles = dir(fullfile(behFigDir, "BehIndex*.fig")); + ephDir = expandName(ephDir); + %} + behIdxFiles = arrayfun(@(d) dir(fullfile(d, "BehIndex*.fig")), behFigDir); behIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... - behIdxFiles); - behRes = arrayfun(@(x) get(x, 'UserData'), behIdxFig, fnOpts{:}); - brSz = cellfun(@numel, behRes); c = 1; + behIdxFiles); behRes = arrayfun(@(x) get(x, 'UserData'), ... + behIdxFig, fnOpts{:}); arrayfun(@close, behIdxFig) + condNames = cellfun(@(x) arrayfun(@(y) string(y.ConditionName), x), ... + behRes, fnOpts{:}); behIdx = cellfun(@(x) arrayfun(@(y) ... + y.BehIndex, x), behRes, fnOpts{:}); + brSz = cellfun(@numel, behRes); c = 1; Nbix = numel(brSz); + sessType = 'single'; + if Nbix == 1 + dataTable = table([condNames{:}]', [behIdx{:}]', tblOpts{:}); + elseif Nbix > 1 + % We need to check where are all of these different + % measurements are coming from. + sessType = 'multi'; + if numel(sessOrgDirs) == Nbix + % Same folders and measurements. Ideal situation for + % several measurements. + dataTable = table(condNames, behIdx, tblOpts{:}, ... + 'RowNames', sessOrgDirs); + else + dataTable = table(condNames, behIdx, tblOpts{:}); + end + end + if string(oldSess) ~= string(currSess) + oldSess = currSess; + auxStruct = struct('Date', currSess, ... + 'DataTable', dataTable, 'Type', sessType); + %{ + if any(xor(delFlag, frqFlag)) + auxStruct.Laser_continuous = behRes(xor(delFlag, ... + frqFlag)).BehIndex; + end + if any(frqFlag) + auxStruct.Laser_freq = behRes(frqFlag).BehIndex; + end + if any(musFlag) + auxStruct.Muscimol = behRes(musFlag).BehIndex; + end + if any(ptxFlag) + auxStruct.PTX = behRes(ptxFlag).BehIndex; + end + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + %} + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + sc = sc + 1; + end + %{ if numel(behIdxFiles) > 1 fprintf(1, "Found more than 1 file! Estimating the correct\n") Ncond = arrayfun(@(m) arrayfun(@(s) numel(fieldnames(s))-1, ... @@ -73,13 +137,24 @@ ctrFlag = contains(consCondNames, 'control', ctOpts{:}); delFlag = contains(consCondNames, 'delay', ctOpts{:}); frqFlag = ~cellfun(@isempty,regexp(consCondNames, lsOpts{:})); + musFlag = contains(consCondNames, 'muscimol', ctOpts{:}); + ptxFlag = contains(consCondNames, 'ptx', ctOpts{:}); if string(oldSess) ~= string(currSess) oldSess = currSess; auxStruct = struct('Date', currSess, ... - 'Control', behRes(ctrFlag).BehIndex, ... - 'Laser_continuous', behRes(xor(delFlag,frqFlag)).BehIndex); + 'Control', behRes(ctrFlag).BehIndex); + if any(xor(delFlag, frqFlag)) + auxStruct.Laser_continuous = behRes(xor(delFlag, ... + frqFlag)).BehIndex; + end if any(frqFlag) auxStruct.Laser_freq = behRes(frqFlag).BehIndex; end + if any(musFlag) + auxStruct.Muscimol = behRes(musFlag).BehIndex; + end + if any(ptxFlag) + auxStruct.PTX = behRes(ptxFlag).BehIndex; + end if ~isfield(mice, 'Sessions') mice(mc).Sessions = auxStruct; else @@ -87,5 +162,54 @@ end sc = sc + 1; end + %} end -end \ No newline at end of file +end +%% +jittDist = makedist('Normal', 'mu', 0, 'sigma', 1/9); +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +habTable = arrayfun(@(m, f) {m.Sessions(f{:}).DataTable}, mice, habFlag, ... + fnOpts{:}); +pBehIdx = cellfun(@(x) cellfun(@(y) cell2mat(y.BehaviourIndices), x, ... + fnOpts{:}), habTable, fnOpts{:}); +Ncc = cellfun(@(x) cellfun(@(y) numel(y), x), pBehIdx, fnOpts{:}); +rSz = cellfun(@(x) max(cellfun(@(y) numel(y), x)), pBehIdx); +cSz = cellfun(@numel, pBehIdx); +resBehIdx = arrayfun(@(x,y) nan(x,y), rSz, cSz, fnOpts{:}); +resTable = cell(numel(mice), 1); Nm = numel(mice); +mNames = arrayfun(@(m) m.Name, mice); clrMap = roma(Nm); +habFig = figure('Name', 'Intensity v.s. index', 'Color', 'w'); +ax = axes('Parent', habFig, 'Color', 'none', 'Box', 'off', 'NextPlot', 'add'); +x = []; y = []; +for m = 1:Nm + mxSub = find(Ncc{m} == rSz(m), 1, "first"); + for ci = 1:cSz(m) + endS = numel(pBehIdx{m}{ci}); + resBehIdx{m}(1:endS,ci) = pBehIdx{m}{ci}; + end + resTable{m} = table(resBehIdx{m}, ... + 'RowNames', mice(m).Sessions(mxSub).DataTable.Row, ... + 'VariableNames', "BehaviourIndices"); + x = [x; reshape(ones(rSz(m), cSz(m)).*(1:rSz(m))', [], 1)]; + y = [y; resTable{m}.BehaviourIndices(:)]; + %scatter(ax, ones(cSz(m),rSz(m)).*(1:rSz(m)) + ... + scatter(ax, (1:rSz(m)) + random(jittDist, [1,rSz(m)]), ... + mean(resTable{m}.BehaviourIndices,2,'omitnan')', [], clrMap(m,:), ... + "filled", "MarkerFaceAlpha", 0.5) +end +xticks(ax, 1:max(rSz)); + +lgObj = legend(ax, mNames); +set(lgObj, "Box", 'off', 'Color', 'none', 'Location', 'best', 'AutoUpdate', 'off') + +%% +%{ +dateFlag = arrayfun(@(m) arrayfun(@(s) ~contains(fieldnames(s), 'Date'), ... + m.Sessions, fnOpts{:}), mice, fnOpts{:}); +mCatg = arrayfun(@(mn) categorical(regexp(mn.Name, '[A-Za-z]{2}', ... + 'match')), mice); +Nfn = cellfun(@(x) cellfun(@sum, x), dateFlag, fnOpts{:}); +values = arrayfun(@(m) arrayfun(@(s) struct2cell(s), m.Sessions, ... + fnOpts{:}), mice, fnOpts{:}); +%} \ No newline at end of file From 1ea57ddf8132dbdd5d8480568935a8584b64b861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 12 May 2023 18:17:37 +0200 Subject: [PATCH 017/201] Batch10 --- Emilio/poolBehIndices.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 0b84144..3a73b99 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -11,7 +11,7 @@ %% Assuming 1 level of animal organisation i.e. % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 -batchDir = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch11_ephys.MC"; +batchDir = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch10_ephys.e"; childFolders = dir(batchDir); pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), childFolders); From 83851c97e14805285b6ef32d49705ae4803d8c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 17 May 2023 18:27:16 +0200 Subject: [PATCH 018/201] Saving results in the corresponding batch folder --- Emilio/poolBehIndices.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 3a73b99..127f3a2 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -165,6 +165,8 @@ %} end end +btchName = regexp(batchDir, 'Batch\d+','match'); +save(fullfile(batchDir, btchName+"_BehaviourIndex.mat"), 'mice') %% jittDist = makedist('Normal', 'mu', 0, 'sigma', 1/9); habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... From 142c01246600e3262de52908c0e57f3c38272e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 17 May 2023 18:31:40 +0200 Subject: [PATCH 019/201] Eliminate dead code and small fix for no analysis --- Emilio/poolBehIndices.m | 40 +++++++--------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 127f3a2..e00c8b5 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -11,7 +11,7 @@ %% Assuming 1 level of animal organisation i.e. % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 -batchDir = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch10_ephys.e"; +batchDir = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch12_ephys.e"; childFolders = dir(batchDir); pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), childFolders); @@ -40,22 +40,16 @@ currSess = char(regexp(csd.name, '\d{6}', 'match')); childFolders = getSubFolds(curDir); sessOrgDirs = arrayfun(@(d) string(d.name), childFolders); - sessOrgDirs(contains(sessOrgDirs, {'behaviour', 'ephys', 'figures'}, ... - ctOpts{:})) = []; + sessOrgDirs(contains(sessOrgDirs, {'behaviour', 'ephys', ... + 'figures', 'opto'}, ctOpts{:})) = []; behFigDir = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... behFF), childFolders, fnOpts{:}); behFigDir = cat(1, behFigDir{:}); - %{ - if isempty(ephDir) - fprintf(1, "This session didn't have ephys!\n") - fprintf(1, "Skipping\n") + behIdxFiles = arrayfun(@(d) dir(fullfile(d, "BehIndex*.fig")), ... + behFigDir, fnOpts{:}); behIdxFiles = cat(1, behIdxFiles{:}); + if isempty(behIdxFiles) + fprintf(1, 'No new behaviour analysis done! Skipping %s!\n', curDir) continue - else - behFigDir = recursiveFolderSearch(ephDir,... - "Beh V-0.25 - 0.50 s R5.00 - 400.00 ms"); end - ephDir = expandName(ephDir); - %} - behIdxFiles = arrayfun(@(d) dir(fullfile(d, "BehIndex*.fig")), behFigDir); behIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... behIdxFiles); behRes = arrayfun(@(x) get(x, 'UserData'), ... behIdxFig, fnOpts{:}); arrayfun(@close, behIdxFig) @@ -83,26 +77,6 @@ oldSess = currSess; auxStruct = struct('Date', currSess, ... 'DataTable', dataTable, 'Type', sessType); - %{ - if any(xor(delFlag, frqFlag)) - auxStruct.Laser_continuous = behRes(xor(delFlag, ... - frqFlag)).BehIndex; - end - if any(frqFlag) - auxStruct.Laser_freq = behRes(frqFlag).BehIndex; - end - if any(musFlag) - auxStruct.Muscimol = behRes(musFlag).BehIndex; - end - if any(ptxFlag) - auxStruct.PTX = behRes(ptxFlag).BehIndex; - end - if ~isfield(mice, 'Sessions') - mice(mc).Sessions = auxStruct; - else - mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; - end - %} if ~isfield(mice, 'Sessions') mice(mc).Sessions = auxStruct; else From 27f119dba64bb0a973e485cc48d5022d1c996f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 17 May 2023 18:31:57 +0200 Subject: [PATCH 020/201] Small changes --- Emilio/muscimol_analysis.m | 2 +- Jesus/DE_Jittering.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Emilio/muscimol_analysis.m b/Emilio/muscimol_analysis.m index ddff129..0c1fecc 100644 --- a/Emilio/muscimol_analysis.m +++ b/Emilio/muscimol_analysis.m @@ -8,7 +8,7 @@ condFiles = dir(fullfile(ephDir, "*analysis.mat")); load(fullName(condFiles), "Conditions", "fs") %% -ccSub = find(arrayfun(@(c) contains(c.name, ["Control Puff", "Delay"], ... +ccSub = find(arrayfun(@(c) contains(c.name, ["Control Puff", "PTX","Death"], ... "IgnoreCase", true), Conditions)); pairedStim = arrayfun(@(x) Conditions(1).Triggers(:,1) == ... diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index fe2e8fa..b96bf4b 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -876,6 +876,6 @@ set(behAreaFig, 'UserData', behRes) biFN = sprintf(biFigPttrn, pAreas); - saveFigure(behAreaFig, fullfile(behFigDir, biFN), true); + saveFigure(behAreaFig, fullfile(behFigDir, biFN), true, true); end end \ No newline at end of file From 6d670e24e500a587b3848f13e6fdad8c505a3a79 Mon Sep 17 00:00:00 2001 From: Ross Folkard Date: Fri, 26 May 2023 11:17:04 +0200 Subject: [PATCH 021/201] Update PoolDifMech.m --- Ross/PoolDifMech.m | 839 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 825 insertions(+), 14 deletions(-) diff --git a/Ross/PoolDifMech.m b/Ross/PoolDifMech.m index 0239f0c..59aa329 100644 --- a/Ross/PoolDifMech.m +++ b/Ross/PoolDifMech.m @@ -16,13 +16,14 @@ '\\lsdf02.urz.uni-heidelberg.de\sd19b001\PainData\Corrected_Channel_Map\VPL\8.8.22\DifMech\VPL_E1_KS3__Nblocks2__9_9__0pt9__20\m53_VPL_E1_DifMech_ECE_Processing_-10-to-10\PopulationAnalysis\SelectedUnitData.mat' }; - +figureDir = '\\lsdf02.urz.uni-heidelberg.de\sd19b001\PainData\Corrected_Channel_Map\VPL\DifMechPooled'; %% variables to be collected -discStacks = []; +discStacks = false(0); csts = []; Data = []; - +sortedDatapooled = []; +goodspooled = []; %% collecting trial numbers early chCond = 1; nExpts = size(dataDirs, 1); @@ -45,7 +46,7 @@ % Time lapse, bin size, and spontaneous and response windows promptStrings = {'Viewing window (time lapse) [s]:','Response window [s]',... 'Bin size [s]:'}; -defInputs = {'-2, 6', '0.1, 5', '0.01'}; +defInputs = {'-2, 6', '0.1, 3', '0.05'}; answ = inputdlg(promptStrings,'Inputs', [1, 30],defInputs); if isempty(answ) fprintf(1,'Cancelling...\n'); @@ -121,6 +122,11 @@ clInfo = getClusterInfo([dataDir filesep 'cluster_info.tsv']); + if any(ismember(clInfo.Properties.VariableNames,'ActiveUnit')) + clInfo = removevars(clInfo, 'ActiveUnit'); + end + + expID = dir([dataDir, '*expParams*.mat']); [r, ~] = size(expID); if r ~= 1 @@ -165,7 +171,7 @@ % Logical spike trace for the first good cluster spkLog = StepWaveform.subs2idx(round(sortedData{goods(1),2}*fs),Ns); % Subscript column vectors for the rest good clusters - spkSubs = cellfun(@(x) round(x.*fs),sortedData(goods(2:end),2),... + spkSubs = cellfun(@(x) round(x.*fs),sortedData(goods,2),... 'UniformOutput',false); % Number of good clusters Ncl = numel(goods); @@ -199,11 +205,11 @@ - Data = [Data; clInfo(:,1:13)]; + Data = [Data; clInfo(:,1:12)]; %% Constructing the stack out of the user's choice - + onOffStr = 'on'; % discStack - dicrete stack has a logical nature @@ -211,7 +217,7 @@ % Both of these stacks have the same number of time samples and trigger % points. They differ only in the number of considered events. - [discStack, cst] = getStacks(spkLog,Conditions(chCond).Triggers,onOffStr,... + [~, cst] = getStacks(false,Conditions(chCond).Triggers,onOffStr,... timeLapse,fs,fs,spkSubs,continuousSignals); if cexpt == 1 nTriggerscst = size(cst, 1); @@ -230,22 +236,41 @@ csts(end,:,:) = []; end + discStack = getStacks(false,Conditions(chCond).Triggers,onOffStr,... + timeLapse,fs,fs,spkSubs,continuousSignals); + if cexpt == 1 + discStack(2,:,:) = []; + else + discStack(1:2,:,:) = []; + end + + %% concatenating important variables across expts tic discStacks = cat(1, discStacks, discStack); toc csts = cat(1, csts, cst); - -end + + goodsoffset = size(sortedDatapooled,1); + goodspooled = cat(1, goodspooled, goods + goodsoffset); + + sortedDatapooled = cat(1, sortedDatapooled, sortedData); + +end +%% discStack = discStacks; clear discStacks -[Ne, Nt, NTa] = size(discStacks); +cst = [mean(csts([1,3,5],:,:)); mean(csts([2,4,6],:,:))]; clear csts +sortedData = sortedDatapooled; clear sortedDatapooled +goods = goodspooled; clear goodspooled +[Ne, Nt, NTa] = size(discStack); +Ncl = numel(goods); % Computing the time axis for the stack tx = (0:Nt - 1)/fs + timeLapse(1); - +condNames = arrayfun(@(x) x.name,Conditions,'UniformOutput',false); consideredConditions = find(~ismember(1:length(Conditions), chCond)); - +Nccond = length(consideredConditions); %% Boolean flags delayFlags = false(NTa,Nccond); counter2 = 1; @@ -254,4 +279,790 @@ Conditions(ccond).Triggers(:,1)); counter2 = counter2 + 1; end -Na = sum(delayFlags,1); \ No newline at end of file +Na = sum(delayFlags,1); + +%% Computing which units/clusters/putative neurons respond to the stimulus +% Logical indices for fetching the stack values +gclID = sortedData(goods,1); +expName = 'pooled'; +sponActStackIdx = tx >= spontaneousWindow(1) & tx <= spontaneousWindow(2); +respActStackIdx = tx >= responseWindow(1) & tx <= responseWindow(2); +% The spontaneous activity of all the clusters, which are allocated from +% the second until one before the last row, during the defined spontaneous +% time window, and the whisker control condition. + +timeFlags = [sponActStackIdx;respActStackIdx]; +% Time window +delta_t = diff(responseWindow); +% Statistical tests +[Results, Counts] = statTests(discStack, delayFlags, timeFlags); + +indCondSubs = cumsum(Nccond:-1:1); +consCondNames = condNames(consideredConditions); +% Plotting statistical tests +[Figs, Results] = scatterSignificance(Results, Counts,... + consCondNames, delta_t, sortedData(goods,1)); +configureFigureToPDF(Figs); +stFigBasename = fullfile(figureDir,[expName,' ']); +stFigSubfix = sprintf(' Stat RW%.1f-%.1fms SW%.1f-%.1fms',... + responseWindow(1)*1e3, responseWindow(2)*1e3, spontaneousWindow(1)*1e3,... + spontaneousWindow(2)*1e3); +ccn = 1; +%for cc = indCondSubs +for cc = 1:numel(Figs) + if ~ismember(cc, indCondSubs) + altCondNames = strsplit(Figs(cc).Children(2).Title.String,': '); + altCondNames = altCondNames{2}; + else + altCondNames = consCondNames{ccn}; + ccn = ccn + 1; + end + stFigName = [stFigBasename, altCondNames, stFigSubfix]; + % if ~exist([stFigName,'.pdf'],'file') || ~exist([stFigName,'.emf'],'file') + % print(Figs(cc),[stFigName,'.pdf'],'-dpdf','-fillpage') + % print(Figs(cc),[stFigName,'.emf'],'-dmeta') + % end + savefig(Figs(cc),fullfile(figureDir, [altCondNames, stFigSubfix '.fig'])); +end + +H = cell2mat(cellfun(@(x) x.Pvalues,... + arrayfun(@(x) x.Activity, Results(indCondSubs), 'UniformOutput', 0),... + 'UniformOutput', 0)) < 0.05; + +Htc = sum(H,2); +CtrlCond = contains(consCondNames,'control','IgnoreCase',true); +if ~nnz(CtrlCond) + CtrlCond = true(size(H,2),1); +end +wruIdx = any(H(:,CtrlCond),2); +Nwru = nnz(wruIdx); + +fprintf('%d responding clusters:\n', Nwru); +fprintf('- %s\n',gclID{wruIdx}) + +%% Addition mean signals to the Conditions variable +if ~isfield(Conditions,'Stimulus') ||... + any(arrayfun(@(x) isempty(x.Stimulus), Conditions(consideredConditions))) + fprintf(1,'Writting the stimulus raw signal into Conditions variable:\n') + whFlag = contains(trigNames, whStim, 'IgnoreCase', 1); + lrFlag = contains(trigNames, cxStim, 'IgnoreCase', 1); + cdel = 1; + for cc = consideredConditions + fprintf(1,'- %s\n', Conditions(cc).name) + Conditions(cc).Stimulus = struct(... + 'Mechanical',reshape(mean(cst((1),:,delayFlags(:,cdel)),3),... + 1,Nt),... + 'MechPressure',reshape(mean(cst((2),:,delayFlags(:,cdel)),3),... + 1,Nt),'TimeAxis',(0:Nt-1)/fs + timeLapse(1)); + cdel = cdel + 1; + end + %save(fullfile(dataDir,[expName,'_analysis.mat']),'Conditions','-append') +end + + +%% Filter question +filterIdx = true(Ne,1); +ansFilt = questdlg('Would you like to filter for significance?','Filter',... + 'Yes','No','Yes'); +filtStr = 'unfiltered'; +if strcmp(ansFilt,'Yes') + filterIdx = [true; wruIdx]; + filtStr = 'Filtered'; +end +%ruIdx = wruIdx; + + +%% Ordering PSTH + +orderedStr = 'ID ordered'; +dans = questdlg('Do you want to order the PSTH other than by IDs?',... + 'Order', 'Yes', 'No', 'No'); +ordSubs = 1:nnz(filterIdx(2:Ncl+1)); +pclID = gclID(filterIdx(2:end)); +if strcmp(dans, 'Yes') + % if ~exist('clInfo','var') + % clInfo = getClusterInfo(fullfile(dataDir,'cluster_info.tsv')); + % end + % varClass = varfun(@class,clInfo,'OutputFormat','cell'); + [ordSel, iOk] = listdlg('ListString', Data.Properties.VariableNames,... + 'SelectionMode', 'multiple'); + orderedStr = []; + ordVar = Data.Properties.VariableNames(ordSel); + for cvar = 1:numel(ordVar) + orderedStr = [orderedStr, sprintf('%s ',ordVar{cvar})]; %#ok + end + orderedStr = [orderedStr, 'ordered']; + + if ~strcmp(ordVar,'id') + [~,ordSubs] = sortrows(Data(pclID,:),ordVar, 'ascend'); + end +end +%% Plot PSTH +% goodsIdx = logical(clInfo.ActiveUnit); +csNames = fieldnames(Triggers); +while size(csNames,1) > size(cst) + csNames(end) = []; +end + +Nbn = diff(timeLapse)/binSz; +if (Nbn - round(Nbn)) ~= 0 + Nbn = ceil(Nbn); +end +PSTH = zeros(nnz(filterIdx) - 1, Nbn, Nccond); +psthFigs = gobjects(Nccond,1); +for ccond = 1:Nccond + figFileName = sprintf('%s %s VW%.1f-%.1f ms B%.1f ms RW%.1f-%.1f ms SW%.1f-%.1f ms %sset %s (%s)',... + expName, Conditions(consideredConditions(ccond)).name, timeLapse*1e3,... + binSz*1e3, responseWindow*1e3, spontaneousWindow*1e3, onOffStr,... + orderedStr, filtStr); + [PSTH(:,:,ccond), trig, sweeps] = getPSTH(discStack(filterIdx,:,:),timeLapse,... + ~delayFlags(:,ccond),binSz,fs); + stims = mean(cst(:,:,delayFlags(:,ccond)),3); + stims = stims - median(stims,2); + for cs = 1:size(stims,1) + if abs(log10(var(stims(cs,:),[],2))) < 15 + [m,b] = lineariz(stims(cs,:),1,0); + stims(cs,:) = m*stims(cs,:) + b; + else + stims(cs,:) = zeros(1,Nt); + end + end + psthFigs(ccond) = plotClusterReactivity(PSTH(ordSubs,:,ccond),trig,sweeps,timeLapse,binSz,... + [{Conditions(consideredConditions(ccond)).name};... + pclID(ordSubs)],... + strrep(expName,'_','\_'),... + stims, csNames); + configureFigureToPDF(psthFigs(ccond)); + psthFigs(ccond).Children(end).YLabel.String =... + [psthFigs(ccond).Children(end).YLabel.String,... + sprintf('^{%s}',orderedStr)]; + % if ~exist([figFileName,'.pdf'], 'file') + % print(psthFigs(ccond), fullfile(figureDir,[figFileName, '.pdf']),... + % '-dpdf','-fillpage') + % end + % if ~exist([figFileName,'.emf'], 'file') + % print(psthFigs(ccond), fullfile(figureDir,[figFileName, '.emf']),... + % '-dmeta') + % end + +end +% for a = 1:length(consideredConditions) +% savefig(figure(a), fullfile(figureDir, [consCondNames{a}, '_filtered_PSTH_0.001binSz.fig'])); +% end + + +%% Getting cluster info and adding variables to table + +ActiveUnit = false(height(Data),1); +Data = addvars(Data,ActiveUnit,'NewVariableNames','ActiveUnit','After','id'); +Data{goods, 'ActiveUnit'} = true; + +window = diff(responseWindow); + +for a = 1: length(consCondNames) + Data{Data.ActiveUnit == true,[consCondNames{1,a}, '_Rate_Spont']} = mean(Counts{a,1}')'/window; + Data{Data.ActiveUnit == true,[consCondNames{1,a}, '_Rate_Evoked']} = mean(Counts{a,2}')'/window; +end + + +% Significant mechanical responses per condition +b = length(consCondNames); +for a = 1 : length(consCondNames) + Data{Data.ActiveUnit == true,[consCondNames{1,a}, '_R']} = Results(b).Activity(1).Pvalues < 0.05; + b = b + length(consCondNames) - a; +end + +% Comparing Across Conditions (i.e. manipulation effect on spontaneous and evoked activity) +% RAM: comment to explain what you are doing +sZ = size(Counts); +d = length(consCondNames); +e = 1; +f = length(consCondNames); +for a = 1:length(consCondNames) - 1 + for b = (a + 1): length(consCondNames) + + for c = 1: sZ(1,2) + Data{Data.ActiveUnit == true,[consCondNames{1,a},'_vs_',consCondNames{1,b}, '_', Results(e).Activity(c).Type, '_Response']} = Results(e).Activity(c).Pvalues < 0.05; + %RAM example + %myString = [consCondNames{1,a},'_vs_',consCondNames{1,b}, '_', Results(e).Activity(c).Type, '_Response']; + %clInfo{clInfo.ActiveUnit == true,myString} = Results(e).Activity(c).Pvalues < 0.05; + + end + + e = e + 1; + + if e == f + e = e + 1; + end + end + d = d - 1; + f = f + d; +end +writeClusterInfo(Data, fullfile(figureDir,'cluster_info_TonicResponses.tsv')); + +%% Rasters +% DE_Jittering needs to be unfiltered for significance for this to work! +csNames = fieldnames(Triggers); +% csNames = csNames(2:end); +IDs = csNames; +trigTX = linspace(timeLapse(1),timeLapse(2),size(trig,2)); + +rasterDir = fullfile(figureDir,'Rasters\'); +if ~mkdir(rasterDir) + fprintf(1,'There was an issue with the figure folder...\n'); +end + + +Power = NaN(length(consCondNames),1); +for cc = 1:length(consCondNames) + + mWfind = strfind(consCondNames{cc}, 'mW'); + + pwr = consCondNames{cc}(mWfind-2:mWfind+1); + if isnan(pwr) + pwrMissing = true; + elseif contains(pwr, '.') + pwr = consCondNames{cc}(mWfind-3:mWfind+1); + elseif contains(pwr, '_') || contains(pwr, ' ') + pwr = pwr(2:end); + end + pwr = str2double(pwr(1:end-2)); + Power(cc) = pwr; +end +pwrs = unique(Power); + +med = 0.2; +low = 0.4; +high = 0; +colours = ones(1,3); +colours(1:4,:) = med; colours(5:8,:) = low; colours(9:10,:) = high; + +for a = 1%:length(pwrs) + pwr = pwrs(a); + % MchTblInd = ['Mech_Control_', num2str(pwr), 'mW_MR']; + % LasTblInd = [20,21,22];%['Laser_Control_', num2str(pwr), 'mW_LR']; + % MchCondControl = ['Mech_Control_', num2str(pwr), 'mW']; + % LasCondControl = ['Laser_Control_', num2str(pwr), 'mW']; + % MchLasCond = ['Mech_Laser_', num2str(pwr), 'mW']; + % EffectTblInd = ['Mech_Control_', num2str(pwr), 'mW_vs_Mech_Laser_', num2str(pwr), 'mW_Evoked_Response']; + % TblInd = find(clInfo.ActiveUnit); % ATM this only makes rasters that show sig control mech response + % clIDind = clInfo.id(TblInd); + % pwrInd = Power == pwr; + clIDind = Data.id(Data.Mech_Low_R); + lngth = length(clIDind); + for a = 1:lngth + rng('default'); + cl = clIDind(a); + clSel = find(ismember(pclID, cl)); + % if chCond == 1 + % rasCondSel = find(ismember(consCondNames, MchCondControl) | ismember(consCondNames, MchLasCond)); + % label = 'Mech'; + % else + % rasCondSel = find(ismember(consCondNames, LasCondControl) | ismember(consCondNames, MchLasCond)); + % label = 'Laser'; + % end + rasCondSel = [1 2 3]; + rasCond = consideredConditions(rasCondSel); + rasCondNames = consCondNames(rasCondSel); + Nrcl = numel(clSel); + % Reorganize the rasters in the required order. + clSub = find(ismember(gclID, pclID(clSel)))+1; + [rasIdx, rasOrd] = ismember(pclID(ordSubs), pclID(clSel)); + clSub = clSub(rasOrd(rasIdx)); + clSel = clSel(rasOrd(rasOrd ~= 0)); + Nma = min(Na(rasCondSel)); + rasFig = figure; + columns = length(pwrs); + Nrcond = length(rasCond); + ax = gobjects(4*Nrcond*Nrcl,1); + lidx = 1; + for cc = 1:length(rasCond) + % Equalize trial number + trigSubset = sort(randsample(Na(rasCondSel(cc)),Nma)); + tLoc = find(delayFlags(:,rasCondSel(cc))); + tSubs = tLoc(trigSubset); + % Trigger subset for stimulation shading + trigAlSubs = Conditions(rasCond(cc)).Triggers(trigSubset,:); + timeDur = round(diff(trigAlSubs, 1, 2)/fs, 3); + trigChange = find(diff(timeDur) ~= 0); + for ccl = 1:Nrcl + + stims = mean(cst(:,:,delayFlags(:,rasCondSel(cc))),3); + % stims = stims([2,3],:); + + stims = stims - median(stims,2); + + + + for cs = 2 %for cs = 1:size(stims,1) + if abs(log10(var(stims(cs,:),[],2))) < 13 + [m,b] = lineariz(stims(cs,:),1,0); + stims(cs,:) = m*stims(cs,:) + b; + else + stims(cs,:) = zeros(1,Nt); + end + end + + [r,c] = size(stims); + + if r < c + stims = stims'; + stmClr = zeros(r, 3); + + end + + + + + for cs = 2 %for cs = 1:size(stims,1) + if stims(1,cs) > 0.5 + stim = ones(size(stims(:,cs)))-stims(:,cs); + else + stim = stims(:,cs); + end + % dP=[0; diff(stim)]; + stim = smooth(stim,10); + ax(lidx) = subplot(4*Nrcond, Nrcl, lidx); + if exist('IDs','var') + plot(trigTX,stim, 'LineStyle','-','LineWidth', 1,... + 'DisplayName', IDs{cs}, 'Color', stmClr(cs,:)) + % P = stim'; %ax(lidx).Children.YData; + % dP = [0 diff(P)]; + % dP = smooth(dP,100); + % dP = dP-mean(dP(1:100));dP=dP/max(dP); + % + % yyaxis right + % plot(trigTX, dP, 'LineStyle','-','LineWidth', 1,... + % 'DisplayName', IDs{cs}, 'Color', stmClr(cs,:)) + else + plot(trigTX,stim,'LineStyle','-','LineWidth',1, 'Color', stmClr(cs,:)) + + % P = ax(lidx).Children.YData; + % dP = [0 diff(P)]; + % dP = smooth(dP,100); + % dP = dP-mean(dP(1:100));dP=dP/max(dP); + % yyaxis right + % plot(trigTX, dP, 'LineStyle','-','LineWidth', 1,... + % 'DisplayName', IDs{cs}, 'Color', stmClr(cs,:)) + end + ax(lidx).Visible = 'off'; + + + % ax2.Children(1).Color = defineColorForStimuli(IDs(cs)); + + if cs == 1 + ax2.NextPlot = 'add'; + end + + end + % ax = gca; + % + % + % % ax.YAxis(2).Limits = [0.015, 1]; + % % ax.YAxis(2).Visible = 'off'; + % ax.FontName ='Arial'; + % ax.FontSize = 12; + + % f=get(gca,'Children'); + % legend(f) + % + lidx = lidx + 1; + + + % lidx = ccl + (cc - 1) * Nrcl; + ax(lidx) = subplot(4*Nrcond, Nrcl, lidx:lidx+2); % subplot( Nrcl, Nrcond, lidx); % to plot the other way around + title(ax(lidx),sprintf(rasCondNames{cc}), 'Interpreter', 'none') % ,pclID{clSel(ccl)} + plotRasterFromStack(discStack([1,clSub(ccl)],:,tSubs),... + timeLapse, fs,'',ax(lidx)); + % plotRasterFromStack(discStack([1,clSub(ccl)],:,tSubs),... + % timeLapse, fs,'',colours(lidx,:),ax(lidx)); + ax(lidx).YAxisLocation = 'origin';ax(lidx).YAxis.TickValues = Nma; + ax(lidx).YAxis.Label.String = 'Trials'; + % ax(lidx).YAxis.Label.Position =... + % [timeLapse(1)-timeLapse(1)*0.65, Nma,0]; + % ax(lidx).XAxis.TickLabels =... + % cellfun(@(x) (x)*1e3, ax(lidx).XAxis.TickValues,... + % 'UniformOutput', 0); + xlabel(ax(lidx), 'Time [s]') + initSub = 0; + optsRect = {'EdgeColor','none','FaceColor','none'}; + for ctr = 1:numel(trigChange) + rectangle('Position',[0, initSub,... + timeDur(trigChange(ctr)), trigChange(ctr)],optsRect{:}) + initSub = trigChange(ctr); + end + rectangle('Position', [0, initSub, timeDur(Nma),... + Nma - initSub],optsRect{:}) + + % ax(lidx).XAxis.Visible = 'off'; + ax(lidx).YAxis.Visible = 'off'; + stims = mean(cst(:,:,delayFlags(:,rasCondSel(cc))),3); + % stims = stims([2,3],:); + + stims = stims - median(stims,2); + + + + for cs = 2 %for cs = 1:size(stims,1) + if abs(log10(var(stims(cs,:),[],2))) < 13 + [m,b] = lineariz(stims(cs,:),1,0); + stims(cs,:) = m*stims(cs,:) + b; + else + stims(cs,:) = zeros(1,Nt); + end + end + + [r,c] = size(stims); + + if r < c + stims = stims'; + stmClr = zeros(r, 3); + + end + + % stmClr =[ 1 0 0 0.25; 0 1 1 0.25]; + + + + lidx = lidx + 3; + + + end + end + + + + + + rasConds = rasCondNames{1}; + if length(rasCondNames) > 1 + for r = 2:length(rasCondNames) + rasConds = [rasConds, '+', rasCondNames{r}]; + end + end + + + ax(2).Title.Color = colours(2,:); + ax(6).Title.Color = colours(6,:); + ax(10).Title.Color = colours(10,:); + ax(1).Children.Color = colours(1,:); + ax(5).Children.Color = colours(5,:); + ax(9).Children.Color = colours(9,:); + + + linkaxes(ax,'x') + rasFigName = ['Unit_', cell2mat(cl), '_', ]; + rasFig.Name = [rasFigName, '_', num2str(pwr), 'mW']; + configureFigureToPDF (rasFig); + set(rasFig, 'Position', get(0, 'ScreenSize')/2); + saveas(rasFig,fullfile(rasterDir, [rasFigName,'_',rasConds,'_', num2str(timeLapse(1)), '_to_', num2str(timeLapse(2)),'.emf'])); + %savefig(rasFig,fullfile(rasterDir, [rasFigName, ' ', num2str(pwr), 'mW.fig'])); + savefig(rasFig,fullfile(rasterDir, [rasFigName,'_',rasConds, '.fig'])); + end +end + + +%% print mech responses to pdf +targetdir = [figureDir filesep 'difMech']; %put all individual pdfs here, replace blocking with whatever makes sense +mergedir=print_all_figs(targetdir,'-dpdf'); %print all open figures to pdf +cd(figureDir) +merge_PDF_dir(mergedir) %merge all single figure pdfs to one large pdf, in this directory + + +%% Ordering PSTH +filterIdx = [true; ismember(gclID, Data.id(Data.Mech_Low_R))]; +orderedStr = 'ID ordered'; +ordSubs = 1:nnz(filterIdx(2:Ncl+1)); +pclID = gclID(filterIdx(2:end)); + + + + +%% PSTHs for comparisons +binSz = 0.5; +% goodsIdx = logical(clInfo.ActiveUnit); +csNames = fieldnames(Triggers); +while size(csNames,1) > size(cst) + csNames(end) = []; +end + +Nbn = diff(timeLapse)/binSz; +if (Nbn - round(Nbn)) ~= 0 + Nbn = ceil(Nbn); +end +PSTH = zeros(nnz(filterIdx) - 1, Nbn, Nccond); +psthFigs = gobjects(Nccond,1); +for ccond = 1:Nccond + figFileName = sprintf('%s %s VW%.1f-%.1f ms B%.1f ms RW%.1f-%.1f ms SW%.1f-%.1f ms %sset %s (%s)',... + expName, Conditions(consideredConditions(ccond)).name, timeLapse*1e3,... + binSz*1e3, responseWindow*1e3, spontaneousWindow*1e3, onOffStr,... + orderedStr, filtStr); + [PSTH(:,:,ccond), trig, sweeps] = getPSTH(discStack(filterIdx,:,:),timeLapse,... + ~delayFlags(:,ccond),binSz,fs); + stims = mean(cst(:,:,delayFlags(:,ccond)),3); + stims = stims - median(stims,2); + for cs = 1:size(stims,1) + if abs(log10(var(stims(cs,:),[],2))) < 13 + [m,b] = lineariz(stims(cs,:),1,0); + stims(cs,:) = m*stims(cs,:) + b; + else + stims(cs,:) = zeros(1,Nt); + end + end + PSTH = PSTH./binSz/sum(delayFlags(:,1)); + +end + +%% +for unit = 1:size(PSTH, 1) + figure('Name',['unit_', pclID{unit}], 'Color', 'white') + hold on + for ccond = 1:length(consideredConditions) + plot(PSTH(unit,:,ccond)); + end + ax = gca; + legend(consCondNames); + ax.XTickLabel = ax.XTick*binSz-2; + +end + + +%% PopPSTH By Group +figure('Name','DifMech_PopPSTH', 'Color','white'); hold on +[Ncl, Npt, Nconds] = size(PSTH); +psthTX = linspace(timeLapse(1),timeLapse(2),Npt); +trigTX = linspace(timeLapse(1),timeLapse(2),size(trig,2)); +for ccond = 1:length(consideredConditions) + + + medPSTH = median(sum(PSTH(:,1:40,ccond),1,'omitnan')/(Ncl * sweeps * binSz)); + popPSTH = sum(PSTH(:,:,ccond),1,'omitnan')/(Ncl * sweeps * binSz); + % popPSTH = popPSTH-medPSTH; + popPSTH = smooth(popPSTH, 5); + plot(psthTX,popPSTH, 'LineWidth',1.5) + + +end +leg = legend; +leg.String = consCondNames; +leg.Box = 'off'; +leg.FontName = 'Arial'; +ax = gca; +ax.FontSize = 25; +leg.Location = 'northeast'; + + +%% Absolute Pressure Difference Comparison + +cs = 2; +stims = mean(cst,3); +[m,b] = lineariz(stims(cs,:),1,0); +stims(cs,:) = m*stims(cs,:) + b; +% figure('Color','white', 'Name', 'AvPressure'); +% plot(stims(cs,:)) + +figure('Color','white', 'Name', 'Pressures'); + +hold on + +for ccond = 1:Nccond + stims = mean(cst(:,:,delayFlags(:,ccond)),3); + if abs(log10(var(stims(cs,:),[],2))) < 15 + stims(cs,:) = m*stims(cs,:) + b; + stims(cs,:) = stims(cs,:) - min(stims(cs,:)); + + stims(cs,:) = smooth(stims(cs,:),10^4); + else + stims(cs,:) = zeros(1,Nt); + end + plot(stims(cs,:)) +end + + +%% Delta Pressure Difference Comparison + +colours = [0,0,0.75; 0, 0.75, 0; 0.75, 0, 0.75]; +cs = 2; +stims = mean(cst,3); +[m,b] = lineariz(stims(cs,:),1,0); +stims(cs,:) = m*stims(cs,:) + b; +% figure('Color','white', 'Name', 'AvPressure'); +% plot(stims(cs,:)) + +figure('Color','white', 'Name', '\Delta Pressures'); + +hold on + +for ccond = 1:Nccond + stims = mean(cst(:,:,delayFlags(:,ccond)),3); + if abs(log10(var(stims(cs,:),[],2))) < 15 + stims(cs,:) = m*stims(cs,:) + b; + stims(cs,:) = stims(cs,:) - min(stims(cs,:)); + + stims(cs,:) = smooth(stims(cs,:),10^4); + else + stims(cs,:) = zeros(1,Nt); + end + stim = diff(stims(cs,:)); + stim = smooth(stim, 10^4); + plot(stim, 'color', colours(ccond,:), 'LineWidth', 1.25); +end +fig = gcf; +ax = gca; +ax.FontName = 'Arial'; +ax.FontSize = 25; + +%% Rasters + +csNames = fieldnames(Triggers); +% csNames = csNames(2:end); +IDs = csNames; +trigTX = linspace(timeLapse(1),timeLapse(2),size(trig,2)); + + +rasterDir = fullfile(figureDir,'Rasters\'); +if ~mkdir(rasterDir) + fprintf(1,'There was an issue with the figure folder...\n'); +end + +colours = [0,0,0.75; 0, 0.75, 0; 0.75, 0, 0.75]; +cs = 2; + +clIDind = pclID; +lngth = length(clIDind); +for a = 1:lngth + rng('default'); + cl = clIDind(a); + clSel = find(ismember(pclID, cl)); + % if chCond == 1 + % rasCondSel = find(ismember(consCondNames, MchCondControl) | ismember(consCondNames, MchLasCond)); + % label = 'Mech'; + % else + % rasCondSel = find(ismember(consCondNames, LasCondControl) | ismember(consCondNames, MchLasCond)); + % label = 'Laser'; + % end + rasCondSel = [1 2 3]; + rasCond = consideredConditions(rasCondSel); + rasCondNames = consCondNames(rasCondSel); + Nrcl = numel(clSel); + % Reorganize the rasters in the required order. + clSub = find(ismember(gclID, pclID(clSel)))+1; + [rasIdx, rasOrd] = ismember(pclID(ordSubs), pclID(clSel)); + clSub = clSub(rasOrd(rasIdx)); + clSel = clSel(rasOrd(rasOrd ~= 0)); + Nma = min(Na(rasCondSel)); + rasFig = figure; + Nrcond = length(rasCond); + ax = gobjects(4*Nrcond*Nrcl,1); + lidx = 1; + for cc = 1:length(rasCond) + % Equalize trial number + trigSubset = sort(randsample(Na(rasCondSel(cc)),Nma)); + tLoc = find(delayFlags(:,rasCondSel(cc))); + tSubs = tLoc(trigSubset); + % Trigger subset for stimulation shading + trigAlSubs = Conditions(rasCond(cc)).Triggers(trigSubset,:); + timeDur = round(diff(trigAlSubs, 1, 2)/fs, 3); + trigChange = find(diff(timeDur) ~= 0); + for ccl = 1:Nrcl + + stims = mean(cst(:,:,delayFlags(:,rasCondSel(cc))),3); + if abs(log10(var(stims(cs,:),[],2))) < 15 + stims(cs,:) = m*stims(cs,:) + b; + stims(cs,:) = stims(cs,:) - min(stims(cs,:)); + + stims(cs,:) = smooth(stims(cs,:),10^4); + else + stims(cs,:) = zeros(1,Nt); + end + stim = [0, diff(stims(cs,:))]; + stim = smooth(stim, 10^4); + + + + + + + ax(lidx) = subplot(4*Nrcond, Nrcl, lidx); + if exist('IDs','var') + plot(trigTX,stims(cs,:), 'LineStyle','-','LineWidth', 1,... + 'DisplayName', IDs{cs}, 'Color',colours(rasCondSel(cc),:)); + + else + plot(trigTX,stim(cs,:),'LineStyle','-','LineWidth', 1, 'color', colours(rasCondSel(cc),:)); + + end + ax(lidx).Visible = 'off'; + + + + + if cs == 1 + ax2.NextPlot = 'add'; + end + + end + + lidx = lidx + 1; + + + ax(lidx) = subplot(4*Nrcond, Nrcl, lidx:lidx+2); % subplot( Nrcl, Nrcond, lidx); % to plot the other way around + title(ax(lidx),sprintf(rasCondNames{cc}), 'Interpreter', 'none') % ,pclID{clSel(ccl)} + + plotRasterFromStack(discStack([1,clSub(ccl)],:,tSubs),... + timeLapse, fs,'',ax(lidx)); + ax(lidx).YAxisLocation = 'origin';ax(lidx).YAxis.TickValues = Nma; + ax(lidx).YAxis.Label.String = 'Trials'; + + xlabel(ax(lidx), 'Time [s]') + initSub = 0; + optsRect = {'EdgeColor','none','FaceColor','none'}; + for ctr = 1:numel(trigChange) + rectangle('Position',[0, initSub,... + timeDur(trigChange(ctr)), trigChange(ctr)],optsRect{:}) + initSub = trigChange(ctr); + end + rectangle('Position', [0, initSub, timeDur(Nma),... + Nma - initSub],optsRect{:}) + + ax(lidx).XAxis.Visible = 'off'; + ax(lidx).YAxis.Visible = 'off'; + stims = mean(cst(:,:,delayFlags(:,rasCondSel(cc))),3); + + + stims = stims - median(stims,2); + + + + + + lidx = lidx + 3; + + + end + + + + + + +rasConds = rasCondNames{1}; +if length(rasCondNames) > 1 + for r = 2:length(rasCondNames) + rasConds = [rasConds, '+', rasCondNames{r}]; + end +end + + + + + +linkaxes(ax,'x') +rasFigName = ['Unit_', cell2mat(cl), '_', ]; +rasFig.Name = [rasFigName, '_', num2str(pwr), 'mW']; +configureFigureToPDF (rasFig); +set(rasFig, 'Position', get(0, 'ScreenSize')/2); +saveas(rasFig,fullfile(rasterDir, [rasFigName,'_',rasConds,'_', num2str(timeLapse(1)), '_to_', num2str(timeLapse(2)),'.emf'])); +%savefig(rasFig,fullfile(rasterDir, [rasFigName, ' ', num2str(pwr), 'mW.fig'])); +savefig(rasFig,fullfile(rasterDir, [rasFigName,'_',rasConds, '.fig'])); +end From 0d947efba8a06dc89f48c1c5b0f280c6dbf268f3 Mon Sep 17 00:00:00 2001 From: Ross Folkard Date: Fri, 26 May 2023 19:30:01 +0200 Subject: [PATCH 022/201] Update PoolDifMech.m --- Ross/PoolDifMech.m | 196 +++++++++++++++++++++++++++++++++------------ 1 file changed, 144 insertions(+), 52 deletions(-) diff --git a/Ross/PoolDifMech.m b/Ross/PoolDifMech.m index 59aa329..1b6a552 100644 --- a/Ross/PoolDifMech.m +++ b/Ross/PoolDifMech.m @@ -828,6 +828,7 @@ %% PopPSTH By Group +colours = [0,0,0.75; 0, 0.75, 0; 0.75, 0, 0.75]; figure('Name','DifMech_PopPSTH', 'Color','white'); hold on [Ncl, Npt, Nconds] = size(PSTH); psthTX = linspace(timeLapse(1),timeLapse(2),Npt); @@ -839,7 +840,7 @@ popPSTH = sum(PSTH(:,:,ccond),1,'omitnan')/(Ncl * sweeps * binSz); % popPSTH = popPSTH-medPSTH; popPSTH = smooth(popPSTH, 5); - plot(psthTX,popPSTH, 'LineWidth',1.5) + plot(psthTX,popPSTH, 'LineWidth',1.5, 'Color',colours(ccond,:)); end @@ -925,7 +926,7 @@ fprintf(1,'There was an issue with the figure folder...\n'); end -colours = [0,0,0.75; 0, 0.75, 0; 0.75, 0, 0.75]; +colours = [0,0,0.75; 0, 0.25, 0; 0.5, 0, 0.5]; cs = 2; clIDind = pclID; @@ -951,7 +952,7 @@ clSub = clSub(rasOrd(rasIdx)); clSel = clSel(rasOrd(rasOrd ~= 0)); Nma = min(Na(rasCondSel)); - rasFig = figure; + rasFig = figure('Color','white'); Nrcond = length(rasCond); ax = gobjects(4*Nrcond*Nrcl,1); lidx = 1; @@ -964,36 +965,67 @@ trigAlSubs = Conditions(rasCond(cc)).Triggers(trigSubset,:); timeDur = round(diff(trigAlSubs, 1, 2)/fs, 3); trigChange = find(diff(timeDur) ~= 0); + for ccl = 1:Nrcl + ax(lidx) = subplot(6*Nrcond, Nrcl, lidx:lidx+1); + % subplot( Nrcl, Nrcond, lidx); % to plot the other way around + % title(ax(lidx),sprintf(rasCondNames{cc}), 'Interpreter', 'none') % ,pclID{clSel(ccl)} + + plotRasterFromStack(discStack([1,clSub(ccl)],:,tSubs),... + timeLapse, fs,'',ax(lidx)); + ax(lidx).YAxisLocation = 'origin';ax(lidx).YAxis.TickValues = Nma; + ax(lidx).YAxis.Label.String = 'Trials'; + + xlabel(ax(lidx), 'Time [s]') + initSub = 0; + optsRect = {'EdgeColor','none','FaceColor','none'}; + for ctr = 1:numel(trigChange) + rectangle('Position',[0, initSub,... + timeDur(trigChange(ctr)), trigChange(ctr)],optsRect{:}) + initSub = trigChange(ctr); + end + rectangle('Position', [0, initSub, timeDur(Nma),... + Nma - initSub],optsRect{:}) + + ax(lidx).XAxis.Visible = 'off'; + ax(lidx).YAxis.Visible = 'off'; + + lidx = lidx + 2; + - stims = mean(cst(:,:,delayFlags(:,rasCondSel(cc))),3); - if abs(log10(var(stims(cs,:),[],2))) < 15 - stims(cs,:) = m*stims(cs,:) + b; - stims(cs,:) = stims(cs,:) - min(stims(cs,:)); - stims(cs,:) = smooth(stims(cs,:),10^4); - else - stims(cs,:) = zeros(1,Nt); - end - stim = [0, diff(stims(cs,:))]; - stim = smooth(stim, 10^4); + ax(lidx) = subplot(6*Nrcond, Nrcl, lidx:lidx+3); + stims = mean(cst(:,:,delayFlags(:,rasCondSel(cc))),3); + if abs(log10(var(stims(cs,:),[],2))) < 15 + stims(cs,:) = m*stims(cs,:) + b; + stims(cs,:) = stims(cs,:) - min(stims(cs,:)); + stims(cs,:) = smooth(stims(cs,:),10^4); + else + stims(cs,:) = zeros(1,Nt); + end + stim = [0, diff(stims(cs,:))]; + stim = smooth(stim, 10^4); + % stim = stim - min(stim); + yyaxis right + plot(trigTX,stim, 'Color',colours(rasCondSel(cc),:), 'LineWidth',1.5) + ylim([-10^-4, 10^-4]); - ax(lidx) = subplot(4*Nrcond, Nrcl, lidx); + yyaxis left if exist('IDs','var') - plot(trigTX,stims(cs,:), 'LineStyle','-','LineWidth', 1,... - 'DisplayName', IDs{cs}, 'Color',colours(rasCondSel(cc),:)); + area(trigTX,stims(cs,:), 'FaceColor', [0.75,0.75,0.75], 'LineStyle','none') + else - plot(trigTX,stim(cs,:),'LineStyle','-','LineWidth', 1, 'color', colours(rasCondSel(cc),:)); + area(trigTX,stim(cs,:), 'FaceColor', [0.75,0.75,0.75], 'LineStyle','none') end ax(lidx).Visible = 'off'; - + ylim([-1,1]); @@ -1003,66 +1035,126 @@ end - lidx = lidx + 1; - ax(lidx) = subplot(4*Nrcond, Nrcl, lidx:lidx+2); % subplot( Nrcl, Nrcond, lidx); % to plot the other way around - title(ax(lidx),sprintf(rasCondNames{cc}), 'Interpreter', 'none') % ,pclID{clSel(ccl)} - plotRasterFromStack(discStack([1,clSub(ccl)],:,tSubs),... - timeLapse, fs,'',ax(lidx)); - ax(lidx).YAxisLocation = 'origin';ax(lidx).YAxis.TickValues = Nma; - ax(lidx).YAxis.Label.String = 'Trials'; - xlabel(ax(lidx), 'Time [s]') - initSub = 0; - optsRect = {'EdgeColor','none','FaceColor','none'}; - for ctr = 1:numel(trigChange) - rectangle('Position',[0, initSub,... - timeDur(trigChange(ctr)), trigChange(ctr)],optsRect{:}) - initSub = trigChange(ctr); + + + + + + + lidx = lidx + 4; + + + end + + + + + + + rasConds = rasCondNames{1}; + if length(rasCondNames) > 1 + for r = 2:length(rasCondNames) + rasConds = [rasConds, '+', rasCondNames{r}]; end - rectangle('Position', [0, initSub, timeDur(Nma),... - Nma - initSub],optsRect{:}) + end - ax(lidx).XAxis.Visible = 'off'; - ax(lidx).YAxis.Visible = 'off'; - stims = mean(cst(:,:,delayFlags(:,rasCondSel(cc))),3); - stims = stims - median(stims,2); + linkaxes(ax,'x') + rasFigName = ['Unit_', cell2mat(cl), '_', ]; + rasFig.Name = rasFigName; + configureFigureToPDF (rasFig); + saveas(rasFig,fullfile(rasterDir, [rasFigName,'_',rasConds,'_', num2str(timeLapse(1)), '_to_', num2str(timeLapse(2)),'.emf'])); + %savefig(rasFig,fullfile(rasterDir, [rasFigName, ' ', num2str(pwr), 'mW.fig'])); + savefig(rasFig,fullfile(rasterDir, [rasFigName,'_',rasConds, '.fig'])); +end +%% Pressures vs PopPSTHs +colours = [0,0,0.75; 0, 0.25, 0; 0.5, 0, 0.5]; +[Ncl, Npt, Nconds] = size(PSTH); +psthTX = linspace(timeLapse(1),timeLapse(2),Npt); +cs = 2; +lidx = 1; +fig = figure('Color','white', 'Name', 'PopPSTHwithPressures'); +for ccond = 1:length(consideredConditions) + ax(lidx) = subplot(6*Nccond, 1, lidx:lidx+1); + medPSTH = median(sum(PSTH(:,1:40,ccond),1,'omitnan')/(Ncl * sweeps * binSz)); + popPSTH = sum(PSTH(:,:,ccond),1,'omitnan')/(Ncl * sweeps * binSz); + % popPSTH = popPSTH-medPSTH; + popPSTH = smooth(popPSTH, 5); + plot(psthTX,popPSTH, 'LineWidth',1.5, 'Color',colours(ccond,:)) + ylim([ax(lidx).YLim(1), 4]); + + ax(lidx).XAxis.Visible = 'off'; + - lidx = lidx + 3; + lidx = lidx + 2; + ax(lidx) = subplot(6*Nccond, 1, lidx:lidx+3); + stims = mean(cst(:,:,delayFlags(:,ccond)),3); + if abs(log10(var(stims(cs,:),[],2))) < 15 + stims(cs,:) = m*stims(cs,:) + b; + stims(cs,:) = stims(cs,:) - min(stims(cs,:)); + stims(cs,:) = smooth(stims(cs,:),10^4); + else + stims(cs,:) = zeros(1,Nt); end + stim = [0, diff(stims(cs,:))]; + stim = smooth(stim, 10^4); + % stim = stim - min(stim); + + yyaxis right + plot(trigTX,stim, 'Color',[0,0,0], 'LineWidth',1.5) + ylim([-10^-4, 10^-4]); + yyaxis left + if exist('IDs','var') + area(trigTX,stims(cs,:), 'FaceColor', [0.75,0.75,0.75], 'LineStyle','none') + else + area(trigTX,stim(cs,:), 'FaceColor', [0.75,0.75,0.75], 'LineStyle','none') -rasConds = rasCondNames{1}; -if length(rasCondNames) > 1 - for r = 2:length(rasCondNames) - rasConds = [rasConds, '+', rasCondNames{r}]; end -end + ax(lidx).Visible = 'off'; + ylim([-1,1]); + + + -linkaxes(ax,'x') -rasFigName = ['Unit_', cell2mat(cl), '_', ]; -rasFig.Name = [rasFigName, '_', num2str(pwr), 'mW']; -configureFigureToPDF (rasFig); -set(rasFig, 'Position', get(0, 'ScreenSize')/2); -saveas(rasFig,fullfile(rasterDir, [rasFigName,'_',rasConds,'_', num2str(timeLapse(1)), '_to_', num2str(timeLapse(2)),'.emf'])); -%savefig(rasFig,fullfile(rasterDir, [rasFigName, ' ', num2str(pwr), 'mW.fig'])); -savefig(rasFig,fullfile(rasterDir, [rasFigName,'_',rasConds, '.fig'])); + + + + + + + + + + lidx = lidx + 4; + + end + + + + + + + + + From ecd486817a7e8dd10330cc6ebd4a10367118060c Mon Sep 17 00:00:00 2001 From: Ross Folkard Date: Fri, 26 May 2023 20:06:15 +0200 Subject: [PATCH 023/201] Adding MechPressure+PopPSTH in one plot --- Ross/PoolDifMech.m | 66 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/Ross/PoolDifMech.m b/Ross/PoolDifMech.m index 1b6a552..c0dd541 100644 --- a/Ross/PoolDifMech.m +++ b/Ross/PoolDifMech.m @@ -851,10 +851,11 @@ ax = gca; ax.FontSize = 25; leg.Location = 'northeast'; - +ax.XTickLabel = ax.XTick*binSz-2; %% Absolute Pressure Difference Comparison - +trigTX = linspace(timeLapse(1),timeLapse(2),size(trig,2)); +colours = [0,0,0.75; 0, 0.75, 0; 0.75, 0, 0.75]; cs = 2; stims = mean(cst,3); [m,b] = lineariz(stims(cs,:),1,0); @@ -876,9 +877,16 @@ else stims(cs,:) = zeros(1,Nt); end - plot(stims(cs,:)) + plot(trigTX, stims(cs,:), 'Color',colours(ccond,:), 'LineWidth',2) end +leg = legend; +leg.String = consCondNames; +leg.Box = 'off'; +leg.FontName = 'Arial'; +ax = gca; +ax.FontSize = 25; +leg.Location = 'northeast'; %% Delta Pressure Difference Comparison @@ -1151,10 +1159,62 @@ end +%% Abs pressure vs PopPTH overlay + +%% Absolute Pressure Difference Comparison +trigTX = linspace(timeLapse(1),timeLapse(2),size(trig,2)); +pressurecolours = [0.8,0.8,0.8; 0.7, 0.7, 0.7; 0.9, 0.9, 0.9]; + +cs = 2; +stims = mean(cst,3); +[m,b] = lineariz(stims(cs,:),1,0); +stims(cs,:) = m*stims(cs,:) + b; +colours = [0,0,0.75; 0, 0.25, 0; 0.5, 0, 0.5]; +[Ncl, Npt, Nconds] = size(PSTH); +psthTX = linspace(timeLapse(1),timeLapse(2),Npt); + +figure('Color','white', 'Name', 'Pressures'); + +yyaxis right + +hold on +for ccond = [3, 1, 2] + stims = mean(cst(:,:,delayFlags(:,ccond)),3); + if abs(log10(var(stims(cs,:),[],2))) < 15 + stims(cs,:) = m*stims(cs,:) + b; + stims(cs,:) = stims(cs,:) - min(stims(cs,:)); + stims(cs,:) = smooth(stims(cs,:),10^4); + else + stims(cs,:) = zeros(1,Nt); + end + area(trigTX,stims(cs,:), 'FaceColor', pressurecolours(ccond,:), 'LineStyle','none') +end +yyaxis left +hold on +for ccond = 1:length(consideredConditions) + medPSTH = median(sum(PSTH(:,1:40,ccond),1,'omitnan')/(Ncl * sweeps * binSz)); + popPSTH = sum(PSTH(:,:,ccond),1,'omitnan')/(Ncl * sweeps * binSz); + % popPSTH = popPSTH-medPSTH; + popPSTH = smooth(popPSTH, 5); + plot(psthTX,popPSTH, 'LineWidth',2, 'Color',colours(ccond,:), 'LineStyle', '-') +end + + +leg = legend; +leg.String = [consCondNames{3}, consCondNames{1}, consCondNames{2}, consCondNames]; +leg.Box = 'off'; +leg.FontName = 'Arial'; +ax = gca; +ax.XLabel.String = 'Time [secs]'; +ax.YAxis(2).Visible = 'off'; +ax.YAxis(1).Label.String = 'Spike Frequency[Hz]'; +ax.FontSize = 25; +leg.Location = 'northeast'; +set(gca, 'SortMethod', 'depth'); From f0c32108b5d8a3ccbd0153e85c017fcd35adf0f2 Mon Sep 17 00:00:00 2001 From: Ross Folkard Date: Fri, 26 May 2023 20:09:31 +0200 Subject: [PATCH 024/201] Update PoolDifMech.m --- Ross/PoolDifMech.m | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Ross/PoolDifMech.m b/Ross/PoolDifMech.m index c0dd541..7cd4456 100644 --- a/Ross/PoolDifMech.m +++ b/Ross/PoolDifMech.m @@ -1099,7 +1099,7 @@ ylim([ax(lidx).YLim(1), 4]); ax(lidx).XAxis.Visible = 'off'; - + @@ -1173,7 +1173,7 @@ [Ncl, Npt, Nconds] = size(PSTH); psthTX = linspace(timeLapse(1),timeLapse(2),Npt); -figure('Color','white', 'Name', 'Pressures'); +fig = figure('Color','white', 'Name', 'Pressures'); yyaxis right @@ -1198,7 +1198,7 @@ hold on for ccond = 1:length(consideredConditions) - medPSTH = median(sum(PSTH(:,1:40,ccond),1,'omitnan')/(Ncl * sweeps * binSz)); + medPSTH = median(sum(PSTH(:,1:40,ccond),1,'omitnan')/(Ncl * sweeps * binSz)); popPSTH = sum(PSTH(:,:,ccond),1,'omitnan')/(Ncl * sweeps * binSz); % popPSTH = popPSTH-medPSTH; popPSTH = smooth(popPSTH, 5); @@ -1218,3 +1218,6 @@ leg.Location = 'northeast'; set(gca, 'SortMethod', 'depth'); +configureFigureToPDF (fig); +saveas(fig,fullfile(figureDir, 'MechPressure+PopPSTHs.emf')); +savefig(fig,fullfile(figureDir, 'MechPressure+PopPSTHs.fig')); \ No newline at end of file From a167c8b48016a74aeb14cef37864d8253509aefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 2 Jun 2023 17:19:38 +0200 Subject: [PATCH 025/201] Adding structure to the mice array --- Emilio/poolBehIndices.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index e00c8b5..210a532 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -23,10 +23,12 @@ oldMouse = ""; mc = 0; mice = []; for cad = animalFolders(:)' - [~, currMouse] = fileparts(cad); + [structPath, currMouse] = fileparts(cad); + [~, structName] = fileparts(structPath); if string(oldMouse) ~= string(currMouse) oldMouse = currMouse; - mice = [mice; struct('Name', currMouse, 'Sessions',[])]; + mice = [mice; struct('Name', currMouse, 'Sessions',[], ... + 'Structure', structName)]; mc = mc + 1; sc = 0; oldSess = ""; end @@ -140,8 +142,8 @@ end end btchName = regexp(batchDir, 'Batch\d+','match'); -save(fullfile(batchDir, btchName+"_BehaviourIndex.mat"), 'mice') -%% +save(fullfile(batchDir, btchName+"_BehaviourIndex.mat"), 'mice', "-append") +%% multiple jittDist = makedist('Normal', 'mu', 0, 'sigma', 1/9); habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... m.Sessions), mice, fnOpts{:}); From dd2ed24af50a9053806a120755d0a25335775540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 2 Jun 2023 17:19:58 +0200 Subject: [PATCH 026/201] Try out to plot behaviour indices --- Emilio/poolBehIndices.m | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 210a532..cb07064 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -181,7 +181,69 @@ lgObj = legend(ax, mNames); set(lgObj, "Box", 'off', 'Color', 'none', 'Location', 'best', 'AutoUpdate', 'off') +%% single +singFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "single", ... + m.Sessions), mice, fnOpts{:}); +behTable = arrayfun(@(m, f) m.Sessions(f{:}).DataTable, mice, singFlag, ... + fnOpts{:}); behTable = cat(1, behTable{:}); +ctrl = behTable{behTable.Conditions == "Control Puff", "BehaviourIndices"}; +ptx = behTable{behTable.Conditions == "PTX", "BehaviourIndices"}; +figure; scatter(ones(size(ptx, 1),2).*[1,2], [ctrl, ptx]) +hold on; plot(ones(2,size(ptx, 1)).*[1;2], [ctrl, ptx]', 'k:') +behTable = [behTable; mice(5).Sessions(2).DataTable] +ctrl = behTable{behTable.Conditions == "Control Puff", "BehaviourIndices"} +ptx = behTable{behTable.Conditions == "PTX", "BehaviourIndices"} +figure; scatter(ones(size(ptx, 1),2).*[1,2], [ctrl, ptx]) +hold on; plot(ones(2,size(ptx, 1)).*[1;2], [ctrl, ptx]', 'k:') +ptx = behTable{contains(behTable.Conditions, "PTX"), "BehaviourIndices"} +figure; scatter(ones(size(ptx, 1),2).*[1,2], [ctrl, ptx]) +xlim([0,3]) +xticks(1:2) +hold on; plot(ones(2,size(ptx, 1)).*[1;2], [ctrl, ptx]', 'k:') +[p, h] = ranksum(ctrl, ptx) +[p, h] = ranksum(ctrl(setdiff(1:6,3)), ptx(setdiff(1:6,3))) +koFlag = true(size(ctrl)); +koFlag(3) = false; +[p, h] = ranksum(ctrl(koFlag), ptx(koFlag)) +[ctrl, ptx] +[ctrl, ptx, koFlag] +[p, h] = ranksum(ctrl(koFlag), ptx(koFlag), "tail", "right") +[p, h] = ranksum(ctrl(koFlag), ptx(koFlag), "tail", "left") +[p, h] = ranksum(ctrl, ptx, "tail", "left") +[p, h] = ranksum(ctrl(koFlag), ptx(koFlag), "tail", "left") +ylim([0,1]) +ylabel('Behaviour index') +xticks(1:2) +xticklabels({'Control', 'PTX'}) +hold on; plot([1,2], max([ctrl, ptx], [], "all")*([1,1]+0.1), 'k') +text(1.5, max([ctrl, ptx],[], "all")*1.1, '\ast', "HorizontalAlignment", 'center', "VerticalAlignment", "bottom") +title(["PTX [60 \muM] in SC";"Significance: left tail"]) +configureFigureToPDF(gcf) +figure; scatter(ones(sum(koFlag),2).*[1,2], [ctrl(koFlag), ptx(koFlag)]) +hold on; plot([1,2], max([ctrl(koFlag), ptx(koFlag)], [], "all")*([1,1]+0.1), 'k') +hold on; plot(ones(2,sum(koFlag)).*[1;2], [ctrl(koFlag), ptx(koFlag)]', 'k:') +xlim([0,3]) +xticks(1:2) +xticklabels({'Control', 'PTX'}) +ylim([0,1]) +ylabel('Behaviour index') +title(["PTX [60 \muM] in SC";"Significance: left tail"]) +configureFigureToPDF(gcf) +saveFigure(gcf, fullfile("Z:\Emilio\SuperiorColliculusExperiments\Roller\GenFigures", "PTX effect"), true); +text(1.5, max([ctrl, ptx],[], "all")*1.1, '\ast', "HorizontalAlignment", 'center', "VerticalAlignment", "bottom") %% +muscFlag = arrayfun(@(m) arrayfun(@(s) cellfun(@(c) ... + any(contains(c, 'musc', ctOpts{:}),2), s.DataTable.Conditions), ... + m.Sessions, fnOpts{:}), mice, fnOpts{:}); +sessFlag = cellfun(@(f) cellfun(@any, f), muscFlag, fnOpts{:}); +behTable2 = arrayfun(@(m, f1) m.Sessions(f1{:}).DataTable, ... + mice, sessFlag, fnOpts{:}); +multFlag = cellfun(@(t) ~isstring(t.Conditions), behTable2); +behTableM = cellfun(@(t, f, s) t(f{s},:), behTable2(multFlag), ... + muscFlag(multFlag), sessFlag(multFlag), fnOpts{:}); +behTableM = cellfun(@(t) table(t.Conditions{:}(:), t.BehaviourIndices{:}(:), ... + 'VariableNames', t.Properties.VariableNames), behTableM, fnOpts{:}); +behTable2 = cat(1, behTableM{:}, behTable2{~multFlag}); %{ dateFlag = arrayfun(@(m) arrayfun(@(s) ~contains(fieldnames(s), 'Date'), ... m.Sessions, fnOpts{:}), mice, fnOpts{:}); From e42d4bc048197fbc570cf3553148d201b1877087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 20 Jun 2023 13:26:18 +0200 Subject: [PATCH 027/201] Create Rescue_trig.m --- Emilio/Rescue_trig.m | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Emilio/Rescue_trig.m diff --git a/Emilio/Rescue_trig.m b/Emilio/Rescue_trig.m new file mode 100644 index 0000000..37910c3 --- /dev/null +++ b/Emilio/Rescue_trig.m @@ -0,0 +1,7 @@ +for ct = lSub(lSub(:,1) > 1e3*fs,:)' + trig(2,ct(1):ct(2)) = trig(2, ct(1):ct(2)) + 2^15 - 230; +end +%% +for ct = (Conditions(2).Triggers(Conditions(2).Triggers(:,1)>expSamples(1),:) - expSamples(1))' + trig(2,ct(1):ct(2)) = trig(2, ct(1):ct(2)) + int16(2^15 - 230); +end \ No newline at end of file From 820bfa55892b0b5b73a0fc38f161159c2ed255ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 30 Jun 2023 18:47:49 +0200 Subject: [PATCH 028/201] Added a testing part to the script --- Jesus/DE_Jittering.m | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index b96bf4b..3b82618 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -864,6 +864,7 @@ fprintf(1, "Found %s!\n", behDir) answ = questdlg('Analyse behaviour?','Behaviour','Yes','No','Yes'); if strcmpi(answ,'Yes') + hstOpts = {'BinMethod', 'integers', 'BinLimits', [-0.5,4.5]}; behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); [behRes, behFigDir] = analyseBehaviour(behDir, 'Condition', possNames(behChCond), ... @@ -877,5 +878,27 @@ biFN = sprintf(biFigPttrn, pAreas); saveFigure(behAreaFig, fullfile(behFigDir, biFN), true, true); + + trMvFlag = arrayfun(@(cr) behRes(1).Results(cr).MovStrucure.MovmentFlags, ... + 1:size(behRes(1).Results,2), fnOpts{:}); trMvFlag = cat(3, trMvFlag{:}); + BIscaleMat = sum(trMvFlag,3); + BIscale = arrayfun(@(cc) BIscaleMat(pairedStim(:,cc), cc), 1:Nccond, ... + fnOpts{:}); + [hg, hg_bin] = cellfun(@(c) histcounts(c, hstOpts{:}), ... + BIscale, fnOpts{:}); + hg = cat(1, hg{:}); hg_bin = cat(1, hg_bin{:}); + %% + figure; bar(0:4, hg./sum(hg,2), 'EdgeColor', 'none'); hold on; + ylim([0,1]); set(gca, axOpts{:}); + legend(consCondNames, 'AutoUpdate','off', lgOpts{:}) + lmbdaHeight = 0.95-(0.15/Nccond)*(0:Nccond-1); + arrayfun(@(pd) scatter(poaDist(pd).lambda, lmbdaHeight(pd), '|',... + 'MarkerEdgeColor', clrMap(pd,:)), 1:Nccond) + + arrayfun(@(pd) line(paramci(poaDist(pd)), ... + lmbdaHeight([pd,pd]), 'Color', clrMap(pd,:), ... + 'Marker', '|'), 1:Nccond) + title(strrep(expName, '_',' ')); xlabel('Moving body parts') + ylabel('Trial proportion') end end \ No newline at end of file From 0f64fa17be6a6c50c98346cbbeb2b3218da3ccba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Sun, 9 Jul 2023 13:20:38 +0200 Subject: [PATCH 029/201] Adding bar plot for proportions --- Jesus/DE_Jittering.m | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 3b82618..f5784d2 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -864,6 +864,7 @@ fprintf(1, "Found %s!\n", behDir) answ = questdlg('Analyse behaviour?','Behaviour','Yes','No','Yes'); if strcmpi(answ,'Yes') + lgOpts = [axOpts(:)', {'Location'}, {'best'}]; hstOpts = {'BinMethod', 'integers', 'BinLimits', [-0.5,4.5]}; behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); @@ -877,28 +878,46 @@ set(behAreaFig, 'UserData', behRes) biFN = sprintf(biFigPttrn, pAreas); - saveFigure(behAreaFig, fullfile(behFigDir, biFN), true, true); - + trMvFlag = arrayfun(@(cr) behRes(1).Results(cr).MovStrucure.MovmentFlags, ... 1:size(behRes(1).Results,2), fnOpts{:}); trMvFlag = cat(3, trMvFlag{:}); BIscaleMat = sum(trMvFlag,3); - BIscale = arrayfun(@(cc) BIscaleMat(pairedStim(:,cc), cc), 1:Nccond, ... + BIscale = arrayfun(@(cc) BIscaleMat(delayFlags(:,cc), cc), 1:Nccond, ... fnOpts{:}); [hg, hg_bin] = cellfun(@(c) histcounts(c, hstOpts{:}), ... BIscale, fnOpts{:}); hg = cat(1, hg{:}); hg_bin = cat(1, hg_bin{:}); + + + [p_amp, h_amp] = ranksum(cat(1, zamp{1,:}), cat(1, zamp{2,:})); %% - figure; bar(0:4, hg./sum(hg,2), 'EdgeColor', 'none'); hold on; - ylim([0,1]); set(gca, axOpts{:}); - legend(consCondNames, 'AutoUpdate','off', lgOpts{:}) + clrMap = lines(Nccond); + countFig = figure; ax(1) = subplot(10,1,1:8); + bar(ax(1), 0:4, hg./sum(hg,2), 'EdgeColor', 'none'); hold on; + poaDist = cellfun(@(bi) fitdist(bi,"Poisson"), BIscale); + ylim(ax(1), [0,1]); set(ax(1), axOpts{:}); + legend(ax(1), consCondNames, 'AutoUpdate','off', lgOpts{:}) lmbdaHeight = 0.95-(0.15/Nccond)*(0:Nccond-1); - arrayfun(@(pd) scatter(poaDist(pd).lambda, lmbdaHeight(pd), '|',... + arrayfun(@(pd) scatter(ax(1), poaDist(pd).lambda, lmbdaHeight(pd), '|',... 'MarkerEdgeColor', clrMap(pd,:)), 1:Nccond) - - arrayfun(@(pd) line(paramci(poaDist(pd)), ... + arrayfun(@(pd) line(ax(1), paramci(poaDist(pd)), ... lmbdaHeight([pd,pd]), 'Color', clrMap(pd,:), ... 'Marker', '|'), 1:Nccond) - title(strrep(expName, '_',' ')); xlabel('Moving body parts') - ylabel('Trial proportion') + [p, chiVal] = arrayfun(@(ps) chi2test(hg(prmSubs(ps,:), :)), ... + 1:size(prmSubs,1)); + ax(2) = subplot(10,1,9:10); + signBeh = arrayfun(@(x) sprintf("%s vs %s p=%.3f", ... + consCondNames(prmSubs(x,:)), p(x)), 1:size(prmSubs,1)); + text(ax(2), 0, -0.3, sprintf('%s vs. %s P=%.3f\n', ... + [consCondNames(prmSubs), string(p(:))]')) + set(ax(2), 'Visible', 'off') + set(countFig, 'UserData', {signBeh, p}) + title(ax(1), strrep(expName, '_',' ')); xlabel(ax(1),'Moving body parts') + ylabel(ax(1),'Trial proportion') + countFigName = sprintf("Count distributions P%s", ... + sprintf(" %.3f", p(:))); + %% + saveFigure(behAreaFig, fullfile(behFigDir, biFN), true, true); + saveFigure(countFig, fullfile(behFigDir, countFigName), true); end end \ No newline at end of file From e0d420e93d487b45a103657de92d388a6062fd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Sun, 9 Jul 2023 14:15:08 +0200 Subject: [PATCH 030/201] Preparing the amplitude comparison --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index f5784d2..69ad409 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -889,7 +889,7 @@ hg = cat(1, hg{:}); hg_bin = cat(1, hg_bin{:}); - [p_amp, h_amp] = ranksum(cat(1, zamp{1,:}), cat(1, zamp{2,:})); + % [p_amp, h_amp] = ranksum(cat(1, zamp{1,:}), cat(1, zamp{2,:})); %% clrMap = lines(Nccond); countFig = figure; ax(1) = subplot(10,1,1:8); From df3f6c2b8f945783e121dc17ec1a27177b166904 Mon Sep 17 00:00:00 2001 From: Ross Folkard Date: Wed, 12 Jul 2023 17:19:00 +0200 Subject: [PATCH 031/201] Create getBurstingMeasuresMUA.m --- Ross/getBurstingMeasuresMUA.m | 142 ++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 Ross/getBurstingMeasuresMUA.m diff --git a/Ross/getBurstingMeasuresMUA.m b/Ross/getBurstingMeasuresMUA.m new file mode 100644 index 0000000..60c676d --- /dev/null +++ b/Ross/getBurstingMeasuresMUA.m @@ -0,0 +1,142 @@ +% function [burstSpkFreq, burstCF, nBursts, nSpikes, eventRatio] = getBurstingMeasuresMUA(UnitID, SpikeTrains, TrialStarts, TimeBefore, TimeAfter, Condition) + +%% + +%% Picking out the desired units +if ~exist("spkSubs") + ind = ismember(sortedData(:,1), gclID); + Spikes = cellfun(@(x) round(x.*fs),sortedData(ind,2),... + 'UniformOutput',false); +else + Spikes = spkSubs; +end + + +%% Parameters + +minSpksperBurst = 2; +Traincutoff = 40 * 10^-3; +ISIcutoff = 6 * 10^-3; +nSpkscutoff = 5; + +timeBeforesecs = 2.25; +timeAftersecs = 2.25; + +consconds = [20, 22, 25]; + + +%% Triggered Spike Times + + +conscondnames = {Conditions(consconds).name}; + +Triggers = {Conditions(consconds).Triggers}; +timeBefore = timeBeforesecs*fs; +timeAfter = timeAftersecs*fs; + +for t = 1:length(Triggers) + triggers = Triggers{t}(:,1); + +spont_window = [triggers-timeBefore, triggers-0.01]; +ev_window = [triggers+0.01, triggers+timeAfter]; + +consSpks = cell(length(Spikes), 2); + +for cu = 1:length(Spikes) + spks = Spikes{cu}; + sp_spks = []; + ev_spks = []; + for ct = 1:length(triggers) + sp_spks = [sp_spks; spks(spks > spont_window(ct,1) & spks < spont_window(ct,2))]; + ev_spks = [ev_spks; spks(spks > ev_window(ct,1) & spks < ev_window(ct,2))]; + end + consSpks{cu,1} = sp_spks; + consSpks{cu,2} = ev_spks; +end + + +%% Spont and Evoked Bursting Measures +% burstSpkFreq = cell(size(consSpks)); +burstCF = cell(size(consSpks)); % no. of spikes belonging to bursts / total spikes +nBursts = cell(size(consSpks)); % no. of bursts +nSpikes = cell(size(consSpks)); % no. of total spikes +bursteventRatio = cell(size(consSpks)); % no. of burst events + + + + +refperiod = 0.001; + +for cu = 1:length(Spikes) + for ct = 1:2 + spks = consSpks{cu,ct}; + if isempty(spks) +% burstSpkFreq{cu,ct} = 0; + burstCF{cu,ct} = 0; + nBursts{cu,ct} = 0; + nSpikes{cu,ct} = 0; + bursteventRatio{cu,ct} = 0; + else + + dim=size(spks); if dim(2)>dim(1),spks=spks';end %consistent column of spike times. + if spks(1) == round(spks(1)) + spks = spks/fs; + end + spks(diff(spks) < refperiod) = []; + ISIs = diff(spks); + Events = [1; find(ISIs > ISIcutoff)]; + Events=unique(Events); + + + + c = 1; + Bursts = []; + for a = 1:length(Events) - 1 + current = Events(a); next = Events(a+1); + if sum(ISIs(current:next-1)) <= Traincutoff && next-current-minSpksperBurst >= 0 && next-current <= nSpkscutoff-1 % min number of spikes per burst has to be greater than 1 + Bursts{c} = (spks(current+1:next)); + c = c + 1; + end + end + current = Events(end); + + if sum(ISIs(current:end)) <= Traincutoff && next-current-minSpksperBurst >= 0 && next-current <= nSpkscutoff-1 % min number of spikes per burst has to be greater than 1 + Bursts{c} = (ISIs(current:end)); + end + if isempty(Bursts) + nBursts{cu,ct} = 0; +% burstSpkFreq{cu,ct} = zeros(10,1); + burstCF{cu,ct} = 0; + bursteventRatio{cu,ct} = 0; + else + nBursts{cu,ct} = length(Bursts); + + bursteventRatio{cu,ct} = length(Bursts)/(length(Events)); + + burstSpikes = cat(1, Bursts{:}); + burstCF{cu,ct} = length(burstSpikes)/length(spks); + + burstSz = zeros(size(Bursts))'; + for a = 1:length(Bursts) + burstSz(a,1) = numel(Bursts{a}); + end +% burstSpkFreq = zeros(10,1); + for a = 1: 10 +% burstSpkFreq(a,1) = sum(burstSz == a); + end + end + nSpikes{cu,ct} = length(spks); + + end + + + + end +end +TriggeredBursts(t).ConditionName = conscondnames{t}; +TriggeredBursts(t).burstCF = burstCF; +TriggeredBursts(t).bursteventRatio = bursteventRatio; +TriggeredBursts(t).nBursts = nBursts; +TriggeredBursts(t).nSpikes = nSpikes; + +end From a72dee6207c935d6e5e31778e7f4efe851e46b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 13 Jul 2023 18:00:07 +0200 Subject: [PATCH 032/201] Saving or appending mice structure --- Emilio/poolBehIndices.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index cb07064..7a9671d 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -142,7 +142,12 @@ end end btchName = regexp(batchDir, 'Batch\d+','match'); -save(fullfile(batchDir, btchName+"_BehaviourIndex.mat"), 'mice', "-append") +behFP = fullfile(batchDir, btchName+"_BehaviourIndex.mat"); +svOpts = {'-mat'}; +if exist(behFP, "file") + svOpts = {'-append'}; +end +save(behFP, "mice", svOpts{:}) %% multiple jittDist = makedist('Normal', 'mu', 0, 'sigma', 1/9); habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... From a3d1081cd680c778289a1c92da87f49be4050a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 13 Jul 2023 18:00:24 +0200 Subject: [PATCH 033/201] Full table for all sessions --- Emilio/poolBehIndices.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 7a9671d..ab12b9b 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -189,8 +189,9 @@ %% single singFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "single", ... m.Sessions), mice, fnOpts{:}); -behTable = arrayfun(@(m, f) m.Sessions(f{:}).DataTable, mice, singFlag, ... - fnOpts{:}); behTable = cat(1, behTable{:}); +behTable = arrayfun(@(m, f) {m.Sessions(f{:}).DataTable}, mice, singFlag, ... + fnOpts{:}); behTable = arrayfun(@(t) cat(1, t{:}{:}), behTable, fnOpts{:}); +behTable = cat(1, behTable{:}); ctrl = behTable{behTable.Conditions == "Control Puff", "BehaviourIndices"}; ptx = behTable{behTable.Conditions == "PTX", "BehaviourIndices"}; figure; scatter(ones(size(ptx, 1),2).*[1,2], [ctrl, ptx]) From 049d7ccdc25e7562fbd892117744f2a061c3449b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 13 Jul 2023 18:00:38 +0200 Subject: [PATCH 034/201] Validation for only 1 condition --- Jesus/DE_Jittering.m | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 69ad409..a130ec9 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -366,18 +366,25 @@ resFP = fullfile(resDir, resFN); % Statistical scatter figure names -prmSubs = nchoosek(1:Nccond,2); Nsf = size(prmSubs,1) + Nccond; -snglSubs = cumsum(Nccond:-1:1); cmbSubs = setdiff(1:Nsf, snglSubs); -cmpCondNames = string(consCondNames(:)); -cmpCondNames = cat(1, cmpCondNames, arrayfun(@(x) ... - consCondNames(prmSubs(x,1)) + " vs. " + ... - consCondNames(prmSubs(x,2)), (1:size(prmSubs, 1))')); stFigSubfix = ""; if metaNameFlag stFigSubfix = stFigSubfix + " " + RW_key + " " + SW_key; end + +cmbSubs = 0; snglSubs = 1; +cmpCondNames = string(consCondNames(:)); prmSubs = ones(1,2); +if Nccond > 1 + prmSubs = nchoosek(1:Nccond,2); Nsf = size(prmSubs,1) + Nccond; + snglSubs = cumsum(Nccond:-1:1); cmbSubs = setdiff(1:Nsf, snglSubs); + cmpCondNames = cat(1, cmpCondNames, arrayfun(@(x) ... + consCondNames(prmSubs(x,1)) + " vs. " + ... + consCondNames(prmSubs(x,2)), (1:size(prmSubs, 1))')); +end stFigFN = fullfile(ephFigDir, "Stat " + cmpCondNames + stFigSubfix); -cmpCondNames_aux([snglSubs, cmbSubs]) = stFigFN; stFigFN = cmpCondNames_aux; +if cmbSubs + cmpCondNames_aux([snglSubs, cmbSubs]) = stFigFN; + stFigFN = cmpCondNames_aux; +end if exist(resFP,"file") && all(arrayfun(@(x) exist(x, "file"), stFigFN)) load(resFP, "Results", "Counts") From 491e0d71c09e6a8f373ec23b2536e9cead47ee90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 21 Jul 2023 19:12:50 +0200 Subject: [PATCH 035/201] Added an option to set plot visibility --- Emilio/AKK/plotThetaProgress.m | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Emilio/AKK/plotThetaProgress.m b/Emilio/AKK/plotThetaProgress.m index 8ed5997..68c3bb3 100644 --- a/Emilio/AKK/plotThetaProgress.m +++ b/Emilio/AKK/plotThetaProgress.m @@ -1,10 +1,25 @@ -function [probFigs] = plotThetaProgress(logMat, thSet, sNames) +function [probFigs] = plotThetaProgress(logMat, thSet, sNames, varargin) %UNTITLED3 Summary of this function goes here % Detailed explanation goes here %% +p = inputParser; + +addRequired(p, 'logMat', @(x) islogical(x{:})) +addRequired(p, 'thSet', @(x) isvector(x{:})) +addRequired(p, 'sNames', @(x) ~isempty(x)) +addParameter(p, 'showPlots', true, @(x) islogical(x) & numel(x) == 1) + +parse(p, logMat, thSet, sNames, varargin{:}) + +logMat = p.Results.logMat; +thSet = p.Results.thSet; +sNames = p.Results.sNames; +showPlots = p.Results.showPlots; + probFigs = gobjects(size(logMat,2),1); for cs = 1:size(logMat,2) - probFigs(cs) = figure; plot(thSet{cs}, sum(logMat{cs})/size(logMat{cs},1),... + probFigs(cs) = figure('Visible', showPlots); + plot(thSet{cs}, sum(logMat{cs})/size(logMat{cs},1),... "DisplayName", sNames(cs)) lgnd = legend("show"); set(lgnd, "Box", "off", "Location", "best"); ylabel("Trial proportion"); set(gca, "Box", "off", "Color", "none"); From 9eca4ef9269f715faffe9ed998bc04ea3fa8c8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 31 Oct 2023 18:37:40 +0100 Subject: [PATCH 036/201] Removed outdated indexing --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index a130ec9..1bcf278 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -471,7 +471,7 @@ %} if ~exist(relSpkFN,'file') || any(~contains(who(rspMF), consVars)) rst = arrayfun(@(x) getRasterFromStack(discStack, ~delayFlags(:,x), ... - filterIdx(3:end), timeLapse, fs, true, true), 1:size(delayFlags,2), ... + filterIdx(2:end), timeLapse, fs, true, true), 1:size(delayFlags,2), ... fnOpts{:}); relativeSpkTmsStruct = struct('name', cellstr(consCondNames), ... 'SpikeTimes', rst); From 6617499376cb0a29f3f826bfe3b8c256a3a11804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 8 Nov 2023 18:07:57 +0100 Subject: [PATCH 037/201] Create parfor_tryout.m --- Emilio/parfor_tryout.m | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Emilio/parfor_tryout.m diff --git a/Emilio/parfor_tryout.m b/Emilio/parfor_tryout.m new file mode 100644 index 0000000..65c5112 --- /dev/null +++ b/Emilio/parfor_tryout.m @@ -0,0 +1,19 @@ +Npr = 1000; +for cl = 1:find(wruIdx) + auxSubs = arrayfun(@(x) randperm(NnzvPcl(cl)), 1:Npr, 'UniformOutput', false); + auxSpks = cellfun(@(s) round(cumsum(ISIVals{cl}(s))*fs), auxSubs, 'UniformOutput', false); + rndStack = getStacks(false, Conditions(chCond).Triggers, onOffStr,... + timeLapse, fs, fs, cat(2, spkSubs{cl}, auxSpks)); + rndStack(2,:,:) = []; + rst2 = arrayfun(@(x) getRasterFromStack(rndStack, ~delayFlags(:,x), ... + [false; true(Npr-2,1)], timeLapse, fs, true, true), ... + 1:size(delayFlags,2), 'UniformOutput', false); + [C, bE] = arrayfun(@(c) histcounts([rst2{1}{c,:}], 'BinWidth', ... + binSz, 'BinLimits', timeLapse), 1:size(rst2{1},1), ... + 'UniformOutput', false); + bE = bE{1}; Ctot = cat(1, C{:}); bC = mean([bE(1:end-1);bE(2:end)]); + P = arrayfun(@(x) fitdist(Ctot(2:end,x), 'Poisson'), 1:size(Ctot,2)); + lambdas = arrayfun(@(x) x.lambda, P); + PI = arrayfun(@(x) x.paramci, P, 'UniformOutput', false); PI = cat(2, PI{:}); + figure; plot(bC, Ctot') +end \ No newline at end of file From 297511291055e86a0c117aba2de61e8d860037c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 21 Nov 2023 16:31:22 +0100 Subject: [PATCH 038/201] Fixed the trigger in the RST --- Jesus/DE_Jittering.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 1bcf278..7f5990a 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -471,8 +471,8 @@ %} if ~exist(relSpkFN,'file') || any(~contains(who(rspMF), consVars)) rst = arrayfun(@(x) getRasterFromStack(discStack, ~delayFlags(:,x), ... - filterIdx(2:end), timeLapse, fs, true, true), 1:size(delayFlags,2), ... - fnOpts{:}); + [false; filterIdx(2:end)], timeLapse, fs, true, true), ... + 1:size(delayFlags,2), fnOpts{:}); relativeSpkTmsStruct = struct('name', cellstr(consCondNames), ... 'SpikeTimes', rst); firstSpkStruct = getFirstSpikeInfo(relativeSpkTmsStruct, configStructure); From 974388afab778f4dcc8245fe39778ca5dd7d606f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 30 Nov 2023 18:29:20 +0100 Subject: [PATCH 039/201] Summary for MC --- Emilio/MC_summary.m | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Emilio/MC_summary.m diff --git a/Emilio/MC_summary.m b/Emilio/MC_summary.m new file mode 100644 index 0000000..eba8049 --- /dev/null +++ b/Emilio/MC_summary.m @@ -0,0 +1,48 @@ +getMI = @(a, c) (c - a) ./ (a + c); +getRC = @(a, c) (c - a) ./ c; +normDist = makedist("Normal", "mu", 0, "sigma", 0.075); + +singFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "single", ... + m.Sessions), mice, fnOpts{:}); +behTable = arrayfun(@(m, f) {m.Sessions(f{:}).DataTable}, mice, singFlag, ... + fnOpts{:}); + +behMI = cellfun(@(m) cellfun(@(t) arrayfun(@(c) ... + getMI(t{1,"BehaviourIndices"}, t{c,"BehaviourIndices"}), ... + 2:size(t,1)), ... + m, fnOpts{:}), ... + behTable, fnOpts{:}); + +behMI = cellfun(@(m) cat(1, m{:}), behMI, fnOpts{:}); + +behRC = cellfun(@(m) cellfun(@(t) arrayfun(@(c) ... + getRC(t{1,"BehaviourIndices"}, t{c,"BehaviourIndices"}), ... + 2:size(t,1)), ... + m, fnOpts{:}), ... + behTable, fnOpts{:}); + +behRC = cellfun(@(m) cat(1, m{:}), behRC, fnOpts{:}); +%% +figure; boxplot([cat(1, behMI{1:2}); padarray(behMI{3}, [0,2], nan, "both")], ... + "Notch", "on"); hold on +title('Modulation index on behaviour index for MC\rightarrowSC excitation') +for cm = 1:3 + auxBMI = padarray(behMI{cm}, [0,(6 - size(behMI{cm},2))/2], nan, "both"); + xpos = reshape(repmat(1:size(auxBMI,2), size(auxBMI, 1 ) , 1 ) + ... + random(normDist, size( auxBMI ) ), [], 1); + scatter(xpos, auxBMI(:), "filled") +end +yline(0, 'k:') +xticklabels(condNames{1}{1}(2:end)) +ylabel('MI(BI)'); xlabel('Conditions') +set(gca, 'Box', 'off', 'Color', 'none') +ylim([-1,1]) +%% +figure; boxplot(cat(1, behMI{4:6}), "Notch", "on"); hold on +title('Modulation index on behaviour index for MC\rightarrowSC inhibition') +for cm = 4:6 + scatter(ones(size(behMI{cm}))+random(normDist, size(behMI{cm})), ... + behMI{cm}, "filled") +end +xticklabels(condNames{4}{1}(2)) +yline(0, 'k:'); set(gca, 'Box', 'off', 'Color', 'none') From 66c9b9e962ed4d52cc1bfa5902136688516ddfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 14 Dec 2023 15:05:14 +0100 Subject: [PATCH 040/201] Bug fix --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 7f5990a..c8841b9 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -900,7 +900,7 @@ %% clrMap = lines(Nccond); countFig = figure; ax(1) = subplot(10,1,1:8); - bar(ax(1), 0:4, hg./sum(hg,2), 'EdgeColor', 'none'); hold on; + bar(ax(1), (0:4)', (hg./sum(hg,2))', 'EdgeColor', 'none'); hold on; poaDist = cellfun(@(bi) fitdist(bi,"Poisson"), BIscale); ylim(ax(1), [0,1]); set(ax(1), axOpts{:}); legend(ax(1), consCondNames, 'AutoUpdate','off', lgOpts{:}) From 73266e28ec1eba54afb457815524777b8167e338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 6 Feb 2024 15:15:55 +0100 Subject: [PATCH 041/201] Create Habituation_prep_4_R.m --- Emilio/Habituation_prep_4_R.m | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Emilio/Habituation_prep_4_R.m diff --git a/Emilio/Habituation_prep_4_R.m b/Emilio/Habituation_prep_4_R.m new file mode 100644 index 0000000..a12f42a --- /dev/null +++ b/Emilio/Habituation_prep_4_R.m @@ -0,0 +1,16 @@ +miceArray = []; +for cm = 1:numel(resTable) + [Np, Ns] = size(resTable{cm}.BehaviourIndices); + sess_id = repmat(1:Ns, Np, 1); sess_id = sess_id(:); + mouse_id = cm + zeros(Np*Ns, 1); + puff_strength = ... + cellfun(@(f) textscan(f, "%fbars"), ... + resTable{cm}.Properties.RowNames); + if any(cellfun(@isempty, puff_strength)) + puff_strength{cellfun(@isempty, puff_strength)} = -1; + end + puff_strength = repmat(cat(1, puff_strength{:}), Ns, 1); + bi_values = resTable{cm}.BehaviourIndices(:); + miceArray = [miceArray; + mouse_id, sess_id, puff_strength, bi_values]; +end \ No newline at end of file From b5ae7976752a9f8c349024709013ea144e6878a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 6 Feb 2024 15:15:59 +0100 Subject: [PATCH 042/201] Create PSTH_percluster_pertrial.m --- Emilio/PSTH_percluster_pertrial.m | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Emilio/PSTH_percluster_pertrial.m diff --git a/Emilio/PSTH_percluster_pertrial.m b/Emilio/PSTH_percluster_pertrial.m new file mode 100644 index 0000000..431988b --- /dev/null +++ b/Emilio/PSTH_percluster_pertrial.m @@ -0,0 +1,13 @@ +binSize = 1e-4; +histOpts = {'BinLimits', vw, 'BinWidth', binSize, ... + 'Normalization', 'count'}; +fnOpts = {'UniformOutput', false}; +psth_u = arrayfun(@(v) cellfun(@(u) histcounts(u, histOpts{:}), ... + relativeSpkTmsStruct(1).SpikeTimes(v,:), fnOpts{:}), ... + 1:size(relativeSpkTmsStruct(1).SpikeTimes,1), fnOpts{:}); +psth_u = cellfun(@(x) cat(1, x{:}), psth_u, fnOpts{:}); +psth_u = cat(3, psth_u{:}); +% psth_u = cat(1, psth_u{:}); +mdl_psth_tx = fit_poly([1,size(psth_u, 2)], vw + [1,-1]*binSize/2, 1); +psth_tx = ( ( 1:size(psth_u, 2) )'.^[1,0] ) * mdl_psth_tx; +% figure; imagesc( psth_tx, [], psth_u) \ No newline at end of file From ff996a40f96fdcceb87270aa0e44895e9fbc0290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 6 Feb 2024 15:16:02 +0100 Subject: [PATCH 043/201] Create Spike_times_for_R.m --- Emilio/Spike_times_for_R.m | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Emilio/Spike_times_for_R.m diff --git a/Emilio/Spike_times_for_R.m b/Emilio/Spike_times_for_R.m new file mode 100644 index 0000000..f27e458 --- /dev/null +++ b/Emilio/Spike_times_for_R.m @@ -0,0 +1,31 @@ +fnOpts = {'UniformOutput', false}; +% N_spikes_pcond = arrayfun(@(c) sum(arrayfun(@(u) ... +% numel([relativeSpkTmsStruct(c).SpikeTimes{u,:}]), ... +% 1:size(relativeSpkTmsStruct(c).SpikeTimes,1))), ... +% 1:length(relativeSpkTmsStruct)); +N_spikes_ptrial_u25 = arrayfun(@(c) cellfun(@(ut) numel(ut), ... + relativeSpkTmsStruct(c).SpikeTimes(25,:)), ... + 1:length(relativeSpkTmsStruct), fnOpts{:}); +% (Neuron), condition, trial, spike time. No neuron information now because +% trying only with unit X (25). +unit_spike_times = zeros(sum([N_spikes_ptrial_u25{:}]), 3); + +dat_i = 1; dat_j = 1; +for ccond = 1:length(relativeSpkTmsStruct) + for cu = 25 + cond_id = repmat(ccond, sum(N_spikes_ptrial_u25{ccond}), 1); + for ctr = 1:size(relativeSpkTmsStruct(ccond).SpikeTimes,2) + if N_spikes_ptrial_u25{ccond}(ctr) + trial_id = repmat(ctr, N_spikes_ptrial_u25{ccond}(ctr), 1); + curr_i = dat_i:N_spikes_ptrial_u25{ccond}(ctr)+dat_i-1; + unit_spike_times(curr_i,2:3) = [trial_id, ... + relativeSpkTmsStruct(ccond).SpikeTimes{cu,ctr}']; + dat_i = dat_i + N_spikes_ptrial_u25{ccond}(ctr); + else + continue + end + end + unit_spike_times(dat_j:sum(N_spikes_ptrial_u25{ccond})+dat_j-1,1) = ... + cond_id; dat_j = dat_j + sum(N_spikes_ptrial_u25{ccond}); + end +end \ No newline at end of file From b27decb6bb59a34a33de3bb4d8753c692ce5c82b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 6 Feb 2024 15:16:21 +0100 Subject: [PATCH 044/201] Re-arranged for better readability --- Jesus/DE_Jittering.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index c8841b9..81441a3 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -875,8 +875,10 @@ hstOpts = {'BinMethod', 'integers', 'BinLimits', [-0.5,4.5]}; behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); - [behRes, behFigDir] = analyseBehaviour(behDir, 'Condition', possNames(behChCond), ... - 'PairedFlags', delayFlags, 'FigureDirectory', FigureDir, ... + [behRes, behFigDir, ~, behData] = analyseBehaviour(behDir, ... + 'Condition', possNames(behChCond), ... + 'PairedFlags', delayFlags, ... + 'FigureDirectory', FigureDir, ... 'ConditionsNames', cellstr(consCondNames)); biFigPttrn = "BehIndex%s"; biFigPttrn = sprintf(biFigPttrn, sprintf(" %s (%%.3f)", consCondNames)); From d5dceaaee3341b77ef9fdd87a57c8b55b2ba39eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 8 Feb 2024 15:57:26 +0100 Subject: [PATCH 045/201] Create first_spike_4_R.m --- Emilio/first_spike_4_R.m | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Emilio/first_spike_4_R.m diff --git a/Emilio/first_spike_4_R.m b/Emilio/first_spike_4_R.m new file mode 100644 index 0000000..d78cc60 --- /dev/null +++ b/Emilio/first_spike_4_R.m @@ -0,0 +1,18 @@ +fnOpts = {'UniformOutput', false}; +Ns_puc = arrayfun(@(c) ... + arrayfun(@(u) ... + cellfun(@(t) all([~isempty(t), t>0, t<0.05]), ... + firstSpkStruct(c).FirstSpikeTimes(u,:)), ... + 1:size(firstSpkStruct(c).FirstSpikeTimes, 1), fnOpts{:}), ... + 1:length(firstSpkStruct), fnOpts{:}); + +fs_puc = arrayfun(@(c) ... + arrayfun(@(u) ... + [repmat(c, sum(Ns_puc{c}{u}), 1), ... + repmat(u, sum(Ns_puc{c}{u}), 1), ... + [firstSpkStruct(c).FirstSpikeTimes{u,Ns_puc{c}{u}}]'], ... + 1:size(firstSpkStruct(c).FirstSpikeTimes, 1), fnOpts{:}), ... + 1:length(firstSpkStruct), fnOpts{:}); + +fs_puc = cellfun(@(c) cat(1, c{ cellfun(@(c2) ~isempty(c2),c) }), fs_puc, fnOpts{:}); +fs_puc = cat(1, fs_puc{:}); \ No newline at end of file From c3bbff48e8bffaeacc263ebf9f3ba5ecdebcb61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 9 Feb 2024 17:29:10 +0100 Subject: [PATCH 046/201] Create Plot_fst_and_BIestimations.m --- Emilio/Plot_fst_and_BIestimations.m | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Emilio/Plot_fst_and_BIestimations.m diff --git a/Emilio/Plot_fst_and_BIestimations.m b/Emilio/Plot_fst_and_BIestimations.m new file mode 100644 index 0000000..ebee0ed --- /dev/null +++ b/Emilio/Plot_fst_and_BIestimations.m @@ -0,0 +1,37 @@ +jitDist = makedist("Normal", "mu", 0, "sigma", 0.1); +vw = [-10, 50]*1e-3; binSize = 5e-4; +histOpts = {'BinLimits', vw, 'BinWidth', binSize, ... + 'Normalization', 'probability'}; +uH = arrayfun(@(c) ... + arrayfun(@(u) ... + histcounts( (params.alpha(:,u,c) + params.g(:,c))*fs_scale + fs_centre, ... + histOpts{:} ), 1:Ncl, fnOpts{:}), 1:Ncond, fnOpts{:}); +uH = cellfun(@(c) cat(1, c{:}), uH, fnOpts{:}); +uH = cat(3, uH{:}); + +[Ncl, Nt, Ncond] = size(uH); + +mdl = fit_poly([1,Nt], vw + [1,-1]*(binSize/2), 1); +tx = ( (1:Nt)'.^[1,0] ) * mdl; + +clrMap = [zeros(1,3); inferno(5)]; +for cu = 1:Ncl + figure; + contour(ones(Nt,1)*(1:6), tx * ones(1,Ncond), squeeze(uH(cu,:,:)), 5); + colormap(inferno(10)) + hold on; + plot(1:6, ... + squeeze(mean( params.alpha(:,cu,:) + reshape(params.g,2e3,1,6), 1 ) ) * ... + fs_scale + fs_centre, "k", "LineWidth", 2) + + arrayfun(@(c) scatter( c+random( jitDist, ... + size([firstSpkStruct(c).FirstSpikeTimes{cu,:}]) ), ... + ... + [firstSpkStruct(c).FirstSpikeTimes{cu,:}], ... + "MarkerEdgeColor","k", "MarkerFaceColor",clrMap(c,:), ... + "MarkerFaceAlpha",0.5), 1:Ncond) + ylim([0,50]*1e-3); set(gca, "Box", "off", "Color", "none"); + yticklabels(yticks*1e3); ylabel('Latency [ms]') + xticks(1:Ncond); xticklabels(string({relativeSpkTmsStruct.name})) + set(get(gca, "YAxis"), "Scale", "log") +end \ No newline at end of file From 99f46169628bfbd069e37afc0004a250fe979f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 9 Feb 2024 17:29:24 +0100 Subject: [PATCH 047/201] Synchrony --- Emilio/PSTH_percluster_pertrial.m | 38 ++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/Emilio/PSTH_percluster_pertrial.m b/Emilio/PSTH_percluster_pertrial.m index 431988b..5089e27 100644 --- a/Emilio/PSTH_percluster_pertrial.m +++ b/Emilio/PSTH_percluster_pertrial.m @@ -1,13 +1,25 @@ -binSize = 1e-4; -histOpts = {'BinLimits', vw, 'BinWidth', binSize, ... - 'Normalization', 'count'}; -fnOpts = {'UniformOutput', false}; -psth_u = arrayfun(@(v) cellfun(@(u) histcounts(u, histOpts{:}), ... - relativeSpkTmsStruct(1).SpikeTimes(v,:), fnOpts{:}), ... - 1:size(relativeSpkTmsStruct(1).SpikeTimes,1), fnOpts{:}); -psth_u = cellfun(@(x) cat(1, x{:}), psth_u, fnOpts{:}); -psth_u = cat(3, psth_u{:}); -% psth_u = cat(1, psth_u{:}); -mdl_psth_tx = fit_poly([1,size(psth_u, 2)], vw + [1,-1]*binSize/2, 1); -psth_tx = ( ( 1:size(psth_u, 2) )'.^[1,0] ) * mdl_psth_tx; -% figure; imagesc( psth_tx, [], psth_u) \ No newline at end of file +histOpts2 = {'BinLimits', [0,0.3], 'BinWidth', 1e-3, 'Normalization', ... + 'probability'}; +binSizes = logspace(-4,-2,100); +b_var = zeros(ceil(diff(histOpts2{2})/histOpts2{4}),length(binSizes),'single'); +ii = 1; +for bz = binSizes + binSize = bz; vw = configStructure.Viewing_window_s; + histOpts = {'BinLimits', vw, 'BinWidth', binSize, ... + 'Normalization', 'count'}; + fnOpts = {'UniformOutput', false}; + psth_u = arrayfun(@(v) cellfun(@(u) histcounts(u, histOpts{:}), ... + relativeSpkTmsStruct(1).SpikeTimes(v,:), fnOpts{:}), ... + 1:size(relativeSpkTmsStruct(1).SpikeTimes,1), fnOpts{:}); + psth_u = cellfun(@(x) cat(1, x{:}), psth_u, fnOpts{:}); + psth_u = cat(3, psth_u{:}); + + %mdl_psth_tx = fit_poly([1,size(psth_u, 2)], vw + [1,-1]*binSize/2, 1); + %psth_tx = ( ( 1:size(psth_u, 2) )'.^[1,0] ) * mdl_psth_tx; + %plot(psth_tx, mean(psth_u, [1,3])) + b_var(:,ii) = histcounts(mean(psth_u, [1,3]), histOpts2{:}); + ii = ii + 1; + % figure; imagesc( psth_tx, [], psth_u) +end +figure; imagesc(1:length(binSizes), histOpts2{2}, log10(b_var+1e-6)) +axis xy; colormap(inferno) \ No newline at end of file From daf492eb9db3d7f7b240e40ff81b720f76a68014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 15 Feb 2024 14:55:23 +0100 Subject: [PATCH 048/201] Putting the data export on hold --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 81441a3..15df339 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -875,7 +875,7 @@ hstOpts = {'BinMethod', 'integers', 'BinLimits', [-0.5,4.5]}; behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); - [behRes, behFigDir, ~, behData] = analyseBehaviour(behDir, ... + [behRes, behFigDir, ~] = analyseBehaviour(behDir, ... 'Condition', possNames(behChCond), ... 'PairedFlags', delayFlags, ... 'FigureDirectory', FigureDir, ... From 7e2f9ed6de67d2f8c739d1745cce5fd18fb3cf69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 15 Feb 2024 17:17:26 +0100 Subject: [PATCH 049/201] Create Plot_rasters_dirty.m --- Emilio/Plot_rasters_dirty.m | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Emilio/Plot_rasters_dirty.m diff --git a/Emilio/Plot_rasters_dirty.m b/Emilio/Plot_rasters_dirty.m new file mode 100644 index 0000000..fc315be --- /dev/null +++ b/Emilio/Plot_rasters_dirty.m @@ -0,0 +1,36 @@ + +figure; hold on +Nu = size(relativeSpkTmsStruct(1).SpikeTimes, 1); +clrMap = hsv(Nu); +for ccond = 1:length(relativeSpkTmsStruct) + for cu = 15 + for ct = 1:size(relativeSpkTmsStruct(ccond).SpikeTimes, 2) + spks_cu_ct = [relativeSpkTmsStruct(ccond).SpikeTimes{cu, ct}]'; + tid = repmat(ct, length(spks_cu_ct), 1); + cid = repmat(cu, length(spks_cu_ct), 1); + scatter3( spks_cu_ct, tid, cid, [], ... + 'MarkerFaceColor', clrMap(cu,:), 'MarkerEdgeColor', 'none', ... + 'MarkerFaceAlpha', 3/4) + end + end +end + +%% +clrMap = [zeros(1,3); lines(length(relativeSpkTmsStruct)-1)]; +cu = 18; +figure; hold on +tc = 1; +for ccond = 1:3 + for ctr = 1:size(relativeSpkTmsStruct(ccond).SpikeTimes, 2) + cspks = relativeSpkTmsStruct(ccond).SpikeTimes{cu,ctr}; + if ~isempty(cspks) + line(cspks, tc, 'Marker', 'o', ... + 'MarkerEdgeColor', 'none', ... + 'MarkerFaceColor', clrMap(ccond,:)) + end + tc = tc + 1; + end +end +yticks(Na/2 + cumsum([0, Na(1:end-1)])); +yticklabels({relativeSpkTmsStruct.name}) +ylim([0, sum(Na)+1]) \ No newline at end of file From 2df0a4dbaaa978d99df470f1df9cb5b7c405d896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 11 Mar 2024 15:08:04 +0100 Subject: [PATCH 050/201] Added 'depth' as a session 'key' --- Emilio/poolBehIndices.m | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index ab12b9b..17486ac 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -30,7 +30,7 @@ mice = [mice; struct('Name', currMouse, 'Sessions',[], ... 'Structure', structName)]; mc = mc + 1; - sc = 0; oldSess = ""; + sc = 0; oldSess = ""; oldDepth = ""; end sessDirs = getSubFolds(cad); % Just date sessions @@ -39,7 +39,9 @@ sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; for csd = sessDirs(:)' curDir = expandName(csd); - currSess = char(regexp(csd.name, '\d{6}', 'match')); + sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})', 'tokens', 'once'); + currSess = sessDateDepth{1}; + depthSess = sessDateDepth{2}; childFolders = getSubFolds(curDir); sessOrgDirs = arrayfun(@(d) string(d.name), childFolders); sessOrgDirs(contains(sessOrgDirs, {'behaviour', 'ephys', ... @@ -49,7 +51,7 @@ behIdxFiles = arrayfun(@(d) dir(fullfile(d, "BehIndex*.fig")), ... behFigDir, fnOpts{:}); behIdxFiles = cat(1, behIdxFiles{:}); if isempty(behIdxFiles) - fprintf(1, 'No new behaviour analysis done! Skipping %s!\n', curDir) + fprintf(1, 'No behaviour analysis done! Skipping %s!\n', curDir) continue end behIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... @@ -75,10 +77,13 @@ dataTable = table(condNames, behIdx, tblOpts{:}); end end - if string(oldSess) ~= string(currSess) - oldSess = currSess; + if ( string(oldSess) ~= string(currSess) ) || ... + ( string(oldDepth) ~= string(depthSess) ) + oldSess = currSess; + oldDepth = depthSess; auxStruct = struct('Date', currSess, ... - 'DataTable', dataTable, 'Type', sessType); + 'DataTable', dataTable, 'Type', sessType, ... + 'Depth', depthSess); if ~isfield(mice, 'Sessions') mice(mc).Sessions = auxStruct; else From 90ae522977276bc72edf8421bde901b70272ca9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 11 Mar 2024 15:08:12 +0100 Subject: [PATCH 051/201] Removed dead code --- Emilio/poolBehIndices.m | 53 ----------------------------------------- 1 file changed, 53 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 17486ac..3d0cb54 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -91,59 +91,6 @@ end sc = sc + 1; end - %{ - if numel(behIdxFiles) > 1 - fprintf(1, "Found more than 1 file! Estimating the correct\n") - Ncond = arrayfun(@(m) arrayfun(@(s) numel(fieldnames(s))-1, ... - m.Sessions), mice, fnOpts{:}); Ncond = cat(1, Ncond{:}); - [~, whr] = min(Ncond - brSz',[],"all"); - if std(brSz) - [~, c] = ind2sub([numel(Ncond), numel(brSz)], whr); - else - posCCN = cellfun(@(bc) arrayfun(@(bs) ... - string(bs.ConditionName), bc), behRes, fnOpts{:}); - c = cellfun(@(nms) any(contains(nms, 'delay', ctOpts{:})), posCCN); - end - fprintf(1, "Chose the following conditions:\n") - fprintf(1, " - %s\n", arrayfun(@(x) string(x.ConditionName), ... - behRes{c})) - elseif isempty(behIdxFig) - fprintf(1, "Found no BehIndex figure!\n") - continue - end - behRes = behRes{c}; - arrayfun(@close, behIdxFig) - consCondNames = arrayfun(@(x) string(x.ConditionName), behRes); - % TODO: fix the condition names and run the loop - ctrFlag = contains(consCondNames, 'control', ctOpts{:}); - delFlag = contains(consCondNames, 'delay', ctOpts{:}); - frqFlag = ~cellfun(@isempty,regexp(consCondNames, lsOpts{:})); - musFlag = contains(consCondNames, 'muscimol', ctOpts{:}); - ptxFlag = contains(consCondNames, 'ptx', ctOpts{:}); - if string(oldSess) ~= string(currSess) - oldSess = currSess; auxStruct = struct('Date', currSess, ... - 'Control', behRes(ctrFlag).BehIndex); - if any(xor(delFlag, frqFlag)) - auxStruct.Laser_continuous = behRes(xor(delFlag, ... - frqFlag)).BehIndex; - end - if any(frqFlag) - auxStruct.Laser_freq = behRes(frqFlag).BehIndex; - end - if any(musFlag) - auxStruct.Muscimol = behRes(musFlag).BehIndex; - end - if any(ptxFlag) - auxStruct.PTX = behRes(ptxFlag).BehIndex; - end - if ~isfield(mice, 'Sessions') - mice(mc).Sessions = auxStruct; - else - mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; - end - sc = sc + 1; - end - %} end end btchName = regexp(batchDir, 'Batch\d+','match'); From 8a416264919cac24b5f1ca427ed4225a42230f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 12 Mar 2024 18:23:24 +0100 Subject: [PATCH 052/201] Think how to integrate the built stack --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 15df339..5861cb4 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -875,7 +875,7 @@ hstOpts = {'BinMethod', 'integers', 'BinLimits', [-0.5,4.5]}; behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); - [behRes, behFigDir, ~] = analyseBehaviour(behDir, ... + [behRes, behFigDir, behData, aInfo] = analyseBehaviour(behDir, ... 'Condition', possNames(behChCond), ... 'PairedFlags', delayFlags, ... 'FigureDirectory', FigureDir, ... From f6f090593f5f274673f65a23df05c33ff3489211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 13 Mar 2024 09:08:02 +0100 Subject: [PATCH 053/201] Create remove_artifact.m --- Emilio/remove_artifact.m | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Emilio/remove_artifact.m diff --git a/Emilio/remove_artifact.m b/Emilio/remove_artifact.m new file mode 100644 index 0000000..707dd41 --- /dev/null +++ b/Emilio/remove_artifact.m @@ -0,0 +1,19 @@ +trig_samples = 5; +Nts = 2*trig_samples + 1; +trig_offset_win = (-trig_samples:trig_samples); +random_triggers = sort( randsample(length(laser_triggers), samples) ); +for cchan = 1:64 + for crt = 1:length(laser_triggers) + artif_win = laser_triggers(crt) + trig_offset_win; + segm = double( data( cchan, artif_win ) ); + correction = segm(1) * ((Nts:-1:1)/(Nts+1)) + ... + segm(end) * ((1:Nts)/(Nts+1)) + ... + rand(1, Nts)*5 - 2.5; + + artif_diff = (correction - segm).^2; + corr_fin = (1 - artif_diff/max(artif_diff)).^3; + segm2 = segm.*corr_fin + (1-corr_fin).*correction; + segm = int16(round(segm2)); + data(cchan, artif_win) = segm; + end +end \ No newline at end of file From 669d39b472e6f3ca2f15b38f7e5a7363900710fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 8 Apr 2024 10:19:32 +0200 Subject: [PATCH 054/201] openfig testing --- Jesus/DE_Jittering.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 5861cb4..93bbd9a 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -31,6 +31,7 @@ end fnOpts = {'UniformOutput', false}; axOpts = {'Box','off','Color','none'}; +fgOpts = {'new', 'visible'}; spk_file_vars = {'spike_times','gclID','Nt','Ns','goods'}; %% Constructing the helper 'global' variables @@ -388,7 +389,7 @@ if exist(resFP,"file") && all(arrayfun(@(x) exist(x, "file"), stFigFN)) load(resFP, "Results", "Counts") - arrayfun(@(x) uiopen(x + ".fig", true), stFigFN) + arrayfun(@(x) openfig(x + ".fig", fgOpts{:}), stFigFN) else % Statistical tests [Results, Counts] = statTests(discStack, delayFlags, timeFlags); @@ -551,7 +552,7 @@ psthFigs); arrayfun(@(f, fn) saveFigure(f, fn), psthFigs(:), psthFP(:)); else - arrayfun(@(f) uiopen(f + ".fig", true), psthFP) + arrayfun(@(f) openfig(f + ".fig", 'visible'), psthFP) end % Z-score PSTH for all units ephysPttrn = 'Z-score all-units PSTH %s Ntrials%s'; From b148e6af230e56ff133fe3bfd1f8df53c15c59e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 8 Apr 2024 10:19:56 +0200 Subject: [PATCH 055/201] Session depth and date --- Emilio/poolBehIndices.m | 42 ++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 3d0cb54..63d7cd8 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -1,4 +1,4 @@ -%#ok<*AGROW,*SAGROW> +%#ok<*AGROW,*SAGROW> %% Auxiliary variables and functions fnOpts = {'UniformOutput', false}; expandName = @(x) fullfile(x.folder, x.name); @@ -11,7 +11,10 @@ %% Assuming 1 level of animal organisation i.e. % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 -batchDir = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch12_ephys.e"; +batchDir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments", ... + "Roller", "Batch18_ephys"); +%Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch15_ephys + childFolders = dir(batchDir); pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), childFolders); @@ -35,13 +38,26 @@ sessDirs = getSubFolds(cad); % Just date sessions onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... - 'match')), sessDirs, fnOpts{:}); + 'match')), sessDirs, fnOpts{:}); sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; for csd = sessDirs(:)' curDir = expandName(csd); - sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})', 'tokens', 'once'); - currSess = sessDateDepth{1}; - depthSess = sessDateDepth{2}; + sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})?', 'tokens', 'once'); + if ~isempty( sessDateDepth ) + currSess = sessDateDepth{1}; + if isempty( sessDateDepth{2} ) + depthSess = ''; + else + depthSess = sessDateDepth{2}; + end + else + currSess = regexp(csd.name, '(\d{6})', 'tokens', 'once'); + if isempty(currSess) + fprintf( 1, "Unable to get session date and depth\n" ); + fprintf( 1, "Skipping: %s %s\n", currMouse, csd.name ) + continue + end + end childFolders = getSubFolds(curDir); sessOrgDirs = arrayfun(@(d) string(d.name), childFolders); sessOrgDirs(contains(sessOrgDirs, {'behaviour', 'ephys', ... @@ -55,8 +71,8 @@ continue end behIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... - behIdxFiles); behRes = arrayfun(@(x) get(x, 'UserData'), ... - behIdxFig, fnOpts{:}); arrayfun(@close, behIdxFig) + behIdxFiles); behRes = arrayfun(@(x) get(x, 'UserData'), ... + behIdxFig, fnOpts{:}); arrayfun(@close, behIdxFig) condNames = cellfun(@(x) arrayfun(@(y) string(y.ConditionName), x), ... behRes, fnOpts{:}); behIdx = cellfun(@(x) arrayfun(@(y) ... y.BehIndex, x), behRes, fnOpts{:}); @@ -112,8 +128,8 @@ rSz = cellfun(@(x) max(cellfun(@(y) numel(y), x)), pBehIdx); cSz = cellfun(@numel, pBehIdx); resBehIdx = arrayfun(@(x,y) nan(x,y), rSz, cSz, fnOpts{:}); -resTable = cell(numel(mice), 1); Nm = numel(mice); -mNames = arrayfun(@(m) m.Name, mice); clrMap = roma(Nm); +resTable = cell(numel(mice), 1); Nm = numel(mice); +mNames = arrayfun(@(m) m.Name, mice); clrMap = roma(Nm); habFig = figure('Name', 'Intensity v.s. index', 'Color', 'w'); ax = axes('Parent', habFig, 'Color', 'none', 'Box', 'off', 'NextPlot', 'add'); x = []; y = []; @@ -133,9 +149,9 @@ mean(resTable{m}.BehaviourIndices,2,'omitnan')', [], clrMap(m,:), ... "filled", "MarkerFaceAlpha", 0.5) end -xticks(ax, 1:max(rSz)); +xticks(ax, 1:max(rSz)); -lgObj = legend(ax, mNames); +lgObj = legend(ax, mNames); set(lgObj, "Box", 'off', 'Color', 'none', 'Location', 'best', 'AutoUpdate', 'off') %% single @@ -200,7 +216,7 @@ behTableM = cellfun(@(t, f, s) t(f{s},:), behTable2(multFlag), ... muscFlag(multFlag), sessFlag(multFlag), fnOpts{:}); behTableM = cellfun(@(t) table(t.Conditions{:}(:), t.BehaviourIndices{:}(:), ... - 'VariableNames', t.Properties.VariableNames), behTableM, fnOpts{:}); + 'VariableNames', t.Properties.VariableNames), behTableM, fnOpts{:}); behTable2 = cat(1, behTableM{:}, behTable2{~multFlag}); %{ dateFlag = arrayfun(@(m) arrayfun(@(s) ~contains(fieldnames(s), 'Date'), ... From 7028807ea0bddd3ff9ba2a553a4991128c87e513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 May 2024 13:33:21 +0200 Subject: [PATCH 056/201] Adaptive comparison --- Emilio/AKK/compareMaxWithThresh.m | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Emilio/AKK/compareMaxWithThresh.m b/Emilio/AKK/compareMaxWithThresh.m index 07971e8..611f7df 100644 --- a/Emilio/AKK/compareMaxWithThresh.m +++ b/Emilio/AKK/compareMaxWithThresh.m @@ -1,10 +1,9 @@ -function [moveFlag] = compareMaxWithThresh(mx, thCell) +function [moveFlag, thCell] = compareMaxWithThresh(mx, cmx) %COMPAREMAXWITHTHRESH compares each column of the maximum value per trial %per signal against a given threshold set. % Detailed explanation goes here, later %% -if isrow(mx) - mx = mx'; -end -moveFlag = mx > thCell{1}; +mdl = fit_poly( [1, 64], [double(cmx)/64, double(cmx)], 1 ); +thCell = { ( ( 1:64 )'.^[1,0] ) * mdl }; +moveFlag = mx(:) > thCell{1}(:)'; end From a5daadead92851e161c75d0250b3cecfb86f9e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 17 Jun 2024 18:03:53 +0200 Subject: [PATCH 057/201] Added the new measurements --- Emilio/poolBehIndices.m | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 63d7cd8..caeafaa 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -64,22 +64,30 @@ 'figures', 'opto'}, ctOpts{:})) = []; behFigDir = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... behFF), childFolders, fnOpts{:}); behFigDir = cat(1, behFigDir{:}); - behIdxFiles = arrayfun(@(d) dir(fullfile(d, "BehIndex*.fig")), ... - behFigDir, fnOpts{:}); behIdxFiles = cat(1, behIdxFiles{:}); - if isempty(behIdxFiles) + aiIdxFiles = arrayfun(@(d) dir(fullfile(d, "Amplitude index*.fig")), ... + behFigDir, fnOpts{:}); aiIdxFiles = cat(1, aiIdxFiles{:}); + if isempty(aiIdxFiles) fprintf(1, 'No behaviour analysis done! Skipping %s!\n', curDir) continue end - behIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... - behIdxFiles); behRes = arrayfun(@(x) get(x, 'UserData'), ... - behIdxFig, fnOpts{:}); arrayfun(@close, behIdxFig) + aiIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... + aiIdxFiles); behRes = arrayfun(@(x) get(x, 'UserData'), ... + aiIdxFig, fnOpts{:}); arrayfun(@close, aiIdxFig) condNames = cellfun(@(x) arrayfun(@(y) string(y.ConditionName), x), ... - behRes, fnOpts{:}); behIdx = cellfun(@(x) arrayfun(@(y) ... - y.BehIndex, x), behRes, fnOpts{:}); + behRes, fnOpts{:}); + behIdx = cellfun(@(x) arrayfun(@(y) [y.Trial_proportion, ... + y.Amplitude_index], x, fnOpts{:} ), behRes, fnOpts{:} ); + pol_unfold = cellfun(@(x) arrayfun(@(y) ... + [ reshape( [y.Results.MovProbability], [], 1 ), ... + reshape( [y.Results.AmplitudeIndex], [], 1 ) ], ... + x, fnOpts{:} ), behRes, fnOpts{:} ); brSz = cellfun(@numel, behRes); c = 1; Nbix = numel(brSz); sessType = 'single'; if Nbix == 1 - dataTable = table([condNames{:}]', [behIdx{:}]', tblOpts{:}); + behIdx = behIdx{:}; + pol_unfold = pol_unfold{:}; + dataTable = table( tocol( [condNames{:}] ), ... + cat( 1, behIdx{:} ), pol_unfold(:), tblOpts{:}); elseif Nbix > 1 % We need to check where are all of these different % measurements are coming from. From e42d4cd9c6064b0701507c83f49fbc0f6ba2e95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 17 Jun 2024 18:04:04 +0200 Subject: [PATCH 058/201] Fixed a logical bug --- Emilio/poolBehIndices.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index caeafaa..4a2e7c3 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -52,6 +52,7 @@ end else currSess = regexp(csd.name, '(\d{6})', 'tokens', 'once'); + depthSess = ''; if isempty(currSess) fprintf( 1, "Unable to get session date and depth\n" ); fprintf( 1, "Skipping: %s %s\n", currMouse, csd.name ) From 086148f0677997d45969144bcdd324525969ab37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 17 Jun 2024 18:04:18 +0200 Subject: [PATCH 059/201] Removed mice with no sessions --- Emilio/poolBehIndices.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 4a2e7c3..9357f85 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -120,6 +120,7 @@ end btchName = regexp(batchDir, 'Batch\d+','match'); behFP = fullfile(batchDir, btchName+"_BehaviourIndex.mat"); +mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From b96cf16e84b6f9856c789441493036556b6d952d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 17 Jun 2024 18:04:32 +0200 Subject: [PATCH 060/201] Runtime changes --- Emilio/poolBehIndices.m | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 9357f85..d735e7b 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -6,13 +6,14 @@ rsOpts = {animalPattern, 'SearchType', 'expression'}; ctOpts = {'IgnoreCase', true}; lsOpts = {'L\d+.\d+', 'match'}; -behFF = "Beh V-0.25 - 0.50 s R5.00 - 400.00 ms"; -tblOpts = {'VariableNames', {'Conditions', 'BehaviourIndices'}}; +behFF = "Beh V-0.45 - 0.50 s R25.00 - 350.00 ms"; +tblOpts = {'VariableNames', {'Conditions', 'Trial_and_Amp_Indices', 'PolygonUnfold'}}; +tocol = @(x) x(:); %% Assuming 1 level of animal organisation i.e. % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 batchDir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments", ... - "Roller", "Batch18_ephys"); + "Roller", "Batch11_ephys.MC" ); %Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch15_ephys childFolders = dir(batchDir); @@ -118,9 +119,9 @@ end end end -btchName = regexp(batchDir, 'Batch\d+','match'); -behFP = fullfile(batchDir, btchName+"_BehaviourIndex.mat"); mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; +btchName = regexp( batchDir, 'Batch\d+','match' ); +behFP = fullfile( batchDir, btchName+"_BehaviourIndex.mat" ); svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From 03784f7a5de85f7cb6cf0a01bfc8780b52af7269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 19 Jun 2024 17:48:06 +0200 Subject: [PATCH 061/201] Polygon pooling --- Emilio/poolBehIndices.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index d735e7b..a29f8e4 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -13,7 +13,7 @@ % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 batchDir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments", ... - "Roller", "Batch11_ephys.MC" ); + "Roller", "Batch13_beh" ); %Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch15_ephys childFolders = dir(batchDir); @@ -97,10 +97,10 @@ if numel(sessOrgDirs) == Nbix % Same folders and measurements. Ideal situation for % several measurements. - dataTable = table(condNames, behIdx, tblOpts{:}, ... + dataTable = table(condNames, behIdx, pol_unfold, tblOpts{:}, ... 'RowNames', sessOrgDirs); else - dataTable = table(condNames, behIdx, tblOpts{:}); + dataTable = table(condNames, behIdx, pol_unfold, tblOpts{:}); end end if ( string(oldSess) ~= string(currSess) ) || ... @@ -127,6 +127,7 @@ svOpts = {'-append'}; end save(behFP, "mice", svOpts{:}) +%{ %% multiple jittDist = makedist('Normal', 'mu', 0, 'sigma', 1/9); habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... @@ -229,7 +230,7 @@ behTableM = cellfun(@(t) table(t.Conditions{:}(:), t.BehaviourIndices{:}(:), ... 'VariableNames', t.Properties.VariableNames), behTableM, fnOpts{:}); behTable2 = cat(1, behTableM{:}, behTable2{~multFlag}); -%{ + dateFlag = arrayfun(@(m) arrayfun(@(s) ~contains(fieldnames(s), 'Date'), ... m.Sessions, fnOpts{:}), mice, fnOpts{:}); mCatg = arrayfun(@(mn) categorical(regexp(mn.Name, '[A-Za-z]{2}', ... From a296dc531392e0d575b9fa4e128279f50549c0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 26 Jun 2024 18:21:23 +0200 Subject: [PATCH 062/201] Baseline distribution --- Emilio/poolBehIndices.m | 51 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index a29f8e4..17d5691 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -7,13 +7,15 @@ ctOpts = {'IgnoreCase', true}; lsOpts = {'L\d+.\d+', 'match'}; behFF = "Beh V-0.45 - 0.50 s R25.00 - 350.00 ms"; -tblOpts = {'VariableNames', {'Conditions', 'Trial_and_Amp_Indices', 'PolygonUnfold'}}; +tblOpts = {'VariableNames', {'Conditions', 'Trial_and_Amp_Indices', 'PolygonUnfold','BaselineL2'}}; +my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); tocol = @(x) x(:); %% Assuming 1 level of animal organisation i.e. % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 batchDir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments", ... - "Roller", "Batch13_beh" ); + "Roller", "Batch11_ephys.MC" ); %Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch15_ephys childFolders = dir(batchDir); @@ -83,13 +85,52 @@ [ reshape( [y.Results.MovProbability], [], 1 ), ... reshape( [y.Results.AmplitudeIndex], [], 1 ) ], ... x, fnOpts{:} ), behRes, fnOpts{:} ); + + % Assuming first condition as control!! + [~, mu_c, sig_c] = cellfun(@(c) arrayfun(@(bp) ... + zscore( bp.Baseline_L2 ), ... + c(1).Results, fnOpts{:} ), ... + behRes , fnOpts{:}); + + Nconds = cellfun(@numel, behRes ); + Nbr = numel( behRes ); + bDist = cell( Nbr, 1 ); + + for cc = 1:Nbr + for ccond = 1:Nconds + for cbp = 1:numel( behRes{cc}(ccond).Results ) + bDist{cc}(cbp, ccond) = fitdist( my_zscore( ... + behRes{cc}(ccond).Results(cbp).Baseline_L2, ... + mu_c{cc}{cbp}, sig_c{cc}{cbp} ), "Kernel", ... + "Kernel", "normal" ); + end + end + end + prmSubs = arrayfun(@(x) nchoosek(1:x,2), Nconds , fnOpts{:} ); + Ncombs = cellfun(@(pr) size( pr, 1 ), prmSubs ); + Nbs = cellfun(@(d) size( d, 1), bDist ); + tvd = cell( Nbr, 1); + for cc = 1:Nbr + if Nconds(cc) > 1 + tvd{cc} = zeros( Nbs(cc), Ncombs(cc) ); + for cr = 1:Ncombs(cc) + ps = prmSubs{cc}(cr,:); + for cbp = 1:Nbs(cc) + tvd{cc}(cbp, cr) = total_var_dist( bDist{cc}(cbp, ps) ); + end + end + else + fprintf(1, 'Unsure what to do\n') + end + end brSz = cellfun(@numel, behRes); c = 1; Nbix = numel(brSz); sessType = 'single'; if Nbix == 1 behIdx = behIdx{:}; pol_unfold = pol_unfold{:}; + bDist = bDist{:}'; dataTable = table( tocol( [condNames{:}] ), ... - cat( 1, behIdx{:} ), pol_unfold(:), tblOpts{:}); + cat( 1, behIdx{:} ), pol_unfold(:), bDist, tblOpts{:}); elseif Nbix > 1 % We need to check where are all of these different % measurements are coming from. @@ -97,10 +138,10 @@ if numel(sessOrgDirs) == Nbix % Same folders and measurements. Ideal situation for % several measurements. - dataTable = table(condNames, behIdx, pol_unfold, tblOpts{:}, ... + dataTable = table(condNames, behIdx, pol_unfold, bDist, tblOpts{:}, ... 'RowNames', sessOrgDirs); else - dataTable = table(condNames, behIdx, pol_unfold, tblOpts{:}); + dataTable = table(condNames, behIdx, pol_unfold,bDist, tblOpts{:}); end end if ( string(oldSess) ~= string(currSess) ) || ... From 593526853cca173553c7b369fa2259ac1623e11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 10 Jul 2024 11:53:46 +0200 Subject: [PATCH 063/201] Fixed logical bug --- Emilio/poolBehIndices.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 17d5691..4f4085f 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -97,7 +97,7 @@ bDist = cell( Nbr, 1 ); for cc = 1:Nbr - for ccond = 1:Nconds + for ccond = 1:Nconds(cc) for cbp = 1:numel( behRes{cc}(ccond).Results ) bDist{cc}(cbp, ccond) = fitdist( my_zscore( ... behRes{cc}(ccond).Results(cbp).Baseline_L2, ... From 550d1d76041c545a1fc2da697f743c6cdf5843ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 10 Jul 2024 11:54:17 +0200 Subject: [PATCH 064/201] Added an announcement for the user --- Emilio/poolBehIndices.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 4f4085f..d4db28f 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -168,6 +168,9 @@ svOpts = {'-append'}; end save(behFP, "mice", svOpts{:}) +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +cat( 1, habFlag{:} ) %{ %% multiple jittDist = makedist('Normal', 'mu', 0, 'sigma', 1/9); From b2da266042681bc77c6ff128ed99760df90c28ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 10 Jul 2024 11:54:25 +0200 Subject: [PATCH 065/201] Runtime changes --- Emilio/poolBehIndices.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index d4db28f..7839eaf 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -15,7 +15,7 @@ % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 batchDir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments", ... - "Roller", "Batch11_ephys.MC" ); + "Roller", "Batch1_ephys" ); %Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch15_ephys childFolders = dir(batchDir); From 0fdbbeeca3ba3bc8ce46369002c9d5da9c5dec14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 12 Jul 2024 11:52:10 +0200 Subject: [PATCH 066/201] Runtime changes --- Emilio/poolBehIndices.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 7839eaf..867b877 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -15,7 +15,7 @@ % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 batchDir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments", ... - "Roller", "Batch1_ephys" ); + "Roller", "Mock" ); %Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch15_ephys childFolders = dir(batchDir); From 58d4f41564d1ab1fa8ac4696e1fb038b6238ad94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 12 Jul 2024 11:52:41 +0200 Subject: [PATCH 067/201] Tryout for finding all animals Example ABCabc123 --- Emilio/poolBehIndices.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolBehIndices.m b/Emilio/poolBehIndices.m index 867b877..65f95fe 100644 --- a/Emilio/poolBehIndices.m +++ b/Emilio/poolBehIndices.m @@ -2,7 +2,7 @@ %% Auxiliary variables and functions fnOpts = {'UniformOutput', false}; expandName = @(x) fullfile(x.folder, x.name); -animalPattern = '[A-Za-z]+\d{1,}'; +animalPattern = '[A-Z][a-z]+\d{1,}'; rsOpts = {animalPattern, 'SearchType', 'expression'}; ctOpts = {'IgnoreCase', true}; lsOpts = {'L\d+.\d+', 'match'}; From 7a420c089dd435cfd589aa74ad08602c877e3a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 13 Aug 2024 18:29:12 +0200 Subject: [PATCH 068/201] Created few new scripts --- Emilio/mice_struct_to_table.m | 17 ++ Emilio/poolEphMI.m | 287 ++++++++++++++++++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 Emilio/mice_struct_to_table.m create mode 100644 Emilio/poolEphMI.m diff --git a/Emilio/mice_struct_to_table.m b/Emilio/mice_struct_to_table.m new file mode 100644 index 0000000..8020e8d --- /dev/null +++ b/Emilio/mice_struct_to_table.m @@ -0,0 +1,17 @@ +fnOpts = { 'UniformOutput', false }; +Ni = arrayfun(@(m) arrayfun(@(s) size( s.Intensities, 1 ), m.Sessions ), ... + mice, fnOpts{:} ); +Nr = sum( cat( 1, Ni{:} ) ); +hab_table = zeros( Nr, 12 ); +cr = 1; +for cm = 1:numel(mice) + for cs = 1:numel(mice(cm).Sessions) + Nism = size( mice(cm).Sessions(cs).Intensities, 1 ); + idxs = (0:Nism-1) + cr; + hab_table(idxs, 1:2) = repmat( [cm,cs], Nism, 1 ); + hab_table(idxs, 3:4) = [mice(cm).Sessions(cs).Intensities, ... + mice(cm).Sessions(cs).BehIndex]; + hab_table(idxs, 5:end) = mice(cm).Sessions(cs).MaxVals; + cr = cr + Nism; + end +end \ No newline at end of file diff --git a/Emilio/poolEphMI.m b/Emilio/poolEphMI.m new file mode 100644 index 0000000..ff367f7 --- /dev/null +++ b/Emilio/poolEphMI.m @@ -0,0 +1,287 @@ +%#ok<*AGROW,*SAGROW> +%% Auxiliary variables and functions +fnOpts = {'UniformOutput', false}; +expandName = @(x) fullfile(x.folder, x.name); +animalPattern = '[a-zA-Z]+\d{1,}'; +rsOpts = {animalPattern, 'SearchType', 'expression'}; +ctOpts = {'IgnoreCase', true}; +lsOpts = {'L\d+.\d+', 'match'}; +ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; +tblOpts = {'VariableNames', {'Conditions', 'Trial_and_Amp_Indices', 'PolygonUnfold','BaselineL2'}}; +my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); +tocol = @(x) x(:); +%% Assuming 1 level of animal organisation i.e. +% BatchX/FolderA/Animal001 +% BatchX/FolderB/Animal002 +batchDir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments", ... + "Roller", "Batch11_ephys.MC"); +%Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch15_ephys + +childFolders = dir(batchDir); + +pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), childFolders); +fileFlag = ~[childFolders.isdir]'; +childFolders(pointFlag | fileFlag) = []; +animalFolders = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... + rsOpts{:}), childFolders, fnOpts{:}); animalFolders = cat(1, animalFolders{:}); +%% Looping animals +oldMouse = ""; +mc = 0; mice = []; +for cad = animalFolders(:)' + [structPath, currMouse] = fileparts(cad); + [~, structName] = fileparts(structPath); + if string(oldMouse) ~= string(currMouse) + oldMouse = currMouse; + mice = [mice; struct('Name', currMouse, 'Sessions',[], ... + 'Structure', structName)]; + mc = mc + 1; + sc = 0; oldSess = ""; oldDepth = ""; + end + sessDirs = getSubFolds(cad); + % Just date sessions + onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... + 'match')), sessDirs, fnOpts{:}); + sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; + for csd = sessDirs(:)' + curDir = expandName(csd); + sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})?', 'tokens', 'once'); + if ~isempty( sessDateDepth ) + currSess = sessDateDepth{1}; + if isempty( sessDateDepth{2} ) + depthSess = ''; + else + depthSess = sessDateDepth{2}; + end + else + currSess = regexp(csd.name, '(\d{6})', 'tokens', 'once'); + depthSess = ''; + if isempty(currSess) + fprintf( 1, "Unable to get session date and depth\n" ); + fprintf( 1, "Skipping: %s %s\n", currMouse, csd.name ) + continue + end + end + childFolders = getSubFolds(curDir); + sessOrgDirs = arrayfun(@(d) string(d.name), childFolders); + sessOrgDirs(contains(sessOrgDirs, {'behaviour', 'ephys', ... + 'figures', 'opto'}, ctOpts{:})) = []; + miFigDir = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... + ephFF, 'SearchType', 'expression'), childFolders, fnOpts{:}); + miFigDir = cat(1, miFigDir{:}); + miIdxFiles = arrayfun(@(d) dir(fullfile(d, "LogMI 2-conditions*.fig")), ... + miFigDir, fnOpts{:}); miIdxFiles = cat(1, miIdxFiles{:}); + if isempty(miIdxFiles) + fprintf(1, 'No ephys analysis done! Skipping %s!\n', curDir) + continue + end + miIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... + miIdxFiles); + MI = arrayfun(@(x) get(x, 'UserData'), miIdxFig, fnOpts{:}); + arrayfun(@close, miIdxFig) + condNames = cellfun(@(x) arrayfun(@(y) string(y.ConditionName), x), ... + MI, fnOpts{:}); + behIdx = cellfun(@(x) arrayfun(@(y) [y.Trial_proportion, ... + y.Amplitude_index], x, fnOpts{:} ), MI, fnOpts{:} ); + pol_unfold = cellfun(@(x) arrayfun(@(y) ... + [ reshape( [y.Results.MovProbability], [], 1 ), ... + reshape( [y.Results.AmplitudeIndex], [], 1 ) ], ... + x, fnOpts{:} ), MI, fnOpts{:} ); + + % Assuming first condition as control!! + [~, mu_c, sig_c] = cellfun(@(c) arrayfun(@(bp) ... + zscore( bp.Baseline_L2 ), ... + c(1).Results, fnOpts{:} ), ... + MI , fnOpts{:}); + + Nconds = cellfun(@numel, MI ); + Nbr = numel( MI ); + bDist = cell( Nbr, 1 ); + + for cc = 1:Nbr + for ccond = 1:Nconds(cc) + for cbp = 1:numel( MI{cc}(ccond).Results ) + bDist{cc}(cbp, ccond) = fitdist( my_zscore( ... + MI{cc}(ccond).Results(cbp).Baseline_L2, ... + mu_c{cc}{cbp}, sig_c{cc}{cbp} ), "Kernel", ... + "Kernel", "normal" ); + end + end + end + prmSubs = arrayfun(@(x) nchoosek(1:x,2), Nconds , fnOpts{:} ); + Ncombs = cellfun(@(pr) size( pr, 1 ), prmSubs ); + Nbs = cellfun(@(d) size( d, 1), bDist ); + tvd = cell( Nbr, 1); + for cc = 1:Nbr + if Nconds(cc) > 1 + tvd{cc} = zeros( Nbs(cc), Ncombs(cc) ); + for cr = 1:Ncombs(cc) + ps = prmSubs{cc}(cr,:); + for cbp = 1:Nbs(cc) + tvd{cc}(cbp, cr) = total_var_dist( bDist{cc}(cbp, ps) ); + end + end + else + fprintf(1, 'Unsure what to do\n') + end + end + brSz = cellfun(@numel, MI); c = 1; Nbix = numel(brSz); + sessType = 'single'; + if Nbix == 1 + behIdx = behIdx{:}; + pol_unfold = pol_unfold{:}; + bDist = bDist{:}'; + dataTable = table( tocol( [condNames{:}] ), ... + cat( 1, behIdx{:} ), pol_unfold(:), bDist, tblOpts{:}); + elseif Nbix > 1 + % We need to check where are all of these different + % measurements are coming from. + sessType = 'multi'; + if numel(sessOrgDirs) == Nbix + % Same folders and measurements. Ideal situation for + % several measurements. + dataTable = table(condNames, behIdx, pol_unfold, bDist, tblOpts{:}, ... + 'RowNames', sessOrgDirs); + else + dataTable = table(condNames, behIdx, pol_unfold,bDist, tblOpts{:}); + end + end + if ( string(oldSess) ~= string(currSess) ) || ... + ( string(oldDepth) ~= string(depthSess) ) + oldSess = currSess; + oldDepth = depthSess; + auxStruct = struct('Date', currSess, ... + 'DataTable', dataTable, 'Type', sessType, ... + 'Depth', depthSess); + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + sc = sc + 1; + end + end +end +mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; +btchName = regexp( batchDir, 'Batch\d+','match' ); +behFP = fullfile( batchDir, btchName+"_BehaviourIndex.mat" ); +svOpts = {'-mat'}; +if exist(behFP, "file") + svOpts = {'-append'}; +end +save(behFP, "mice", svOpts{:}) +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +cat( 1, habFlag{:} ) +%{ +%% multiple +jittDist = makedist('Normal', 'mu', 0, 'sigma', 1/9); +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +habTable = arrayfun(@(m, f) {m.Sessions(f{:}).DataTable}, mice, habFlag, ... + fnOpts{:}); +pBehIdx = cellfun(@(x) cellfun(@(y) cell2mat(y.BehaviourIndices), x, ... + fnOpts{:}), habTable, fnOpts{:}); +Ncc = cellfun(@(x) cellfun(@(y) numel(y), x), pBehIdx, fnOpts{:}); +rSz = cellfun(@(x) max(cellfun(@(y) numel(y), x)), pBehIdx); +cSz = cellfun(@numel, pBehIdx); +resBehIdx = arrayfun(@(x,y) nan(x,y), rSz, cSz, fnOpts{:}); +resTable = cell(numel(mice), 1); Nm = numel(mice); +mNames = arrayfun(@(m) m.Name, mice); clrMap = roma(Nm); +habFig = figure('Name', 'Intensity v.s. index', 'Color', 'w'); +ax = axes('Parent', habFig, 'Color', 'none', 'Box', 'off', 'NextPlot', 'add'); +x = []; y = []; +for m = 1:Nm + mxSub = find(Ncc{m} == rSz(m), 1, "first"); + for ci = 1:cSz(m) + endS = numel(pBehIdx{m}{ci}); + resBehIdx{m}(1:endS,ci) = pBehIdx{m}{ci}; + end + resTable{m} = table(resBehIdx{m}, ... + 'RowNames', mice(m).Sessions(mxSub).DataTable.Row, ... + 'VariableNames', "BehaviourIndices"); + x = [x; reshape(ones(rSz(m), cSz(m)).*(1:rSz(m))', [], 1)]; + y = [y; resTable{m}.BehaviourIndices(:)]; + %scatter(ax, ones(cSz(m),rSz(m)).*(1:rSz(m)) + ... + scatter(ax, (1:rSz(m)) + random(jittDist, [1,rSz(m)]), ... + mean(resTable{m}.BehaviourIndices,2,'omitnan')', [], clrMap(m,:), ... + "filled", "MarkerFaceAlpha", 0.5) +end +xticks(ax, 1:max(rSz)); + +lgObj = legend(ax, mNames); +set(lgObj, "Box", 'off', 'Color', 'none', 'Location', 'best', 'AutoUpdate', 'off') + +%% single +singFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "single", ... + m.Sessions), mice, fnOpts{:}); +behTable = arrayfun(@(m, f) {m.Sessions(f{:}).DataTable}, mice, singFlag, ... + fnOpts{:}); behTable = arrayfun(@(t) cat(1, t{:}{:}), behTable, fnOpts{:}); +behTable = cat(1, behTable{:}); +ctrl = behTable{behTable.Conditions == "Control Puff", "BehaviourIndices"}; +ptx = behTable{behTable.Conditions == "PTX", "BehaviourIndices"}; +figure; scatter(ones(size(ptx, 1),2).*[1,2], [ctrl, ptx]) +hold on; plot(ones(2,size(ptx, 1)).*[1;2], [ctrl, ptx]', 'k:') +behTable = [behTable; mice(5).Sessions(2).DataTable] +ctrl = behTable{behTable.Conditions == "Control Puff", "BehaviourIndices"} +ptx = behTable{behTable.Conditions == "PTX", "BehaviourIndices"} +figure; scatter(ones(size(ptx, 1),2).*[1,2], [ctrl, ptx]) +hold on; plot(ones(2,size(ptx, 1)).*[1;2], [ctrl, ptx]', 'k:') +ptx = behTable{contains(behTable.Conditions, "PTX"), "BehaviourIndices"} +figure; scatter(ones(size(ptx, 1),2).*[1,2], [ctrl, ptx]) +xlim([0,3]) +xticks(1:2) +hold on; plot(ones(2,size(ptx, 1)).*[1;2], [ctrl, ptx]', 'k:') +[p, h] = ranksum(ctrl, ptx) +[p, h] = ranksum(ctrl(setdiff(1:6,3)), ptx(setdiff(1:6,3))) +koFlag = true(size(ctrl)); +koFlag(3) = false; +[p, h] = ranksum(ctrl(koFlag), ptx(koFlag)) +[ctrl, ptx] +[ctrl, ptx, koFlag] +[p, h] = ranksum(ctrl(koFlag), ptx(koFlag), "tail", "right") +[p, h] = ranksum(ctrl(koFlag), ptx(koFlag), "tail", "left") +[p, h] = ranksum(ctrl, ptx, "tail", "left") +[p, h] = ranksum(ctrl(koFlag), ptx(koFlag), "tail", "left") +ylim([0,1]) +ylabel('Behaviour index') +xticks(1:2) +xticklabels({'Control', 'PTX'}) +hold on; plot([1,2], max([ctrl, ptx], [], "all")*([1,1]+0.1), 'k') +text(1.5, max([ctrl, ptx],[], "all")*1.1, '\ast', "HorizontalAlignment", 'center', "VerticalAlignment", "bottom") +title(["PTX [60 \muM] in SC";"Significance: left tail"]) +configureFigureToPDF(gcf) +figure; scatter(ones(sum(koFlag),2).*[1,2], [ctrl(koFlag), ptx(koFlag)]) +hold on; plot([1,2], max([ctrl(koFlag), ptx(koFlag)], [], "all")*([1,1]+0.1), 'k') +hold on; plot(ones(2,sum(koFlag)).*[1;2], [ctrl(koFlag), ptx(koFlag)]', 'k:') +xlim([0,3]) +xticks(1:2) +xticklabels({'Control', 'PTX'}) +ylim([0,1]) +ylabel('Behaviour index') +title(["PTX [60 \muM] in SC";"Significance: left tail"]) +configureFigureToPDF(gcf) +saveFigure(gcf, fullfile("Z:\Emilio\SuperiorColliculusExperiments\Roller\GenFigures", "PTX effect"), true); +text(1.5, max([ctrl, ptx],[], "all")*1.1, '\ast', "HorizontalAlignment", 'center', "VerticalAlignment", "bottom") +%% +muscFlag = arrayfun(@(m) arrayfun(@(s) cellfun(@(c) ... + any(contains(c, 'musc', ctOpts{:}),2), s.DataTable.Conditions), ... + m.Sessions, fnOpts{:}), mice, fnOpts{:}); +sessFlag = cellfun(@(f) cellfun(@any, f), muscFlag, fnOpts{:}); +behTable2 = arrayfun(@(m, f1) m.Sessions(f1{:}).DataTable, ... + mice, sessFlag, fnOpts{:}); +multFlag = cellfun(@(t) ~isstring(t.Conditions), behTable2); +behTableM = cellfun(@(t, f, s) t(f{s},:), behTable2(multFlag), ... + muscFlag(multFlag), sessFlag(multFlag), fnOpts{:}); +behTableM = cellfun(@(t) table(t.Conditions{:}(:), t.BehaviourIndices{:}(:), ... + 'VariableNames', t.Properties.VariableNames), behTableM, fnOpts{:}); +behTable2 = cat(1, behTableM{:}, behTable2{~multFlag}); + +dateFlag = arrayfun(@(m) arrayfun(@(s) ~contains(fieldnames(s), 'Date'), ... + m.Sessions, fnOpts{:}), mice, fnOpts{:}); +mCatg = arrayfun(@(mn) categorical(regexp(mn.Name, '[A-Za-z]{2}', ... + 'match')), mice); +Nfn = cellfun(@(x) cellfun(@sum, x), dateFlag, fnOpts{:}); +values = arrayfun(@(m) arrayfun(@(s) struct2cell(s), m.Sessions, ... + fnOpts{:}), mice, fnOpts{:}); +%} \ No newline at end of file From 20ee987723440b396150662dbe9820090e5ec604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 13 Aug 2024 18:30:17 +0200 Subject: [PATCH 069/201] Overwriting flag for figures --- Jesus/DE_Jittering.m | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 93bbd9a..eba6c43 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -33,6 +33,7 @@ axOpts = {'Box','off','Color','none'}; fgOpts = {'new', 'visible'}; spk_file_vars = {'spike_times','gclID','Nt','Ns','goods'}; +owFlag = true; %% Constructing the helper 'global' variables spkPttrn = "%s_Spike_Times.mat"; @@ -544,15 +545,18 @@ else stims = repmat({zeros(1,Ntc)}, Nccond, 1); end + saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); psthFigs = cellfun(@(p,t,n,ids,s) plotClusterReactivity(p(ordSubs,:), t,... n, timeLapse, binSz, [ids; pclID(ordSubs)], strrep(expName,'_',' '), ... s, csNames), PSTH, trig, num2cell(Na), cellstr(consCondNames), stims); arrayfun(@(f) ylabel(f.Children(end), ... [f.Children(end).YLabel.String, sprintf('^{%s}',orderedStr)]), ... psthFigs); - arrayfun(@(f, fn) saveFigure(f, fn), psthFigs(:), psthFP(:)); + %} + end else - arrayfun(@(f) openfig(f + ".fig", 'visible'), psthFP) + psthFigs = arrayfun(@(f) openfig(f + ".fig", 'visible'), psthFP); + PSTH = arrayfun(@(f) get( f, 'UserData' ), psthFigs, fnOpts{:} ); end % Z-score PSTH for all units ephysPttrn = 'Z-score all-units PSTH %s Ntrials%s'; @@ -562,7 +566,7 @@ if ~exist(ephysFile, 'file') [ppFig, PSTHall] = compareCondPSTHs(cat(3,PSTH{:}), Na, binSz, ... timeLapse, consCondNames); - saveFigure(ppFig, ephysFile, 1); + saveFigure(ppFig, ephysFile, 1, owFlag ); else uiopen(ephysFile, true); end @@ -588,7 +592,7 @@ end lpFP = fullfile(ephFigDir, lpFN); if ~exist(lpFP+".fig", "file") - logFigs = plotLogPSTH(logPSTH); saveFigure(logFigs(1), lpFP, true) + logFigs = plotLogPSTH(logPSTH); saveFigure(logFigs(1), lpFP, true, owFlag ) if numel(logFigs) > 1 saveFigure(logFigs(2), lmiFP, true) popEffects = logFigs(2).UserData; vrs = who(matfile(resFP)); @@ -597,6 +601,7 @@ string(consCondNames(popEffects(x,1)))+" vs "+... string(consCondNames(popEffects(x,2))), 'Value', popEffects(x,3)), ... 1:size(popEffects,1), fnOpts{:})); + saveFigure(logFigs(2), lmiFP, true, owFlag ) if ~any(ismember(vrs,'MIStruct')) fprintf(1,'Adding "MIStruct" to %s\n', resFN) save(resFP, 'MIStruct','-append') @@ -656,7 +661,7 @@ propPieFileName = fullfile(ephFigDir,... sprintf("Whisker responsive proportion pie %s (%dC, %dR)",... C_key, [Ntn-Nrn, Nrn])); -saveFigure(respFig, propPieFileName, 1); +saveFigure(respFig, propPieFileName, 1, owFlag ); % Potentiated, depressed and unmodulated clusters pie if Nccond == 2 potFig = figure("Color", "w"); @@ -668,7 +673,7 @@ modPropPieFigFileName = fullfile(ephFigDir,... sprintf("Modulation proportions pie %s (%dR, %dP, %dD)",... C_key, Nrn - Nrsn, Nrsp, Nrsn - Nrsp)); - saveFigure(potFig, modPropPieFigFileName, 1) + saveFigure(potFig, modPropPieFigFileName, 1, owFlag ) % Modulation index histogram MIFig = figure; histogram(MIspon, hsOpts{:}, "Spontaneous"); hold on; histogram(MIevok, hsOpts{:}, "Evoked"); set(gca, axOpts{:}); @@ -676,7 +681,7 @@ ylabel("Cluster proportion"); lgnd = legend("show"); set(lgnd, "Box", "off", "Location", "best") saveFigure(MIFig, fullfile(ephFigDir,... - "Modulation index dist evoked & after induction "+C_key), 1) + "Modulation index dist evoked & after induction "+C_key), 1, owFlag ) end %% Get significantly different clusters gcans = questdlg(['Do you want to get the waveforms from the',... @@ -785,7 +790,7 @@ timeLapse*1e3); rasFigPath = fullfile(ephFigDir, rasFigName); arrayfun(@(x) set(x,'Color','none'), ax); - saveFigure(rasFig, rasFigPath, 1); + saveFigure(rasFig, rasFigPath, 1, owFlag ); clearvars ax rasFig end %% Response speed characterization @@ -927,7 +932,7 @@ countFigName = sprintf("Count distributions P%s", ... sprintf(" %.3f", p(:))); %% - saveFigure(behAreaFig, fullfile(behFigDir, biFN), true, true); - saveFigure(countFig, fullfile(behFigDir, countFigName), true); + saveFigure(behAreaFig, fullfile(behFigDir, biFN), true, true, owFlag ); + saveFigure(countFig, fullfile(behFigDir, countFigName), true, owFlag ); end end \ No newline at end of file From 8440914062e87ac2e6784c14ba57517dd5b149b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 13 Aug 2024 18:30:41 +0200 Subject: [PATCH 070/201] Accelerated saving --- Jesus/DE_Jittering.m | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index eba6c43..52da95f 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -397,7 +397,9 @@ % Plotting statistical tests [Figs, Results] = scatterSignificance(Results, Counts, consCondNames,... delta_t, gclID); configureFigureToPDF(Figs); - arrayfun(@(x,y) saveFigure(x,y,true), Figs, stFigFN(:)) + parfor cf = 1:numel(Figs) + saveFigure( Figs(cf), stFigFN(cf), true, owFlag ) + end save(resFP, "Results", "Counts", "configStructure", "gclID") end [rclIdx, H, zH] = getSignificantFlags(Results); @@ -545,6 +547,19 @@ else stims = repmat({zeros(1,Ntc)}, Nccond, 1); end + psthFigs = gobjects( numel(PSTH), 1 ); + auxID = pclID(ordSubs); auxStack = discStack(filterIdx,:,:); + PSTH = cell(Nccond,1); trig = PSTH; + parfor cf = 1:Nccond + [PSTH{cf}, trig{cf}] = getPSTH(auxStack, timeLapse, ... + ~delayFlags(:,cf), binSz, fs); + psthFigs(cf) = plotClusterReactivity(PSTH{cf}(ordSubs,:), trig{cf},... + Na(cf), timeLapse, binSz, [consCondNames(cf); auxID], strrep(expName,'_',' '), ... + stims{cf}, csNames); + ylabel(psthFigs(cf).Children(end), ... + [psthFigs(cf).Children(end).YLabel.String, ... + sprintf('^{%s}',orderedStr)]) + set( psthFigs(cf), 'UserData', PSTH{cf} ) saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); psthFigs = cellfun(@(p,t,n,ids,s) plotClusterReactivity(p(ordSubs,:), t,... n, timeLapse, binSz, [ids; pclID(ordSubs)], strrep(expName,'_',' '), ... From b817e6188a74f544eb6cffbc66d1ebf0aeed03ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 13 Aug 2024 18:31:00 +0200 Subject: [PATCH 071/201] Removed unused code --- Jesus/DE_Jittering.m | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 52da95f..bc0e814 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -467,12 +467,7 @@ consVars = {'relativeSpkTmsStruct', 'firstSpkStruct', ... 'SpontaneousStruct', 'configStructure'}; rspMF = matfile(fullfile(dataDir, relSpkFN)); -%{ -relSpkFN =... - sprintf('%s RW%.2f - %.2f ms SW%.2f - %.2f ms VW%.2f - %.2f ms %s (%s) exportSpkTms.mat',... - expName, responseWindow*1e3, spontaneousWindow*1e3,... - timeLapse*1e3, Conditions(chCond).name, filtStr); -%} + if ~exist(relSpkFN,'file') || any(~contains(who(rspMF), consVars)) rst = arrayfun(@(x) getRasterFromStack(discStack, ~delayFlags(:,x), ... [false; filterIdx(2:end)], timeLapse, fs, true, true), ... From c54e28fa12fbf8a05d61802507b4c0720b700cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 13 Aug 2024 18:31:11 +0200 Subject: [PATCH 072/201] Few small changes --- Jesus/DE_Jittering.m | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index bc0e814..cc90a69 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -520,8 +520,8 @@ csNames = fieldnames(Triggers); end Nbn = diff(timeLapse)/binSz; -if (Nbn - round(Nbn)) ~= 0 - Nbn = ceil(Nbn); +if (Nbn - round( Nbn )) ~= 0 + Nbn = ceil( Nbn ); end %psthTx = (0:Nbn-1) * binSz + timeLapse(1); @@ -556,6 +556,7 @@ sprintf('^{%s}',orderedStr)]) set( psthFigs(cf), 'UserData', PSTH{cf} ) saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); + %{ psthFigs = cellfun(@(p,t,n,ids,s) plotClusterReactivity(p(ordSubs,:), t,... n, timeLapse, binSz, [ids; pclID(ordSubs)], strrep(expName,'_',' '), ... s, csNames), PSTH, trig, num2cell(Na), cellstr(consCondNames), stims); @@ -580,7 +581,7 @@ else uiopen(ephysFile, true); end -clearvars ppFig ephysPttrn ephysName ephysFile +clearvars ppFig ephysPttrn ephysName ephysFile aux* %% Log PSTH Nbin = 64; ncl = size(relativeSpkTmsStruct(1).SpikeTimes,1); @@ -604,21 +605,22 @@ if ~exist(lpFP+".fig", "file") logFigs = plotLogPSTH(logPSTH); saveFigure(logFigs(1), lpFP, true, owFlag ) if numel(logFigs) > 1 - saveFigure(logFigs(2), lmiFP, true) - popEffects = logFigs(2).UserData; vrs = who(matfile(resFP)); + popEffects = logFigs(2).UserData; MIStruct = struct('ConditionNames', consCondNames, ... 'MI', arrayfun(@(x) struct('Comparative', ... string(consCondNames(popEffects(x,1)))+" vs "+... string(consCondNames(popEffects(x,2))), 'Value', popEffects(x,3)), ... 1:size(popEffects,1), fnOpts{:})); + set( logFigs(2), 'UserData', MIStruct ); saveFigure(logFigs(2), lmiFP, true, owFlag ) + vrs = who(matfile(resFP)); if ~any(ismember(vrs,'MIStruct')) fprintf(1,'Adding "MIStruct" to %s\n', resFN) save(resFP, 'MIStruct','-append') end end else - uiopen(lpFP+".fig", true) + logFigs = uiopen(lpFP+".fig", true); load(resFP, "MIstruct") if Nccond > 1 uiopen(lmiFP+".fig",true) From e3a25e4ef73a706689151db0ecca5bdbf86c3fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 15 Aug 2024 18:22:14 +0200 Subject: [PATCH 073/201] Possible working of ephys MI Pool --- Emilio/poolEphMI.m | 86 +++++++++------------------------------------- 1 file changed, 16 insertions(+), 70 deletions(-) diff --git a/Emilio/poolEphMI.m b/Emilio/poolEphMI.m index ff367f7..67a130d 100644 --- a/Emilio/poolEphMI.m +++ b/Emilio/poolEphMI.m @@ -7,7 +7,7 @@ ctOpts = {'IgnoreCase', true}; lsOpts = {'L\d+.\d+', 'match'}; ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; -tblOpts = {'VariableNames', {'Conditions', 'Trial_and_Amp_Indices', 'PolygonUnfold','BaselineL2'}}; +tblOpts = {'VariableNames', {'Conditions', 'MI'}}; my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); tocol = @(x) x(:); @@ -15,7 +15,7 @@ % BatchX/FolderA/Animal001 % BatchX/FolderB/Animal002 batchDir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments", ... - "Roller", "Batch11_ephys.MC"); + "Roller", "Batch17_ephys.MC"); %Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch15_ephys childFolders = dir(batchDir); @@ -77,75 +77,21 @@ end miIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... miIdxFiles); - MI = arrayfun(@(x) get(x, 'UserData'), miIdxFig, fnOpts{:}); - arrayfun(@close, miIdxFig) - condNames = cellfun(@(x) arrayfun(@(y) string(y.ConditionName), x), ... - MI, fnOpts{:}); - behIdx = cellfun(@(x) arrayfun(@(y) [y.Trial_proportion, ... - y.Amplitude_index], x, fnOpts{:} ), MI, fnOpts{:} ); - pol_unfold = cellfun(@(x) arrayfun(@(y) ... - [ reshape( [y.Results.MovProbability], [], 1 ), ... - reshape( [y.Results.AmplitudeIndex], [], 1 ) ], ... - x, fnOpts{:} ), MI, fnOpts{:} ); - - % Assuming first condition as control!! - [~, mu_c, sig_c] = cellfun(@(c) arrayfun(@(bp) ... - zscore( bp.Baseline_L2 ), ... - c(1).Results, fnOpts{:} ), ... - MI , fnOpts{:}); - - Nconds = cellfun(@numel, MI ); - Nbr = numel( MI ); - bDist = cell( Nbr, 1 ); - - for cc = 1:Nbr - for ccond = 1:Nconds(cc) - for cbp = 1:numel( MI{cc}(ccond).Results ) - bDist{cc}(cbp, ccond) = fitdist( my_zscore( ... - MI{cc}(ccond).Results(cbp).Baseline_L2, ... - mu_c{cc}{cbp}, sig_c{cc}{cbp} ), "Kernel", ... - "Kernel", "normal" ); - end - end - end - prmSubs = arrayfun(@(x) nchoosek(1:x,2), Nconds , fnOpts{:} ); - Ncombs = cellfun(@(pr) size( pr, 1 ), prmSubs ); - Nbs = cellfun(@(d) size( d, 1), bDist ); - tvd = cell( Nbr, 1); - for cc = 1:Nbr - if Nconds(cc) > 1 - tvd{cc} = zeros( Nbs(cc), Ncombs(cc) ); - for cr = 1:Ncombs(cc) - ps = prmSubs{cc}(cr,:); - for cbp = 1:Nbs(cc) - tvd{cc}(cbp, cr) = total_var_dist( bDist{cc}(cbp, ps) ); - end - end - else - fprintf(1, 'Unsure what to do\n') - end + MI = arrayfun(@(x) get(x, 'UserData'), miIdxFig, fnOpts{:} ); + arrayfun(@close, miIdxFig); + switch class(MI{1}) + case 'cell' + condNames = string( cat( 1, MI{:}(1:2) ) ); + condNames = join( [condNames(1), "vs", condNames(2)] ); + miVal = cat( 1, MI{:}{3} ); + case 'struct' + condNames = cellfun( @(m) m.MI.Comparative, MI ); + miVal = cellfun( @(m) m.MI.Value, MI ); end - brSz = cellfun(@numel, MI); c = 1; Nbix = numel(brSz); + Nbix = numel(MI); c = 1; sessType = 'single'; - if Nbix == 1 - behIdx = behIdx{:}; - pol_unfold = pol_unfold{:}; - bDist = bDist{:}'; - dataTable = table( tocol( [condNames{:}] ), ... - cat( 1, behIdx{:} ), pol_unfold(:), bDist, tblOpts{:}); - elseif Nbix > 1 - % We need to check where are all of these different - % measurements are coming from. - sessType = 'multi'; - if numel(sessOrgDirs) == Nbix - % Same folders and measurements. Ideal situation for - % several measurements. - dataTable = table(condNames, behIdx, pol_unfold, bDist, tblOpts{:}, ... - 'RowNames', sessOrgDirs); - else - dataTable = table(condNames, behIdx, pol_unfold,bDist, tblOpts{:}); - end - end + dataTable = table( condNames, miVal, tblOpts{:} ); + if ( string(oldSess) ~= string(currSess) ) || ... ( string(oldDepth) ~= string(depthSess) ) oldSess = currSess; @@ -164,7 +110,7 @@ end mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; btchName = regexp( batchDir, 'Batch\d+','match' ); -behFP = fullfile( batchDir, btchName+"_BehaviourIndex.mat" ); +behFP = fullfile( batchDir, btchName+"_EphMI.mat" ); svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From 9cf7b1beff302ebece85f76fffa34961c0270c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 15 Aug 2024 18:22:37 +0200 Subject: [PATCH 074/201] Redundant data saving --- Jesus/DE_Jittering.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index cc90a69..66feeee 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -570,7 +570,7 @@ PSTH = arrayfun(@(f) get( f, 'UserData' ), psthFigs, fnOpts{:} ); end % Z-score PSTH for all units -ephysPttrn = 'Z-score all-units PSTH %s Ntrials%s'; +ephysPttrn = 'Z-score all-units PSTH %s Ntrials%s.fig'; ephysName = sprintf(ephysPttrn, sprintf('%s ', consCondNames{:}), ... sprintf(' %d', Na)); ephysFile = fullfile(ephFigDir, ephysName); @@ -608,8 +608,8 @@ popEffects = logFigs(2).UserData; MIStruct = struct('ConditionNames', consCondNames, ... 'MI', arrayfun(@(x) struct('Comparative', ... - string(consCondNames(popEffects(x,1)))+" vs "+... - string(consCondNames(popEffects(x,2))), 'Value', popEffects(x,3)), ... + string(popEffects{x,1})+" vs "+... + string(popEffects{x,2}), 'Value', popEffects{x,3}), ... 1:size(popEffects,1), fnOpts{:})); set( logFigs(2), 'UserData', MIStruct ); saveFigure(logFigs(2), lmiFP, true, owFlag ) @@ -620,10 +620,10 @@ end end else - logFigs = uiopen(lpFP+".fig", true); + logFigs = openfig(lpFP+".fig"); load(resFP, "MIstruct") if Nccond > 1 - uiopen(lmiFP+".fig",true) + logFigs(2) = openfig(lmiFP+".fig"); end end %% Cluster population proportions From baed9fe191ada770bc9761050e89523520cbfd42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 26 Aug 2024 19:32:04 +0200 Subject: [PATCH 075/201] Create neg_log_lik_lnp.m --- Emilio/neg_log_lik_lnp.m | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Emilio/neg_log_lik_lnp.m diff --git a/Emilio/neg_log_lik_lnp.m b/Emilio/neg_log_lik_lnp.m new file mode 100644 index 0000000..63adce3 --- /dev/null +++ b/Emilio/neg_log_lik_lnp.m @@ -0,0 +1,5 @@ +function nllik = neg_log_lik_lnp(theta, X, y) +lambda = exp( X * theta ); +log_lik = y' * log( lambda ) - sum( lambda ); +nllik = -log_lik; +end \ No newline at end of file From a69471753f0c7dd7785703595d99f1add96f3cc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Sep 2024 10:34:46 +0200 Subject: [PATCH 076/201] Saving logPSTH structure --- Jesus/DE_Jittering.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 66feeee..9324b4e 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -626,6 +626,11 @@ logFigs(2) = openfig(lmiFP+".fig"); end end + +logRF = fullfile( ephFigDir, "LogPSTH_Structure.mat" ); +if ~exist( logRF, 'file' ) + save( logRF, "logPSTH" ) +end %% Cluster population proportions % Responsive and unresponsive cells, significantly potentiated or depressed % and unmodulated. From 48c42d246408220b77d1768cae5b74e8fb1318ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Sep 2024 17:48:42 +0200 Subject: [PATCH 077/201] Fixed name bugs --- Jesus/DE_Jittering.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 9324b4e..8b37e0e 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -388,7 +388,7 @@ stFigFN = cmpCondNames_aux; end -if exist(resFP,"file") && all(arrayfun(@(x) exist(x, "file"), stFigFN)) +if exist(resFP,"file") && all(arrayfun(@(x) exist(x, "file"), stFigFN + ".fig")) load(resFP, "Results", "Counts") arrayfun(@(x) openfig(x + ".fig", fgOpts{:}), stFigFN) else @@ -468,7 +468,8 @@ 'SpontaneousStruct', 'configStructure'}; rspMF = matfile(fullfile(dataDir, relSpkFN)); -if ~exist(relSpkFN,'file') || any(~contains(who(rspMF), consVars)) +if ~exist( fullfile( dataDir, relSpkFN ),'file') || ... + any(~contains(who(rspMF), consVars)) rst = arrayfun(@(x) getRasterFromStack(discStack, ~delayFlags(:,x), ... [false; filterIdx(2:end)], timeLapse, fs, true, true), ... 1:size(delayFlags,2), fnOpts{:}); From c07e1d509c5d80b39fe819cf2a3af75ceae41ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Sep 2024 17:49:09 +0200 Subject: [PATCH 078/201] Fixed logical bugs --- Jesus/DE_Jittering.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 8b37e0e..438be7c 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -533,9 +533,9 @@ end % PSTH construction psthFP = fullfile(ephFigDir, psthFN); -[PSTH, trig] = arrayfun(@(x) getPSTH(discStack(filterIdx,:,:), ... - timeLapse, ~delayFlags(:,x), binSz, fs), 1:Nccond, fnOpts{:}); if any(arrayfun(@(x) ~exist(x+".fig","file"), psthFP)) + [PSTH, trig] = arrayfun(@(x) getPSTH(discStack(filterIdx,:,:), ... + timeLapse, ~delayFlags(:,x), binSz, fs), 1:Nccond, fnOpts{:}); if exist('cst', 'var') && ~isempty(cst) % Take into account covariance for signals. stims = arrayfun(@(x) mean(cst(:,:,delayFlags(:,x)),3), 1:Nccond, ... @@ -569,6 +569,10 @@ else psthFigs = arrayfun(@(f) openfig(f + ".fig", 'visible'), psthFP); PSTH = arrayfun(@(f) get( f, 'UserData' ), psthFigs, fnOpts{:} ); + if all(cellfun(@(c)isempty(c),PSTH)) + [PSTH, trig] = arrayfun(@(x) getPSTH(discStack(filterIdx,:,:), ... + timeLapse, ~delayFlags(:,x), binSz, fs), 1:Nccond, fnOpts{:}); + end end % Z-score PSTH for all units ephysPttrn = 'Z-score all-units PSTH %s Ntrials%s.fig'; From 0c98955674250dc265acbc6e181837df5fa44833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Sep 2024 17:49:25 +0200 Subject: [PATCH 079/201] Removed useless code --- Jesus/DE_Jittering.m | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 438be7c..b5b84a4 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -545,7 +545,7 @@ end psthFigs = gobjects( numel(PSTH), 1 ); auxID = pclID(ordSubs); auxStack = discStack(filterIdx,:,:); - PSTH = cell(Nccond,1); trig = PSTH; + PSTH = cell(Nccond,1); %trig = PSTH; parfor cf = 1:Nccond [PSTH{cf}, trig{cf}] = getPSTH(auxStack, timeLapse, ... ~delayFlags(:,cf), binSz, fs); @@ -557,14 +557,6 @@ sprintf('^{%s}',orderedStr)]) set( psthFigs(cf), 'UserData', PSTH{cf} ) saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); - %{ - psthFigs = cellfun(@(p,t,n,ids,s) plotClusterReactivity(p(ordSubs,:), t,... - n, timeLapse, binSz, [ids; pclID(ordSubs)], strrep(expName,'_',' '), ... - s, csNames), PSTH, trig, num2cell(Na), cellstr(consCondNames), stims); - arrayfun(@(f) ylabel(f.Children(end), ... - [f.Children(end).YLabel.String, sprintf('^{%s}',orderedStr)]), ... - psthFigs); - %} end else psthFigs = arrayfun(@(f) openfig(f + ".fig", 'visible'), psthFP); @@ -852,7 +844,7 @@ % Arranging the auto-correlograms out of the cross-correlograms into a % single matrix try - acorrs = cellfun(@(x) x(1,:), corrs, 'UniformOutput', 0); + acorrs = cellfun(@(x) x(1,:), corrs, fnOpts{:} ); catch fprintf(1, 'No correlograms in the workspace!\n') end From 7c0f1123b6c4b768d53a7aa99acf6a4712b49734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Sep 2024 17:49:41 +0200 Subject: [PATCH 080/201] Saved a more sensible logPSTH file --- Jesus/DE_Jittering.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index b5b84a4..a4ae816 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -624,7 +624,9 @@ end end -logRF = fullfile( ephFigDir, "LogPSTH_Structure.mat" ); +logRF = fullfile( ephFigDir, ... + sprintf( "LogPSTH_Structure %s %d-conditions NB%d", ... + logPSTH.Normalization, Nccond, Nbin ) ); if ~exist( logRF, 'file' ) save( logRF, "logPSTH" ) end From 15b626e9db2b1e15c52035a81b54aebca86f6fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Sep 2024 17:49:50 +0200 Subject: [PATCH 081/201] Runtime changes --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index a4ae816..e378868 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -33,7 +33,7 @@ axOpts = {'Box','off','Color','none'}; fgOpts = {'new', 'visible'}; spk_file_vars = {'spike_times','gclID','Nt','Ns','goods'}; -owFlag = true; +owFlag = false; %% Constructing the helper 'global' variables spkPttrn = "%s_Spike_Times.mat"; From 5a2e7f7f3566419832238dac42eb9e1b876abf3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Sep 2024 17:50:07 +0200 Subject: [PATCH 082/201] Updated for the 20-50 and 50-200 windows --- Emilio/poolEphMI.m | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/Emilio/poolEphMI.m b/Emilio/poolEphMI.m index 67a130d..75282bd 100644 --- a/Emilio/poolEphMI.m +++ b/Emilio/poolEphMI.m @@ -9,6 +9,7 @@ ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; tblOpts = {'VariableNames', {'Conditions', 'MI'}}; my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +getMI = @(x,d) diff(x, 1, d)./sum(x, d); total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); tocol = @(x) x(:); %% Assuming 1 level of animal organisation i.e. @@ -69,29 +70,26 @@ miFigDir = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... ephFF, 'SearchType', 'expression'), childFolders, fnOpts{:}); miFigDir = cat(1, miFigDir{:}); - miIdxFiles = arrayfun(@(d) dir(fullfile(d, "LogMI 2-conditions*.fig")), ... - miFigDir, fnOpts{:}); miIdxFiles = cat(1, miIdxFiles{:}); + miIdxFiles = arrayfun(@(d) dir( fullfile( d, ... + "LogPSTH_Structure*.mat" ) ), miFigDir, fnOpts{:} ); + miIdxFiles = cat( 1, miIdxFiles{:} ); if isempty(miIdxFiles) fprintf(1, 'No ephys analysis done! Skipping %s!\n', curDir) continue end - miIdxFig = arrayfun(@(x) openfig(expandName(x), 'invisible'), ... - miIdxFiles); - MI = arrayfun(@(x) get(x, 'UserData'), miIdxFig, fnOpts{:} ); - arrayfun(@close, miIdxFig); - switch class(MI{1}) - case 'cell' - condNames = string( cat( 1, MI{:}(1:2) ) ); - condNames = join( [condNames(1), "vs", condNames(2)] ); - miVal = cat( 1, MI{:}{3} ); - case 'struct' - condNames = cellfun( @(m) m.MI.Comparative, MI ); - miVal = cellfun( @(m) m.MI.Value, MI ); - end - Nbix = numel(MI); c = 1; + % miIdxStr = arrayfun(@(x) load( expandName(x), 'logPSTH' ), miIdxFiles); + load( expandName(miIdxFiles), 'logPSTH' ); + lp_mu = squeeze( mean( ... + logPSTH.LogPSTH(:,:,logPSTH.indexMIComparison) ) ); + muMI = getMI( lp_mu, 2 ); + bmot_MI = mean( muMI( ~(logPSTH.TimeAxis < 5e-2) ) ); + sens_MI = mean( muMI( logPSTH.TimeAxis < 5e-2) ); + miVal = [sens_MI, bmot_MI]; + condNames = logPSTH.ConditionNames( logPSTH.indexMIComparison ); + condNames = join([condNames(1), "v", condNames(2)]); + sessType = 'single'; dataTable = table( condNames, miVal, tblOpts{:} ); - if ( string(oldSess) ~= string(currSess) ) || ... ( string(oldDepth) ~= string(depthSess) ) oldSess = currSess; @@ -110,7 +108,7 @@ end mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; btchName = regexp( batchDir, 'Batch\d+','match' ); -behFP = fullfile( batchDir, btchName+"_EphMI.mat" ); +behFP = fullfile( batchDir, btchName+"_EphMI_sm.mat" ); svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From c16091041cc61203a33e0f3b45ab4f5ca8af25ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 5 Sep 2024 18:29:32 +0200 Subject: [PATCH 083/201] No big change --- Emilio/poolEphMI.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphMI.m b/Emilio/poolEphMI.m index 75282bd..1a5b8d3 100644 --- a/Emilio/poolEphMI.m +++ b/Emilio/poolEphMI.m @@ -29,7 +29,7 @@ %% Looping animals oldMouse = ""; mc = 0; mice = []; -for cad = animalFolders(:)' +for cad = tocol(animalFolders)' [structPath, currMouse] = fileparts(cad); [~, structName] = fileparts(structPath); if string(oldMouse) ~= string(currMouse) From d09f0904d878a4ccb36b0e7f71f0106f2d2bf69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 5 Sep 2024 18:29:37 +0200 Subject: [PATCH 084/201] Create iegRNs_AmplitudeIndexPool.m --- Emilio/iegRNs_AmplitudeIndexPool.m | 111 +++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Emilio/iegRNs_AmplitudeIndexPool.m diff --git a/Emilio/iegRNs_AmplitudeIndexPool.m b/Emilio/iegRNs_AmplitudeIndexPool.m new file mode 100644 index 0000000..1182be9 --- /dev/null +++ b/Emilio/iegRNs_AmplitudeIndexPool.m @@ -0,0 +1,111 @@ + +fnOpts = {'UniformOutput', false}; +exp_subtype = {'iRNs', 'eRNs', 'RNs'}; +% exp_subtype = {'terminal inhib'}; +% name_keys = {'GADi', {'GADe', 'vGlut'}, 'WTg'}; +% name_keys = {'GADi', 'vGlut', 'WTg'}; +name_keys = {'GADi', 'GADe', 'WTg'}; +% name_keys = {{'Rb', 'WT'}}; +bodypart_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... + "Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... + "Symmetry", "Nose", "Roller speed"]; +signTh = [0.001, 0.01, 0.05, 0.1]; +createtiles = @(f,nr,nc) tiledlayout( f, nr, nc, ... + 'TileSpacing', 'Compact', 'Padding', 'tight'); +bxOpts = cellstr(["Notch", "on", "JitterOutliers", "on", ... + "BoxFaceColor", "k", 'MarkerStyle', '.', 'MarkerColor', 'k']); +txOpts = {'HorizontalAlignment','left','VerticalAlignment', 'middle', ... + 'Rotation', 90}; +cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); +fig_path = fullfile( ... + "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures" ); +load( fullfile( fig_path, "MC, BC, BS, MCterminals pool.mat" ), "summMice" ); + +expMice = summMice{1}(3); +ovwtFlag = false; +% xLabels = ["Control", "C100", "F100"]; +% xLabels = ["Control", "C30", "F30", "C100", "F100", ... +% "C400", "F400", "C600", "Musc", "Musc" ]; +xLabels = ["Control", "C30", "F30", "C100", "F100", ... + "C400", "F400", "Dead", "PTX", "PTX" ]; +exp_subtype_flags = cellfun(@(x) contains( expMice.MiceNames, x ), ... + name_keys, fnOpts{:} ); +exclude_names = {'GADi13', 'GADi15', 'GADi53'}; +exclude_mice = contains(expMice.MiceNames, exclude_names); +exp_subtype_flags = cat( 2, exp_subtype_flags{:} ); +figs = gobjects( numel( exp_subtype ), 1 ); +% exp_type = join( ['MC-', expMice.ExperimentalGroup] ); +exp_type = expMice.ExperimentalGroup; +for cest = 1:numel(exp_subtype) + cons_mice = exp_subtype_flags(:,cest) & ~exclude_mice; + exp_subtype_flags(:,cest) = exp_subtype_flags(:,cest) & ~exclude_mice; + if sum( cons_mice ) + + figs(cest) = figure( "Color", "w" ); + t = createtiles( figs(cest), 2, 1 ); ax = nexttile(t); + aux = squeeze( mean( expMice.AmplitudeIndex(:,:, ... + cons_mice), 1, "omitmissing" ) )'; + boxchart( ax, aux, bxOpts{:} ); + ylabel( ax, 'Amplitude index' ); xticklabels( ax, xLabels ); + ylim(ax, [0,1]); cleanAxis(ax); ax.XAxis.Visible = "off"; + p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... + "ErrorHandler", @(s,a) nan(1) ); + mark_flag = p(:) < signTh; + text( ax, 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... + arrayfun(@(x) sprintf("p=%.3f", x), p(:) ), txOpts{:} ) + + ax = nexttile(t); + aux = squeeze( mean( expMice.TrialProportions(:,:, ... + cons_mice), 1, "omitmissing" ) )'; + boxchart(ax, aux, bxOpts{:} ); + ylabel( ax, 'Trial proportions' ) + xticklabels( xLabels ); ylim([0,2]); cleanAxis( ax ); + p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... + "ErrorHandler", @(s,a) nan(1) ); + text(ax, 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... + arrayfun(@(x) sprintf("p=%.3f", x), p(:) ), txOpts{:} ) + title(t, sprintf( "Area/%s", exp_subtype{cest} ) ) + + for cbp = 1:numel(bodypart_names) + fig = figure("Color", "w"); t2 = createtiles( fig, 2, 1 ); + ax = nexttile(t2); + aux = squeeze( mean( expMice.PolygonUnfoldAmplIndx(:,:, ... + cbp, cons_mice), 2, "omitmissing" ) )'; + boxchart( ax, aux, bxOpts{:} ); + ylabel( ax, 'Amplitude index' ); xticklabels( ax, xLabels ); + ylim(ax, [0,1]); cleanAxis(ax); ax.XAxis.Visible = "off"; + p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... + "ErrorHandler", @(s,a) nan(1) ); + text( 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... + arrayfun(@(x) sprintf("p=%.3f", x), p(:) ), txOpts{:} ) + + ax = nexttile(t2); + aux = squeeze( mean( expMice.PolygonUnfoldTrialProp(:,:, ... + cbp, cons_mice), 2, "omitmissing" ) )'; + boxchart(ax, aux, bxOpts{:} ); + ylabel( ax, 'Trial proportions' ) + xticklabels( xLabels ); ylim([0,2]); cleanAxis( ax ); + p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... + "ErrorHandler", @(s,a) nan(1) ); + text( 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... + arrayfun(@(x) sprintf("p=%.3f", x), p(:) ), txOpts{:} ) + title(t2, sprintf( "%s/%s", bodypart_names(cbp), exp_subtype{cest} ) ) + + % saveFigure( fig, fullfile( fig_path, join( [bodypart_names(cbp), ... + % exp_type, exp_subtype{cest}, "all mice pool" ] ) ), ... + % true, ovwtFlag ) + saveFigure( fig, fullfile( fig_path, join( [bodypart_names(cbp), ... + exp_type, exp_subtype{cest}, sum( cons_mice ) ] ) ), ... + true, ovwtFlag ) + end + end +end + +% arrayfun(@(f) saveFigure( figs(f), fullfile( fig_path, ... +% join( ["Areas", exp_type, exp_subtype{f}, "all mice pool"] ) ), true, ovwtFlag ), ... +% find( arrayfun(@(f) ~isa( f, 'matlab.graphics.GraphicsPlaceholder'), figs ) ) ); + +arrayfun(@(f) saveFigure( figs(f), fullfile( fig_path, ... + join( ["Areas", exp_type, exp_subtype{f}, ... + sum( exp_subtype_flags(:,f) ) ] ) ), true, ovwtFlag ), ... + find( arrayfun(@(f) ~isa( f, 'matlab.graphics.GraphicsPlaceholder'), figs ) ) ); \ No newline at end of file From 49886038dc36a9c846ae1503c70a27079be93ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 5 Sep 2024 18:29:44 +0200 Subject: [PATCH 085/201] Create poolEphMI_iRNs.m --- Emilio/poolEphMI_iRNs.m | 113 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Emilio/poolEphMI_iRNs.m diff --git a/Emilio/poolEphMI_iRNs.m b/Emilio/poolEphMI_iRNs.m new file mode 100644 index 0000000..6d8d34c --- /dev/null +++ b/Emilio/poolEphMI_iRNs.m @@ -0,0 +1,113 @@ +%#ok<*AGROW,*SAGROW> +%% Auxiliary variables and functions +fnOpts = {'UniformOutput', false}; +expandName = @(x) fullfile(x.folder, x.name); +animalPattern = '[a-zA-Z]+\d{1,}'; +rsOpts = {animalPattern, 'SearchType', 'expression'}; +ctOpts = {'IgnoreCase', true}; +lsOpts = {'L\d+.\d+', 'match'}; +ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; +tblOpts = {'VariableNames', {'Conditions', 'MI'}}; +my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +getMI = @(x,d) diff(x, 1, d)./sum(x, d); +total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); +tocol = @(x) x(:); + +exclude_names = {'GADi13', 'GADi15', 'GADi53'}; + +iRN_mice = dir( "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch*\MC\GADi*" ); +animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); +exclude_flags = contains( animalFolders, exclude_names ); + +%% Looping animals +oldMouse = ""; +mc = 0; mice = []; +for cad = tocol(animalFolders(~exclude_flags))' + [structPath, currMouse] = fileparts(cad); + [~, structName] = fileparts(structPath); + if string(oldMouse) ~= string(currMouse) + oldMouse = currMouse; + mice = [mice; struct('Name', currMouse, 'Sessions',[], ... + 'Structure', structName)]; + mc = mc + 1; + sc = 0; oldSess = ""; oldDepth = ""; + end + sessDirs = getSubFolds(cad); + % Just date sessions + onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... + 'match')), sessDirs, fnOpts{:}); + sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; + for csd = sessDirs(:)' + curDir = expandName(csd); + sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})?', 'tokens', 'once'); + if ~isempty( sessDateDepth ) + currSess = sessDateDepth{1}; + if isempty( sessDateDepth{2} ) + depthSess = ''; + else + depthSess = sessDateDepth{2}; + end + else + currSess = regexp(csd.name, '(\d{6})', 'tokens', 'once'); + depthSess = ''; + if isempty(currSess) + fprintf( 1, "Unable to get session date and depth\n" ); + fprintf( 1, "Skipping: %s %s\n", currMouse, csd.name ) + continue + end + end + childFolders = getSubFolds(curDir); + sessOrgDirs = arrayfun(@(d) string(d.name), childFolders); + sessOrgDirs(contains(sessOrgDirs, {'behaviour', 'ephys', ... + 'figures', 'opto'}, ctOpts{:})) = []; + miFigDir = arrayfun(@(d) recursiveFolderSearch(expandName(d), ... + ephFF, 'SearchType', 'expression'), childFolders, fnOpts{:}); + miFigDir = cat(1, miFigDir{:}); + miIdxFiles = arrayfun(@(d) dir( fullfile( d, ... + "LogPSTH_Structure*.mat" ) ), miFigDir, fnOpts{:} ); + miIdxFiles = cat( 1, miIdxFiles{:} ); + if isempty(miIdxFiles) + fprintf(1, 'No ephys analysis done! Skipping %s!\n', curDir) + continue + end + % miIdxStr = arrayfun(@(x) load( expandName(x), 'logPSTH' ), miIdxFiles); + load( expandName(miIdxFiles), 'logPSTH' ); + lp_mu = squeeze( mean( ... + logPSTH.LogPSTH(:,:,logPSTH.indexMIComparison) ) ); + muMI = getMI( lp_mu, 2 ); + bmot_MI = mean( muMI( ~(logPSTH.TimeAxis < 5e-2) ) ); + sens_MI = mean( muMI( logPSTH.TimeAxis < 5e-2) ); + miVal = [sens_MI, bmot_MI]; + condNames = logPSTH.ConditionNames( logPSTH.indexMIComparison ); + condNames = join([condNames(1), "v", condNames(2)]); + + sessType = 'single'; + dataTable = table( condNames, miVal, tblOpts{:} ); + if ( string(oldSess) ~= string(currSess) ) || ... + ( string(oldDepth) ~= string(depthSess) ) + oldSess = currSess; + oldDepth = depthSess; + auxStruct = struct('Date', currSess, ... + 'DataTable', dataTable, 'Type', sessType, ... + 'Depth', depthSess); + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + sc = sc + 1; + end + end +end +mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; + +behFP = fullfile( "Z:\Emilio\SuperiorColliculusExperiments\Roller", "MCiRNs_EphMI_sm.mat" ); +svOpts = {'-mat'}; +if exist(behFP, "file") + svOpts = {'-append'}; +end +save(behFP, "mice", svOpts{:}) +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +cat( 1, habFlag{:} ) +%{ \ No newline at end of file From 1a29df38b48c5a8f6acc475144d05c1e9fcf50bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 5 Sep 2024 18:29:45 +0200 Subject: [PATCH 086/201] Create Unit_localozation.m --- Emilio/Unit_localozation.m | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Emilio/Unit_localozation.m diff --git a/Emilio/Unit_localozation.m b/Emilio/Unit_localozation.m new file mode 100644 index 0000000..83439ec --- /dev/null +++ b/Emilio/Unit_localozation.m @@ -0,0 +1,46 @@ + +[pg_centered, xy_centre, xy_scale] = zscore( [xcoords, ycoords] ); +[ptp_centered, ptp_centre, ptp_scale] = zscore( ptp, 0, 'all' ); + + +tic +% Create optimization variables +theta_hat = optimvar("theta_hat",1,4,"LowerBound",-10,"UpperBound",10); + +% Set initial starting point for the solver +initialPoint.theta_hat = theta; + +% Create problem +problem = optimproblem; + +% Define problem objective +problem.Objective = fcn2optimexpr(@objectiveFcn,theta_hat,ptp_centered,... + pg_centered); + +% Display problem information +show(problem); + +% Solve problem +[solution,objectiveValue,reasonSolverStopped] = solve(problem,initialPoint); + +% Display results +disp(solution) +disp(reasonSolverStopped) +disp(objectiveValue) +toc + +function objective = objectiveFcn(theta_hat, ptp_centered, pg_centered) +% This function should return a scalar representing an optimization objective. + +% Example: Concession stand profit +% revenue = 3*soda + 5*popcorn + 2*candy; +% cost = 1*soda + 2*popcorn + 0.75*candy; +% objective = revenue - cost; % profit + +% Edit the lines below with your calculations. +for c = 1:size( ptp_centered, 2 ) + objective = sum( ( ptp_centered(:,c) - ... + ( theta_hat(1)./ sqrt( sum( (pg_centered - theta_hat([2,3])).^2, 2 ) + ... + theta_hat(4).^2 ) ) ).^2, 'all' ); +end +end \ No newline at end of file From 8aeb536eb1d0ba45f9086394f0982f74748fd52a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 6 Sep 2024 17:41:37 +0200 Subject: [PATCH 087/201] Latest improvements --- Emilio/poolEphMI_iRNs.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Emilio/poolEphMI_iRNs.m b/Emilio/poolEphMI_iRNs.m index 6d8d34c..9bd03ad 100644 --- a/Emilio/poolEphMI_iRNs.m +++ b/Emilio/poolEphMI_iRNs.m @@ -74,7 +74,7 @@ load( expandName(miIdxFiles), 'logPSTH' ); lp_mu = squeeze( mean( ... logPSTH.LogPSTH(:,:,logPSTH.indexMIComparison) ) ); - muMI = getMI( lp_mu, 2 ); + muMI = getMI( lp_mu, 2 ); muMI(isnan( muMI )) = 0; bmot_MI = mean( muMI( ~(logPSTH.TimeAxis < 5e-2) ) ); sens_MI = mean( muMI( logPSTH.TimeAxis < 5e-2) ); miVal = [sens_MI, bmot_MI]; @@ -106,8 +106,7 @@ if exist(behFP, "file") svOpts = {'-append'}; end -save(behFP, "mice", svOpts{:}) +%save(behFP, "mice", svOpts{:}) habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... m.Sessions), mice, fnOpts{:}); -cat( 1, habFlag{:} ) -%{ \ No newline at end of file +cat( 1, habFlag{:} ) \ No newline at end of file From c2d6908d09a9f0d63d97f2b8c168a72fe2345f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 10 Sep 2024 18:29:10 +0200 Subject: [PATCH 088/201] Saving popLogPSTH from all sessions --- Emilio/poolEphMI_iRNs.m | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Emilio/poolEphMI_iRNs.m b/Emilio/poolEphMI_iRNs.m index 9bd03ad..b28c167 100644 --- a/Emilio/poolEphMI_iRNs.m +++ b/Emilio/poolEphMI_iRNs.m @@ -21,7 +21,7 @@ %% Looping animals oldMouse = ""; -mc = 0; mice = []; +mc = 0; mice = []; lp_mu = []; lPSTH = []; for cad = tocol(animalFolders(~exclude_flags))' [structPath, currMouse] = fileparts(cad); [~, structName] = fileparts(structPath); @@ -72,9 +72,10 @@ end % miIdxStr = arrayfun(@(x) load( expandName(x), 'logPSTH' ), miIdxFiles); load( expandName(miIdxFiles), 'logPSTH' ); - lp_mu = squeeze( mean( ... - logPSTH.LogPSTH(:,:,logPSTH.indexMIComparison) ) ); - muMI = getMI( lp_mu, 2 ); muMI(isnan( muMI )) = 0; + lPSTH = cat( 1, lPSTH, {logPSTH.LogPSTH} ); + lp_mu = cat( 3, lp_mu, squeeze( mean( ... + logPSTH.LogPSTH(:,:,logPSTH.indexMIComparison) ) ) ); + muMI = getMI( lp_mu(:,:,end), 2 ); muMI(isnan( muMI )) = 0; bmot_MI = mean( muMI( ~(logPSTH.TimeAxis < 5e-2) ) ); sens_MI = mean( muMI( logPSTH.TimeAxis < 5e-2) ); miVal = [sens_MI, bmot_MI]; @@ -106,7 +107,7 @@ if exist(behFP, "file") svOpts = {'-append'}; end -%save(behFP, "mice", svOpts{:}) +% save(behFP, "mice", svOpts{:}) habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... m.Sessions), mice, fnOpts{:}); -cat( 1, habFlag{:} ) \ No newline at end of file +cat( 1, habFlag{:} ) From 393e696b92d747dc48ad04919961ab1f32e78318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 11 Sep 2024 18:36:40 +0200 Subject: [PATCH 089/201] Latex interpreter --- Emilio/iegRNs_AmplitudeIndexPool.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Emilio/iegRNs_AmplitudeIndexPool.m b/Emilio/iegRNs_AmplitudeIndexPool.m index 1182be9..efa2b97 100644 --- a/Emilio/iegRNs_AmplitudeIndexPool.m +++ b/Emilio/iegRNs_AmplitudeIndexPool.m @@ -15,7 +15,7 @@ bxOpts = cellstr(["Notch", "on", "JitterOutliers", "on", ... "BoxFaceColor", "k", 'MarkerStyle', '.', 'MarkerColor', 'k']); txOpts = {'HorizontalAlignment','left','VerticalAlignment', 'middle', ... - 'Rotation', 90}; + 'Rotation', 90, 'Interpreter', 'latex'}; cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); fig_path = fullfile( ... "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures" ); @@ -24,10 +24,10 @@ expMice = summMice{1}(3); ovwtFlag = false; % xLabels = ["Control", "C100", "F100"]; -% xLabels = ["Control", "C30", "F30", "C100", "F100", ... -% "C400", "F400", "C600", "Musc", "Musc" ]; xLabels = ["Control", "C30", "F30", "C100", "F100", ... - "C400", "F400", "Dead", "PTX", "PTX" ]; + "C400", "F400", "C600", "Musc", "Musc" ]; +% xLabels = ["Control", "C30", "F30", "C100", "F100", ... +% "C400", "F400", "Dead", "PTX", "PTX" ]; exp_subtype_flags = cellfun(@(x) contains( expMice.MiceNames, x ), ... name_keys, fnOpts{:} ); exclude_names = {'GADi13', 'GADi15', 'GADi53'}; @@ -52,7 +52,7 @@ "ErrorHandler", @(s,a) nan(1) ); mark_flag = p(:) < signTh; text( ax, 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... - arrayfun(@(x) sprintf("p=%.3f", x), p(:) ), txOpts{:} ) + arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) ax = nexttile(t); aux = squeeze( mean( expMice.TrialProportions(:,:, ... @@ -63,7 +63,7 @@ p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... "ErrorHandler", @(s,a) nan(1) ); text(ax, 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... - arrayfun(@(x) sprintf("p=%.3f", x), p(:) ), txOpts{:} ) + arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) title(t, sprintf( "Area/%s", exp_subtype{cest} ) ) for cbp = 1:numel(bodypart_names) @@ -77,7 +77,7 @@ p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... "ErrorHandler", @(s,a) nan(1) ); text( 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... - arrayfun(@(x) sprintf("p=%.3f", x), p(:) ), txOpts{:} ) + arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) ax = nexttile(t2); aux = squeeze( mean( expMice.PolygonUnfoldTrialProp(:,:, ... @@ -88,7 +88,7 @@ p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... "ErrorHandler", @(s,a) nan(1) ); text( 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... - arrayfun(@(x) sprintf("p=%.3f", x), p(:) ), txOpts{:} ) + arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) title(t2, sprintf( "%s/%s", bodypart_names(cbp), exp_subtype{cest} ) ) % saveFigure( fig, fullfile( fig_path, join( [bodypart_names(cbp), ... From a8362382580d1109bcb64e16b920760d396e9325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 11 Sep 2024 18:36:44 +0200 Subject: [PATCH 090/201] Create popPolygon.m --- Emilio/popPolygon.m | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Emilio/popPolygon.m diff --git a/Emilio/popPolygon.m b/Emilio/popPolygon.m new file mode 100644 index 0000000..9a2881c --- /dev/null +++ b/Emilio/popPolygon.m @@ -0,0 +1,53 @@ +aux = expMice.PolygonUnfoldAmplIndx([1,5],:,:,cons_mice); +med_AI_pbp = squeeze( median( aux, 2, "omitmissing" ) ); +med_AI_all = median( med_AI_pbp, 3, "omitmissing" ); +Nb = 8; +bodypart_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... +"Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... +"Symmetry", "Nose", "Roller speed"]; + +radAxis = (0:Nb-1)*(2*pi/Nb); +z_axis = exp(1i*radAxis(:)); + +iqr_AI = quantile( med_AI_pbp, [1,3]/4, 3 ); +iqr_coords = iqr_AI .* transp( z_axis ); +poly_coords = med_AI_all .* transp( z_axis ); + +figure('Color', 'w'); hold on; +line( [-real(z_axis(1:4)), real(z_axis(1:4))]', ... + [-imag(z_axis(1:4)), imag(z_axis(1:4))]', 'LineWidth', 0.1, ... + 'Color', 0.45*ones(1,3)); +arrayfun(@(x) rectangle('Position', [repmat(-x,1,2),repmat(x*2,1,2)], ... + 'Curvature', [1,1], 'EdgeColor', 0.45*ones( 1, 3 ) ), 1:-0.25:0.25 ); +arrayfun(@(c) patch( real( poly_coords(c,:) )', ... + imag( poly_coords(c,:) )', clrMap(c,:), 'EdgeColor', 'none', ... + 'FaceAlpha', 0.8 ), 1:2 ); + +z_rot = exp( 1i*pi/32 ); +% Dots by the polygon +arrayfun(@(c,z) line( real( poly_coords(c,:) * z)', ... + imag( poly_coords(c,:) * z )', 'LineStyle', 'none', ... + 'Marker', '.', 'Color', clrMap(c,:), 'MarkerSize', 20 ), ... + 1:2, [z_rot, z_rot'] ) +set( gca, 'Box', 'off', 'Color', 'none', "Visible", "off" ); +% Lines for IQR +arrayfun(@(x,z) line( squeeze( real( iqr_coords(x,:,:) * z ) )', ... + squeeze( imag( iqr_coords(x,:,:) * z ) )', 'LineWidth', 2, ... + 'Color', clrMap(x,:) ), 1:2, [z_rot, z_rot'] ) +text( 0.25:0.25:1, zeros(1,4), string( ( 1:4 )'/4 ), ... + "HorizontalAlignment", "left", "VerticalAlignment", "cap" ) +title('Population Polygons for MC\rightarrowiRNs' ) +legend( findobj( gca, 'Type', 'Patch' ), {'Laser OFF', 'Laser ON'}, ... + "Location", "best", "Color", "none", "Box", "off" ) +p = arrayfun(@(b) signrank( squeeze( med_AI_pbp(1,b,:) ), ... + squeeze( med_AI_pbp(2,b,:) ) ), 1:8 ); +arrayfun(@(v, y) text( real( 1.25*poly_coords(1,v) ), ... + imag( 1.25*poly_coords(1,v) ), repmat( '\ast', 1, sum( p(v) < ... + [0.05, 0.01, 0.001] ) ), "HorizontalAlignment", "center", ... + "Rotation", y, "VerticalAlignment", "baseline"), 1:8, ... + (180*angle( transp(z_axis) )/pi) - 90 ); + +arrayfun(@(v,b,y) text( real( z_axis(v) ), ... + imag( z_axis(v) ), b, "HorizontalAlignment", "center", "Rotation", y, ... + "VerticalAlignment", "baseline" ), 1:8, bodypart_names, ... + (180*angle( transp(z_axis) )/pi) - 90 ) \ No newline at end of file From e537adefc3b23ff1626da1b7efdb3eff55cbf97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 12 Sep 2024 15:11:18 +0200 Subject: [PATCH 091/201] Saving logPSTH and the popLogPSTH --- Emilio/poolEphMI.m | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Emilio/poolEphMI.m b/Emilio/poolEphMI.m index 1a5b8d3..ff9a108 100644 --- a/Emilio/poolEphMI.m +++ b/Emilio/poolEphMI.m @@ -28,7 +28,8 @@ rsOpts{:}), childFolders, fnOpts{:}); animalFolders = cat(1, animalFolders{:}); %% Looping animals oldMouse = ""; -mc = 0; mice = []; +mc = 0; mice = []; lp_mu = []; lPSTH = []; +var2save = {'mice', 'lp_mu', 'lPSTH'}; for cad = tocol(animalFolders)' [structPath, currMouse] = fileparts(cad); [~, structName] = fileparts(structPath); @@ -79,9 +80,10 @@ end % miIdxStr = arrayfun(@(x) load( expandName(x), 'logPSTH' ), miIdxFiles); load( expandName(miIdxFiles), 'logPSTH' ); - lp_mu = squeeze( mean( ... - logPSTH.LogPSTH(:,:,logPSTH.indexMIComparison) ) ); - muMI = getMI( lp_mu, 2 ); + lPSTH = cat( 1, lPSTH, {logPSTH.LogPSTH} ); + lp_mu = cat( 3, lp_mu, squeeze( mean( ... + logPSTH.LogPSTH(:,:,logPSTH.indexMIComparison) ) ) ); + muMI = getMI( lp_mu(:,:,end), 2 ); muMI(isnan( muMI )) = 0; bmot_MI = mean( muMI( ~(logPSTH.TimeAxis < 5e-2) ) ); sens_MI = mean( muMI( logPSTH.TimeAxis < 5e-2) ); miVal = [sens_MI, bmot_MI]; @@ -113,7 +115,7 @@ if exist(behFP, "file") svOpts = {'-append'}; end -save(behFP, "mice", svOpts{:}) +save(behFP, var2save{:}, svOpts{:}) habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... m.Sessions), mice, fnOpts{:}); cat( 1, habFlag{:} ) From ded7c584e05d09511add077d89ea7b2b2aa8b33b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 12 Sep 2024 18:25:09 +0200 Subject: [PATCH 092/201] Added a little explanation --- Emilio/popPolygon.m | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Emilio/popPolygon.m b/Emilio/popPolygon.m index 9a2881c..c0bf6fd 100644 --- a/Emilio/popPolygon.m +++ b/Emilio/popPolygon.m @@ -1,6 +1,16 @@ -aux = expMice.PolygonUnfoldAmplIndx([1,5],:,:,cons_mice); +% iRNs +expMice = summMice{1}(3); +aux = expMice.PolygonUnfoldAmplIndx([1,5],:,:,cons_mice); +% cons_mice comes from the iegRNs_AmplitudeIndexPool.m script + +% eOPN3 +expMice = summMice{4}(2); +aux = expMice.PolygonUnfoldAmplIndx([1,8],:,:,:); +%% + med_AI_pbp = squeeze( median( aux, 2, "omitmissing" ) ); med_AI_all = median( med_AI_pbp, 3, "omitmissing" ); +clrMap = [0.15*ones(1,3); 0, 0.51, 1]; Nb = 8; bodypart_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... "Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... From 64b4887ce28ee8b83c8f0dc1a5bd69729236bfd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 16 Sep 2024 18:28:37 +0200 Subject: [PATCH 093/201] Create computeEphMI.m --- Emilio/computeEphMI.m | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Emilio/computeEphMI.m diff --git a/Emilio/computeEphMI.m b/Emilio/computeEphMI.m new file mode 100644 index 0000000..e633978 --- /dev/null +++ b/Emilio/computeEphMI.m @@ -0,0 +1,50 @@ +fnOpts = {'UniformOutput', false}; +tocol = @(x) x(:); +my_cat = @(x,d) cat( d, x{:} ); +getMI = @(x,d) diff( x, 1, d ) ./ sum( x, d ); + +mi_lp = squeeze( getMI( lp_mu, 2 ) )'; +popMImean_lp = [mean( mi_lp(:, tx < 0.05), 2, "omitmissing"), ... + mean( mi_lp(:, tx >= 0.05), 2, "omitmissing")]; + +mi_lpu = cell( size( lPSTH ) ); +uMiMatMean = zeros( sum( cellfun(@(x) size( x, 1), lPSTH ) ), 3 ); +uMiMatMed = uMiMatMean; +ridx = cumsum( cellfun(@(x) size( x, 1), lPSTH ) ); +r = 1; +for cs = 1:numel( lPSTH ) + mi_lpu{cs} = getMI( lPSTH{cs}, 3 ); + uMiMatMean(r:ridx(cs),:) = [repmat( cs, size( mi_lpu{cs}, 1 ), 1 ), ... + mean( mi_lpu{cs}(:, tx < 0.05), 2, "omitmissing" ), ... + mean( mi_lpu{cs}(:, tx >= 0.05), 2, "omitmissing" )]; + % uMiMatMed(r:ridx(cs),:) = [repmat( cs, size( mi_lpu{cs}, 1 ), 1 ), ... + % median( mi_lpu{cs}(:, tx < 0.05), 2, "omitmissing" ), ... + % median( mi_lpu{cs}(:, tx >= 0.05, "omitmissing" ), 2)]; + r = 1 + ridx(cs); +end + +popMImedian = my_cat( arrayfun( @(s) ... + median( uMiMatMean( uMiMatMean(:,1) == s, [2,3] ), 1, "omitmissing" ), ... + unique( uMiMatMean(:,1) ), fnOpts{:} ), 1 ); +popMImean = my_cat( arrayfun( @(s) ... + mean( uMiMatMean( uMiMatMean(:,1) == s, [2,3] ), 1, "omitmissing" ), ... + unique( uMiMatMean(:,1) ), fnOpts{:} ), 1 ); + +figure; +subplot(1,5,[1,4]) +boxchart( tocol( repmat( uMiMatMean(:,1), 2, 1) ), ... + tocol( uMiMatMean(:,[2,3]) ), "Notch", "on", ... + "GroupByColor", tocol( ones( size( uMiMatMean, 1), 1) * (1:2) ) ); +xlim( [0, numel(lPSTH)] + 0.5 ) +yline( 0, 'k--'); set( gca, "Box", "off", "Color", "none" ) +subplot(1,5,5) +boxchart(popMImean, 'Notch', 'on' ) +yline( 0, 'k--'); set( gca, "Box", "off", "Color", "none" ) + +figure; boxchart( popMImean_lp, 'Notch', 'on' ); +yline( 0, 'k--'); set( gca, "Box", "off", "Color", "none" ) + +figure; smth = 0.015; +daviolinplot( uMiMatMean(:,[2,3]), 'groups', tocol( ones( size( uMiMatMean, 1), 1 ) * (1:2) ), ... + 'violinalpha', 0.5, 'smoothing', smth, ... 'jitter', 2, ... + 'color', [0,0.51,1] ); \ No newline at end of file From eddd46fc1ceb47f1151287e620a0c3a8915718f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 16 Sep 2024 18:28:40 +0200 Subject: [PATCH 094/201] Create ephysBehaviourRegression.m --- Emilio/ephysBehaviourRegression.m | 123 ++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 Emilio/ephysBehaviourRegression.m diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m new file mode 100644 index 0000000..fc96f21 --- /dev/null +++ b/Emilio/ephysBehaviourRegression.m @@ -0,0 +1,123 @@ + +%{ +res_gof = zeros( 15, 1 ); +% feps = zeros( 15, 1 ); +parfor ii = 1:15 + trainIdx = training( cvpart, ii ); + testIdx = test( cvpart, ii ); + Xtrain = gpuArray( X( any( tr_ID == diag( trainIdx * (1:Nr) )', 2 ), : ) ); + Ytrain = gpuArray( y( any( tr_ID == diag( trainIdx * (1:Nr) )', 2 ), 1 ) ); + Xtest = gpuArray( X( any( tr_ID == diag( testIdx * (1:Nr) )', 2 ), : ) ); + Ytest = gpuArray( y( any( tr_ID == diag( testIdx * (1:Nr) )', 2 ), 1 ) ); + + mdl = fitglm( Xtrain, Ytrain, 'linear', 'Distribution', 'Normal' ); + y_pred = feval( mdl, Xtest ); + res_gof(ii) = goodnessOfFit( Ytest, y_pred, 'MSE' ); + % feps(ii) = loss( mdl, Xtest, Ytest ); +end +%} +%% +fnOpts = {'UniformOutput', false}; +tocol = @(x) x(:); +roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; +data_path = fullfile( roller_path, "Batch18_ephys\MC\GADi43\240227_C+F_2200" ); +eph_path = fullfile( data_path, "ephys_E1" ); +beh_path = fullfile( data_path, "Behaviour" ); +load( fullfile( beh_path, "BehaviourSignals2024-02-27T11_26_07+T11_43_01.mat" ) ) +load( fullfile( beh_path, "RollerSpeed2024-02-27T11_26_07+T11_43_01.mat" ) ) +% load( fullfile( eph_path, "GADi43_C+F_2200_all_channels.mat" ) ) +load( fullfile( eph_path, ... + "GADi43_C+F_2200 RW20.00-50.00 SW-180.00--150.00 VW-300.00-400.00 ms PuffAll (unfiltered) RelSpkTms.mat" ), "configStructure" ) +load( fullfile( eph_path, "GADi43_C+F_2200analysis.mat" ) ) +load( fullfile( eph_path, "GADi43_C+F_2200_Spike_Times.mat" ) ) +stop_time = length( Triggers.Whisker )/ fs; +%% +behSignals = [behDLCSignals, vf]; +mdl_btx = fit_poly( [1, size( behSignals, 1 )], [0, size( behSignals, 1 )/fr] + [1,-1] * (1/fr), 1 ); +btx = (1:size( behSignals, 1 ))'.^[1,0] * mdl_btx; +my_xor = @(x) xor( x(:,1), x(:,2) ); + +% time_limits = [0, length(behSignals)/fr]; +cS = configStructure; +rel_win = [-0.8, 0.8]; +del_win = [-50, 50]*1e-3; +bin_size = 5e-3; +cS.BinSize_s = bin_size; +Nb = ceil( diff( rel_win )/ bin_size ); +% Nb = ceil( diff( time_limits ) / bin_size ); +Nu = numel( spike_times ); +% cons_time = my_xor( btx > time_limits ); +Ns = size( behSignals, 2 ); +%% +bin_edges = 0:bin_size:stop_time; +bin_centres = mean( [bin_edges(1:end-1); bin_edges(2:end)] ); +Ntb = length( bin_centres ); +hstOpts = {'Normalization', 'countdensity'}; +binned_spikes = cellfun(@(s) histcounts( s, bin_edges, hstOpts{:}), ... + spike_times, fnOpts{:} ); +binned_spikes = cat( 1, binned_spikes{:} ); + +binned_beh = zeros( Ntb, Ns ); +parfor b = 1:Ntb + idx = my_xor( btx(:) < bin_edges(b:b+1) ); + binned_beh(b,:) = mean( behSignals( idx , : ), 1 ); +end + +%% Design matrix for a set of trials +time_limits = Conditions(3).Triggers(:,1)./fs + rel_win; +Nr = size( time_limits, 1 ); +Nd = ceil( diff( del_win ) / bin_size ); +auX = zeros( Nb*Nr, Nu, Nd ); + +cwin = arrayfun(@(x) linspace( time_limits(x,1) + (bin_size/2), ... + time_limits(x,2) - (bin_size/2), Nb )', (1:Nr)', fnOpts{:} ); +cwin = cat( 1, cwin{:} ); + +bin_ax = cwin + linspace( del_win(1)+(bin_size/2), ... + del_win(2)-(bin_size/2), Nd ); +% tr_ID = ceil( ( 1:(Nr*Nb) )' / Nb ); +parfor r = 1:(Nr*Nb) + tempC = arrayfun(@(u) interp1( bin_centres, binned_spikes(u,:), ... + bin_ax(r,:) ), 1:Nu, fnOpts{:} ); + tempC = cat( 1, tempC{:} ); + auX( r, :, :) = tempC; +end + +X = reshape( auX, [], Nu*Nd ); clearvars auX; +X2 = [ ones( Nb*Nr, 1), X]; +Xp = X2; +%% Multivariate regression response matrix +%X2 = [ ones( Nb*Nr, 1), X]; +%lmObjs = cell( Ns, 1 ); +y = zeros( Nb*Nr, Ns); +for r = 1:Nr + idx = (r-1)*Nb + (1:Nb); + aux = arrayfun(@(s) interp1( bin_centres, binned_beh(:,s), ... + (1:Nb)'*bin_size + time_limits(r,1) ), (1:Ns), fnOpts{:} ); + aux = cat( 2, aux{:} ); + y(idx,:) = aux; +end + +tr_ID = tocol( ones( Nb, 1) * (1:Nr) ); +cv_kf = cvpartition( tr_ID, "KFold", 15 ); + +[mdl, fitInfo] = lassoglm( X, Y, 'normal', ... + 'CV', cv_kf, 'Lambda', logspace( -5, 3, 64 ), ... + 'Options', statset('UseParallel', true ), ... + 'Alpha', eps ); + +%% Design matrix for the whole experiment +Nb = ceil( diff( bin_edges([1,end]) )/ bin_size ); +auX = zeros( Nb, Nu, Nd ); +parfor b = 1:Nb + cwin = bin_centres(b) + del_win; + bin_ax = linspace( cwin(1), cwin(2), Nd ); + tempC = arrayfun(@(u) interp1( bin_centres, binned_spikes(u,:), ... + bin_ax ), 1:Nu, fnOpts{:} ); + tempC = cat( 1, tempC{:} ); + tempC( isnan(tempC) ) = 0; + auX( b, :, :) = tempC; +end +X = reshape( auX, [], Nu*Nd ); +X2 = [ ones( Nb*Nr, 1), X]; +Xa = X2; From def16d7feb8b06f33756ef28cb46e3bd5c8d9976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 16 Sep 2024 18:29:00 +0200 Subject: [PATCH 095/201] Added the creation of summMice --- Emilio/iegRNs_AmplitudeIndexPool.m | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Emilio/iegRNs_AmplitudeIndexPool.m b/Emilio/iegRNs_AmplitudeIndexPool.m index efa2b97..af89f66 100644 --- a/Emilio/iegRNs_AmplitudeIndexPool.m +++ b/Emilio/iegRNs_AmplitudeIndexPool.m @@ -1,4 +1,27 @@ +roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; +bp_paths = dir( fullfile( roller_path, "\Batch*\Batch*_BehaviourIndex.mat" ) ); +bodypart_names = string( {bp_paths.name} )'; +b_num = regexp( bodypart_names, '\d+', 'match' ); +b_num = cat(1, b_num{:} ); b_num = str2double( b_num ); +expandPath = @(x) fullfile( x.folder, x.name); +fnOpts = {'UniformOutput', false}; + +mc_subs = [1, 2, 7, 8, 10, 12, 15, 16, 18]; +bc_subs = [1, 2, 19]; +bs_subs = 2; +mt_subs = [11, 14, 17]; + +exp_type_subs_cell = {mc_subs, bc_subs, bs_subs, mt_subs}; +clearvars *_subs -except exp_type_subs_cell + +mice_bulk = arrayfun( @(x) load( expandPath( x ), "mice" ), ... + bp_paths ); +mice_exp_sub = cellfun(@(x) any(b_num == x, 2), exp_type_subs_cell, ... + fnOpts{:} ); +summMice = cellfun(@(x) summariseMiceBeh( cat(1, mice_bulk(x).mice ) ), ... + mice_exp_sub, fnOpts{:} ); +%% fnOpts = {'UniformOutput', false}; exp_subtype = {'iRNs', 'eRNs', 'RNs'}; % exp_subtype = {'terminal inhib'}; From b2f4b9376032c1f61651c886cf08bcf8df685f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 17 Sep 2024 18:27:37 +0200 Subject: [PATCH 096/201] Trying out different cross validations --- Emilio/ephysBehaviourRegression.m | 79 +++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index fc96f21..f3c2e7b 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -36,12 +36,14 @@ mdl_btx = fit_poly( [1, size( behSignals, 1 )], [0, size( behSignals, 1 )/fr] + [1,-1] * (1/fr), 1 ); btx = (1:size( behSignals, 1 ))'.^[1,0] * mdl_btx; my_xor = @(x) xor( x(:,1), x(:,2) ); +my_cat = @(x,d) cat( d, x{:} ); +m = 1e-3; % time_limits = [0, length(behSignals)/fr]; cS = configStructure; -rel_win = [-0.8, 0.8]; -del_win = [-50, 50]*1e-3; -bin_size = 5e-3; +rel_win = [-1, 1]*0.8; +del_win = [-50, 50]*m; +bin_size = 5*m; cS.BinSize_s = bin_size; Nb = ceil( diff( rel_win )/ bin_size ); % Nb = ceil( diff( time_limits ) / bin_size ); @@ -77,9 +79,8 @@ del_win(2)-(bin_size/2), Nd ); % tr_ID = ceil( ( 1:(Nr*Nb) )' / Nb ); parfor r = 1:(Nr*Nb) - tempC = arrayfun(@(u) interp1( bin_centres, binned_spikes(u,:), ... - bin_ax(r,:) ), 1:Nu, fnOpts{:} ); - tempC = cat( 1, tempC{:} ); + tempC = my_cat( arrayfun( @(u) interp1( bin_centres, binned_spikes(u,:), ... + bin_ax(r,:) ), 1:Nu, fnOpts{:} ), 1); auX( r, :, :) = tempC; end @@ -97,15 +98,75 @@ aux = cat( 2, aux{:} ); y(idx,:) = aux; end +%% +tr_ID = tocol( ones( Nb, 1 ) * (1:Nr) ); +rmse = zeros( 15 , 1 ); mdl = cell( size( rmse ) ); +parfor ii = 1:15 + testTrials = sort( randperm( Nr, round( Nr*0.15 ) ) ); + trainingTrials = setdiff( 1:Nr, testTrials ); + trainingIdx = any( tr_ID == trainingTrials(:)', 2 ); + testIdx = ~trainingIdx; + + mdl{ii} = fitlm( X(trainingIdx,:), y(trainingIdx,1) ); + y_pred = predict( mdl{ii}, X(testIdx,:) ); + rmse(ii) = sqrt( mean( ( y(testIdx,1) - y_pred ).^2 ) ); +end + +[~, min_error] = min(rmse); +y_all_pred = predict( mdl{min_error}, X ); + +y_1 = reshape( y(:,1), Nb, Nr ); +y_all_pred = reshape( y_all_pred, Nb, Nr ); +%% Training -tr_ID = tocol( ones( Nb, 1) * (1:Nr) ); -cv_kf = cvpartition( tr_ID, "KFold", 15 ); +ho_trials = randperm( Nr, round( Nr*0.1 ) ); +testIdx = any( tr_ID == sort(ho_trials), 2 ); +cv_kf = cvpartition( tr_ID( ~testIdx ), "KFold", 15 ); -[mdl, fitInfo] = lassoglm( X, Y, 'normal', ... +Xtrain = X(~testIdx, :); ytrain = y(~testIdx,1); + +[mdl, fitInfo] = lassoglm( X(~testIdx,:), y(~testIdx,1), 'normal', ... 'CV', cv_kf, 'Lambda', logspace( -5, 3, 64 ), ... 'Options', statset('UseParallel', true ), ... 'Alpha', eps ); +w_vec = [fitInfo.Intercept(fitInfo.IndexMinDeviance); + mdl(:,fitInfo.IndexMinDeviance)]; +y_pred = glmval( w_vec, X, "identity" ); +y_pred = reshape( y_pred, Nb, Nr ); +clrMap = [0.15*ones(1,3); 0.85,0.51,0.15 ]; +figure; lObj = line( 1:(Nb*numel( ho_trials )), [y(testIdx,1), y_pred(:)] ); +arrayfun(@(ii,x) set( x, 'Color', clrMap(ii,:) ), (1:numel(lObj))', lObj(:) ) + +createtiles = @(f,nr,nc) tiledlayout( f, nr, nc, ... + 'TileSpacing', 'Compact', 'Padding', 'tight'); +cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); + +fig = figure( 'Color', 'w' ); t = createtiles( fig, 10, 2); +nexttile([8, 1]); +imagesc( ttx, [], y_1' - 90); colormap(inferno) +xline(0, 'LineStyle', '--', 'Color', 0.85*ones(1,3) ) +nexttile([8, 1]); +imagesc( ttx, [], y_pred' - 90); colormap(inferno) +set( get( gca, 'YAxis' ), 'Visible', 'off' ) +nexttile(t); +line( ttx, mean( y_1, 2 ) - 90, 'Color', 0.15*ones(1,3), 'LineWidth', 1.5 ) +nexttile(t); +line( ttx, mean( y_pred, 2 ) - 90, 'Color', [0.85, 0.51, 0.15] , 'LineWidth', 1.5 ) +axs = get( t, "Children" ); +linkaxes( axs, 'x') +xlim(ttx([1,end])) +arrayfun(@(x) set( get( x, "XAxis" ), "Visible", "off" ), axs(3:4) ) +arrayfun(@(x) xticklabels( x, xticks(x) / m ), axs(1:2) ) + +rmse = mean( ( y_1 - y_pred ).^2, 1 ); + + +wtx = (del_win(1) + bin_size/2):bin_size:(del_win(2) - bin_size/2); +ttx = (rel_win(1) + bin_size/2):bin_size:(rel_win(2) - bin_size/2); + +figure; imagesc( wtx, [], reshape( w_vec(2:end), Nd, Nu )' ) + %% Design matrix for the whole experiment Nb = ceil( diff( bin_edges([1,end]) )/ bin_size ); auX = zeros( Nb, Nu, Nd ); From 0930eed7c2afea49b6196a1efeb0771f0c8f44b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 18 Sep 2024 18:17:40 +0200 Subject: [PATCH 097/201] Trying mvregress --- Emilio/ephysBehaviourRegression.m | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index f3c2e7b..e3a4079 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -101,8 +101,9 @@ %% tr_ID = tocol( ones( Nb, 1 ) * (1:Nr) ); rmse = zeros( 15 , 1 ); mdl = cell( size( rmse ) ); -parfor ii = 1:15 - testTrials = sort( randperm( Nr, round( Nr*0.15 ) ) ); +Nk = round( Nr*0.15 ); +parfor ii = 1:Nk + testTrials = sort( randperm( Nr, Nk ) ); trainingTrials = setdiff( 1:Nr, testTrials ); trainingIdx = any( tr_ID == trainingTrials(:)', 2 ); testIdx = ~trainingIdx; @@ -117,6 +118,32 @@ y_1 = reshape( y(:,1), Nb, Nr ); y_all_pred = reshape( y_all_pred, Nb, Nr ); + +%% +cvk = 15; +Nk = round( Nr*0.15 ); +rmse = zeros( cvk , Ns ); +mdl = zeros( size( X, 2 ), size( y, 2 ), cvk ); +idxs = zeros( cvk, Nk ); [zy, y_mu, y_sig] = zscore(y, 0, 1); +parfor (ii = 1:cvk, 3) + fprintf(1, 'K:%d\n', ii) + testTrials = sort( randperm( Nr, Nk ) ); + idxs(ii,:) = testTrials; + trainingTrials = setdiff( 1:Nr, testTrials ); + trainingIdx = any( tr_ID == trainingTrials, 2 ); + testIdx = ~trainingIdx; + + mdl(:,:,ii) = mvregress( gpuArray( X(trainingIdx,:) ), ... + gpuArray( zy(trainingIdx,:) ) ); + y_pred = X(testIdx,:) * mdl(:,:,ii); + rmse(ii,:) = sqrt( mean( ( zy(testIdx,:) - y_pred ).^2 ) ); +end + +[~, min_error] = min(rmse,[],1); +y_all_pred = X * squeeze( mean( mdl, 3 ) ); + +y_trials = reshape( y, Nb, Nr, Ns ); +y_all_pred = reshape( y_all_pred, Nb, Nr, Ns ); %% Training ho_trials = randperm( Nr, round( Nr*0.1 ) ); From c0010380471ec3d2aea535acb9751f2376e95908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 18 Sep 2024 18:22:31 +0200 Subject: [PATCH 098/201] Having trouble with the intercept --- Emilio/ephysBehaviourRegression.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index e3a4079..7282ec1 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -124,7 +124,7 @@ Nk = round( Nr*0.15 ); rmse = zeros( cvk , Ns ); mdl = zeros( size( X, 2 ), size( y, 2 ), cvk ); -idxs = zeros( cvk, Nk ); [zy, y_mu, y_sig] = zscore(y, 0, 1); +idxs = zeros( cvk, Nk ); %[zy, y_mu, y_sig] = zscore(y, 0, 1); parfor (ii = 1:cvk, 3) fprintf(1, 'K:%d\n', ii) testTrials = sort( randperm( Nr, Nk ) ); @@ -134,9 +134,9 @@ testIdx = ~trainingIdx; mdl(:,:,ii) = mvregress( gpuArray( X(trainingIdx,:) ), ... - gpuArray( zy(trainingIdx,:) ) ); + gpuArray( y(trainingIdx,:) ) ); y_pred = X(testIdx,:) * mdl(:,:,ii); - rmse(ii,:) = sqrt( mean( ( zy(testIdx,:) - y_pred ).^2 ) ); + rmse(ii,:) = sqrt( mean( ( y(testIdx,:) - y_pred ).^2 ) ); end [~, min_error] = min(rmse,[],1); From c1b397f909494c5c72ce59d9640b1acdbbc75255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 19 Sep 2024 14:37:57 +0200 Subject: [PATCH 099/201] Solved intercept --- Emilio/ephysBehaviourRegression.m | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index 7282ec1..1515786 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -123,9 +123,10 @@ cvk = 15; Nk = round( Nr*0.15 ); rmse = zeros( cvk , Ns ); -mdl = zeros( size( X, 2 ), size( y, 2 ), cvk ); +mdl = zeros( size( X, 2 )+Ns, size( y, 2 ), cvk ); idxs = zeros( cvk, Nk ); %[zy, y_mu, y_sig] = zscore(y, 0, 1); -parfor (ii = 1:cvk, 3) +X2 = [[eye(Ns); zeros( size(X,1) - Ns, Ns )], X]; +for ii = 1:cvk fprintf(1, 'K:%d\n', ii) testTrials = sort( randperm( Nr, Nk ) ); idxs(ii,:) = testTrials; @@ -133,14 +134,14 @@ trainingIdx = any( tr_ID == trainingTrials, 2 ); testIdx = ~trainingIdx; - mdl(:,:,ii) = mvregress( gpuArray( X(trainingIdx,:) ), ... + mdl(:,:,ii) = mvregress( gpuArray( X2(trainingIdx,:) ), ... gpuArray( y(trainingIdx,:) ) ); - y_pred = X(testIdx,:) * mdl(:,:,ii); + y_pred = X2(testIdx,:) * mdl(:,:,ii); rmse(ii,:) = sqrt( mean( ( y(testIdx,:) - y_pred ).^2 ) ); end [~, min_error] = min(rmse,[],1); -y_all_pred = X * squeeze( mean( mdl, 3 ) ); +y_all_pred = X2 * squeeze( mean( mdl, 3 ) ); y_trials = reshape( y, Nb, Nr, Ns ); y_all_pred = reshape( y_all_pred, Nb, Nr, Ns ); From d3ed5187f67692a81ad8533fd87437a994278417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 19 Sep 2024 17:17:14 +0200 Subject: [PATCH 100/201] Figuring out what's the best regression --- Emilio/ephysBehaviourRegression.m | 45 +++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index 1515786..f4a7d6a 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -31,6 +31,9 @@ load( fullfile( eph_path, "GADi43_C+F_2200analysis.mat" ) ) load( fullfile( eph_path, "GADi43_C+F_2200_Spike_Times.mat" ) ) stop_time = length( Triggers.Whisker )/ fs; +bp_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... + "Nonstim-whisker mean", "Nonstim-whisker fan arc", ... + "Interwhisker arc", "Symmetry", "Nose", "Roller speed"]; %% behSignals = [behDLCSignals, vf]; mdl_btx = fit_poly( [1, size( behSignals, 1 )], [0, size( behSignals, 1 )/fr] + [1,-1] * (1/fr), 1 ); @@ -99,25 +102,51 @@ y(idx,:) = aux; end %% +cvk = 15; +tr_ID = tocol( ones( Nb, 1 ) * (1:Nr) ); +rmse1v = zeros( cvk , 1 ); mdl1v = cell( size( rmse1v ) ); +Nk = round( Nr*0.15 ); +parfor ii = 1:cvk + testTrials = sort( randperm( Nr, Nk ) ); + trainingTrials = setdiff( 1:Nr, testTrials ); + trainingIdx = any( tr_ID == trainingTrials(:)', 2 ); + testIdx = ~trainingIdx; + + mdl1v{ii} = fitlm( X(trainingIdx,:), y(trainingIdx,1) ); + y_pred = predict( mdl1v{ii}, X(testIdx,:) ); + rmse1v(ii) = sqrt( mean( ( y(testIdx,1) - y_pred ).^2 ) ); +end + +[~, min_error] = min(rmse1v); +y_1_pred = predict( mdl1v{min_error}, X ); + +y_1 = reshape( y(:,1), Nb, Nr ); +y_1_pred = reshape( y_1_pred, Nb, Nr ); + +%% +cvk = 15; Nlambda = 64; tr_ID = tocol( ones( Nb, 1 ) * (1:Nr) ); -rmse = zeros( 15 , 1 ); mdl = cell( size( rmse ) ); +rmse1v = zeros( cvk , Nlambda ); +mdl1v = zeros( size(X,2)+1, Nlambda, cvk ); Nk = round( Nr*0.15 ); -parfor ii = 1:Nk +lambdas = logspace( -3, 2, Nlambda); +parfor ii = 1:cvk testTrials = sort( randperm( Nr, Nk ) ); trainingTrials = setdiff( 1:Nr, testTrials ); trainingIdx = any( tr_ID == trainingTrials(:)', 2 ); testIdx = ~trainingIdx; - mdl{ii} = fitlm( X(trainingIdx,:), y(trainingIdx,1) ); - y_pred = predict( mdl{ii}, X(testIdx,:) ); - rmse(ii) = sqrt( mean( ( y(testIdx,1) - y_pred ).^2 ) ); + mdl1v(:,:,ii) = ridge( y(trainingIdx,1), ... + [ones( sum( trainingIdx ), 1 ), X(trainingIdx,:)], lambdas ); + y_pred = [ones( Nk*Nb, 1), X(testIdx,:)] * mdl1v(:,:,ii); + rmse1v(ii,:) = sqrt( mean( ( y(testIdx,1) - y_pred ).^2 ) ); end -[~, min_error] = min(rmse); -y_all_pred = predict( mdl{min_error}, X ); +[~, min_error] = min(rmse1v); +y_1_pred = [ones( Nb*Nr, 1 ), X] * mdl1v; y_1 = reshape( y(:,1), Nb, Nr ); -y_all_pred = reshape( y_all_pred, Nb, Nr ); +y_1_pred = reshape( y_1_pred, Nb, Nr ); %% cvk = 15; From a8de611e478de1f0fdd4492cbf48d80075573d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 20 Sep 2024 17:31:40 +0200 Subject: [PATCH 101/201] Improving the wording --- Emilio/ephysBehaviourRegression.m | 144 +++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 30 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index f4a7d6a..980c13c 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -19,17 +19,34 @@ %% fnOpts = {'UniformOutput', false}; tocol = @(x) x(:); +getAbsPath = @(x) string( fullfile( x.folder, x.name ) ); roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; -data_path = fullfile( roller_path, "Batch18_ephys\MC\GADi43\240227_C+F_2200" ); -eph_path = fullfile( data_path, "ephys_E1" ); +data_path = fullfile( roller_path, "Batch19_ephys\BC\GADi47\240427_C+F_2150" ); +eph_path = dir( fullfile( data_path, "ephys*" ) ); +if ~isempty( eph_path ) + eph_path = getAbsPath( eph_path ); +else + fprintf(1, 'No ephys folder found!\n') + return +end beh_path = fullfile( data_path, "Behaviour" ); -load( fullfile( beh_path, "BehaviourSignals2024-02-27T11_26_07+T11_43_01.mat" ) ) -load( fullfile( beh_path, "RollerSpeed2024-02-27T11_26_07+T11_43_01.mat" ) ) -% load( fullfile( eph_path, "GADi43_C+F_2200_all_channels.mat" ) ) -load( fullfile( eph_path, ... - "GADi43_C+F_2200 RW20.00-50.00 SW-180.00--150.00 VW-300.00-400.00 ms PuffAll (unfiltered) RelSpkTms.mat" ), "configStructure" ) -load( fullfile( eph_path, "GADi43_C+F_2200analysis.mat" ) ) -load( fullfile( eph_path, "GADi43_C+F_2200_Spike_Times.mat" ) ) + +beh_pttrns = ["RollerSpeed*.mat", "BehaviourSignals*.mat"]; +bfs_paths = arrayfun(@(pt) dir( fullfile( beh_path, pt) ), beh_pttrns ); +if any( ~arrayfun(@(x) exist( getAbsPath(x), "file" ), bfs_paths ) ) + fprintf(1, 'Not all necessary behaviour files exist!\n') + return +end +for x=bfs_paths, load( getAbsPath( x ) ), end + +eph_pttrns = ["*_Spike_Times.mat", "*analysis.mat"]; +efs_paths = arrayfun(@(pt) dir( fullfile( eph_path, pt) ), eph_pttrns ); +if any( ~arrayfun(@(x) exist( getAbsPath(x), "file" ), efs_paths ) ) + fprintf(1, 'Not all necessary ephys files exist!\n') + return +end +for x=efs_paths, load( getAbsPath( x ) ), end + stop_time = length( Triggers.Whisker )/ fs; bp_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... "Nonstim-whisker mean", "Nonstim-whisker fan arc", ... @@ -43,16 +60,18 @@ m = 1e-3; % time_limits = [0, length(behSignals)/fr]; -cS = configStructure; + rel_win = [-1, 1]*0.8; -del_win = [-50, 50]*m; -bin_size = 5*m; -cS.BinSize_s = bin_size; +del_win = [-100, 100]*m; +bin_size = 10*m; + Nb = ceil( diff( rel_win )/ bin_size ); % Nb = ceil( diff( time_limits ) / bin_size ); Nu = numel( spike_times ); % cons_time = my_xor( btx > time_limits ); Ns = size( behSignals, 2 ); +wtx = (del_win(1) + bin_size/2):bin_size:(del_win(2) - bin_size/2); +ttx = (rel_win(1) + bin_size/2):bin_size:(rel_win(2) - bin_size/2); %% bin_edges = 0:bin_size:stop_time; bin_centres = mean( [bin_edges(1:end-1); bin_edges(2:end)] ); @@ -68,8 +87,9 @@ binned_beh(b,:) = mean( behSignals( idx , : ), 1 ); end -%% Design matrix for a set of trials -time_limits = Conditions(3).Triggers(:,1)./fs + rel_win; +%% Design matrix for a set of trials (Control) +ctrl_sub = ismember( string( {Conditions.name} ), "Control Puff" ); +time_limits = Conditions(ctrl_sub).Triggers(:,1)./fs + rel_win; Nr = size( time_limits, 1 ); Nd = ceil( diff( del_win ) / bin_size ); auX = zeros( Nb*Nr, Nu, Nd ); @@ -87,9 +107,8 @@ auX( r, :, :) = tempC; end -X = reshape( auX, [], Nu*Nd ); clearvars auX; -X2 = [ ones( Nb*Nr, 1), X]; -Xp = X2; +X = reshape( auX, Nb*Nr, Nu*Nd ); clearvars auX; +Xp = [ ones( Nb*Nr, 1), X]; %% Multivariate regression response matrix %X2 = [ ones( Nb*Nr, 1), X]; %lmObjs = cell( Ns, 1 ); @@ -101,7 +120,8 @@ aux = cat( 2, aux{:} ); y(idx,:) = aux; end -%% +%{ +%% Linear regression using fitlm cvk = 15; tr_ID = tocol( ones( Nb, 1 ) * (1:Nr) ); rmse1v = zeros( cvk , 1 ); mdl1v = cell( size( rmse1v ) ); @@ -123,32 +143,94 @@ y_1 = reshape( y(:,1), Nb, Nr ); y_1_pred = reshape( y_1_pred, Nb, Nr ); -%% +%% Linear regression using ridge regularisation cvk = 15; Nlambda = 64; tr_ID = tocol( ones( Nb, 1 ) * (1:Nr) ); rmse1v = zeros( cvk , Nlambda ); mdl1v = zeros( size(X,2)+1, Nlambda, cvk ); Nk = round( Nr*0.15 ); -lambdas = logspace( -3, 2, Nlambda); +lambdas = logspace( 3, 8, Nlambda); parfor ii = 1:cvk testTrials = sort( randperm( Nr, Nk ) ); trainingTrials = setdiff( 1:Nr, testTrials ); trainingIdx = any( tr_ID == trainingTrials(:)', 2 ); testIdx = ~trainingIdx; - - mdl1v(:,:,ii) = ridge( y(trainingIdx,1), ... - [ones( sum( trainingIdx ), 1 ), X(trainingIdx,:)], lambdas ); - y_pred = [ones( Nk*Nb, 1), X(testIdx,:)] * mdl1v(:,:,ii); + + Xtrain = [ones( sum( trainingIdx ), 1 ), X(trainingIdx,:)]; + Xtest = [ones( sum( testIdx ), 1 ), X(testIdx,:)]; + % theta_0 = ( X2' * X2 ) \ ( X2' * y(trainingIdx,1) ) ; + mdl1v(:,:,ii) = ridge( y(trainingIdx,1), Xtrain, lambdas ); + y_pred = Xtest * mdl1v(:,:,ii); rmse1v(ii,:) = sqrt( mean( ( y(testIdx,1) - y_pred ).^2 ) ); end -[~, min_error] = min(rmse1v); -y_1_pred = [ones( Nb*Nr, 1 ), X] * mdl1v; +%} +%% Linear regression for all behavioural signals using matrix multiplication +cvk = 15; +tr_ID = tocol( ones( Nb, 1 ) * (1:Nr) ); +rmseAll_ind = zeros( cvk, Ns ); +mdlAll_ind = zeros( size(X,2)+1, cvk, Ns ); +Nk = round( Nr*0.15 ); idxs = zeros( cvk, Nk ); +parfor ii = 1:cvk + testTrials = sort( randperm( Nr, Nk ) ); + idxs(ii,:) = testTrials; + trainingTrials = setdiff( 1:Nr, testTrials ); + trainingIdx = any( tr_ID == trainingTrials, 2 ); + testIdx = ~trainingIdx; -y_1 = reshape( y(:,1), Nb, Nr ); -y_1_pred = reshape( y_1_pred, Nb, Nr ); + Xtrain = Xp(trainingIdx,:); Xtest = Xp(testIdx,:); + for cb = 1:Ns + ytrain = y(trainingIdx, cb); ytest = y(testIdx, cb); + mdlAll_ind(:,ii,cb) = ( Xtrain' * Xtrain ) \ ( Xtrain' * ytrain ) ; + %mdl1v(:,:,ii) = ridge( y(trainingIdx,1), Xtrain, lambdas ); + y_pred = Xtest * mdlAll_ind(:,ii,cb); + rmseAll_ind(ii,cb) = sqrt( mean( ( ytest - y_pred ).^2 ) ); + end +end -%% +save( fullfile( data_path, "Regression ephys2beh.mat"), "-v7.3" ) +%% +createtiles = @(f,nr,nc) tiledlayout( f, nr, nc, ... + 'TileSpacing', 'Compact', 'Padding', 'tight'); +cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); +figWeight = figure('Color', 'w'); t = createtiles( figWeight, 2, 4 ); +mdlAll_ind_norm = [mdlAll_ind(1,:,:); + mdlAll_ind(2:end,:,:) ./ vecnorm( mdlAll_ind(2:end,:,:), 2, 1 )]; +mdl_mu = squeeze( mean( mdlAll_ind_norm, 2 ) ); +for cb = 1:Ns + ax = nexttile(t); + imagesc( ax, wtx/m, [], reshape( mdl_mu(2:end,cb), Nu, Nd ) ) + cleanAxis( ax ); yticks( ax, 1:Nu ); title( ax, bp_names( cb ) ); + colormap( traffic ); clim( 1.3*max(abs(mdl_mu(2:end,cb)))*[-1,1] ) + cbObj = colorbar( 'Box', 'off', 'AxisLocation', 'out', ... + 'TickDirection', 'out', 'Location', 'northoutside' ); +end +xlabel(ax, 'Time [ms]'); axs = findobj( t, "Type", "Axes" ); +ylabel( axs(end), 'Units' ) +title( t, 'Regression weights' ) +arrayfun(@(x) set( get( x, "YAxis" ), "Visible", "off" ), ... + axs(setdiff( 1:Ns, [4,8] )) ) +arrayfun(@(x) set( get( x, "XAxis" ), "Visible", "off" ), axs(5:8) ) + +saveFigure( figWeight, fullfile( eph_path, "Figures", ... + sprintf( "Regression weights CW%.2f-%.2fms DW%.2f-%.2f BZ%.2f", ... + rel_win/m, del_win/m, bin_size/m ) ), true ) +%% +errFig = figure("color", "w"); t = createtiles( errFig, 1, 1 ); +ax = nexttile(t); +gray15pc = 0.15*ones(1,3); +boxchart(ax, rmseAll_ind./range(y) , 'Notch', 'on', ... + 'BoxFaceColor', gray15pc, 'JitterOutliers', 'on', ... + 'MarkerStyle', '.', 'MarkerColor', gray15pc ); +xticklabels( ax, bp_names ); cleanAxis( ax ); +ylabel( ax, 'Normalised error' ) +title( ax, sprintf( '%d-kfold cross-validated error', cvk ) ) + +saveFigure( errFig, fullfile( eph_path, "Figures", ... + sprintf( "%d-kfold cv error CW%.2f-%.2fms DW%.2f-%.2f BZ%.2f", ... + cvk, rel_win/m, del_win/m, bin_size/m ) ), true ) +%{ +%% Multiple output linear regression cvk = 15; Nk = round( Nr*0.15 ); rmse = zeros( cvk , Ns ); @@ -174,6 +256,7 @@ y_trials = reshape( y, Nb, Nr, Ns ); y_all_pred = reshape( y_all_pred, Nb, Nr, Ns ); + %% Training ho_trials = randperm( Nr, round( Nr*0.1 ) ); @@ -239,3 +322,4 @@ X = reshape( auX, [], Nu*Nd ); X2 = [ ones( Nb*Nr, 1), X]; Xa = X2; +%} From 7e4564cb0bf779b80536b20814883c2c96b43843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Sun, 22 Sep 2024 23:44:48 +0200 Subject: [PATCH 102/201] Added delay section and renamed -mat file --- Emilio/ephysBehaviourRegression.m | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index 980c13c..2aa4e92 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -21,7 +21,7 @@ tocol = @(x) x(:); getAbsPath = @(x) string( fullfile( x.folder, x.name ) ); roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; -data_path = fullfile( roller_path, "Batch19_ephys\BC\GADi47\240427_C+F_2150" ); +data_path = fullfile( roller_path, "Batch16_ephys/MC/GADi35/231204_C+F_2450"); eph_path = dir( fullfile( data_path, "ephys*" ) ); if ~isempty( eph_path ) eph_path = getAbsPath( eph_path ); @@ -109,6 +109,31 @@ X = reshape( auX, Nb*Nr, Nu*Nd ); clearvars auX; Xp = [ ones( Nb*Nr, 1), X]; + +%% Delay +delay_sub = cellfun(@(x) ~isempty(x), regexp( string( {Conditions.name} ), ... + 'Delay \d\.\d+\ss\s\+\sL' ) ); + +time_limits = Conditions(delay_sub).Triggers(:,1)./fs + rel_win; +Nr = size( time_limits, 1 ); +Nd = ceil( diff( del_win ) / bin_size ); +auX = zeros( Nb*Nr, Nu, Nd ); + +cwin = arrayfun(@(x) linspace( time_limits(x,1) + (bin_size/2), ... + time_limits(x,2) - (bin_size/2), Nb )', (1:Nr)', fnOpts{:} ); +cwin = cat( 1, cwin{:} ); + +bin_ax = cwin + linspace( del_win(1)+(bin_size/2), ... + del_win(2)-(bin_size/2), Nd ); +% tr_ID = ceil( ( 1:(Nr*Nb) )' / Nb ); +parfor r = 1:(Nr*Nb) + tempC = my_cat( arrayfun( @(u) interp1( bin_centres, binned_spikes(u,:), ... + bin_ax(r,:) ), 1:Nu, fnOpts{:} ), 1); + auX( r, :, :) = tempC; +end + +X = reshape( auX, Nb*Nr, Nu*Nd ); clearvars auX; +Xl = [ ones( Nb*Nr, 1), X]; %% Multivariate regression response matrix %X2 = [ ones( Nb*Nr, 1), X]; %lmObjs = cell( Ns, 1 ); @@ -188,7 +213,8 @@ end end -save( fullfile( data_path, "Regression ephys2beh.mat"), "-v7.3" ) +save( fullfile( data_path, sprintf( "Regression CW%.2f-%.2fms DW%.2f-%.2f BZ%.2f.mat", ... + rel_win/m, del_win/m, bin_size/m ) ), "-v7.3" ) %% createtiles = @(f,nr,nc) tiledlayout( f, nr, nc, ... 'TileSpacing', 'Compact', 'Padding', 'tight'); From c24cdd8bc8c55ec2915472baa2c77bbb86545c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 24 Sep 2024 19:06:20 +0200 Subject: [PATCH 103/201] Saving parameters in file names --- Emilio/ephysBehaviourRegression.m | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index 2aa4e92..1914060 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -1,4 +1,3 @@ - %{ res_gof = zeros( 15, 1 ); % feps = zeros( 15, 1 ); @@ -51,6 +50,8 @@ bp_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... "Nonstim-whisker mean", "Nonstim-whisker fan arc", ... "Interwhisker arc", "Symmetry", "Nose", "Roller speed"]; + +analysis_pttrn = "CW%.2f-%.2fms DW%.2f-%.2f BZ%.2f"; %% behSignals = [behDLCSignals, vf]; mdl_btx = fit_poly( [1, size( behSignals, 1 )], [0, size( behSignals, 1 )/fr] + [1,-1] * (1/fr), 1 ); @@ -59,8 +60,6 @@ my_cat = @(x,d) cat( d, x{:} ); m = 1e-3; -% time_limits = [0, length(behSignals)/fr]; - rel_win = [-1, 1]*0.8; del_win = [-100, 100]*m; bin_size = 10*m; @@ -212,9 +211,9 @@ rmseAll_ind(ii,cb) = sqrt( mean( ( ytest - y_pred ).^2 ) ); end end - -save( fullfile( data_path, sprintf( "Regression CW%.2f-%.2fms DW%.2f-%.2f BZ%.2f.mat", ... - rel_win/m, del_win/m, bin_size/m ) ), "-v7.3" ) +analysis_key = sprintf( analysis_pttrn, rel_win/m, del_win/m, bin_size/m ); +save( fullfile( data_path, join( ["Regression", analysis_key + ".mat"] ) ), ... + "-v7.3" ) %% createtiles = @(f,nr,nc) tiledlayout( f, nr, nc, ... 'TileSpacing', 'Compact', 'Padding', 'tight'); @@ -253,8 +252,7 @@ title( ax, sprintf( '%d-kfold cross-validated error', cvk ) ) saveFigure( errFig, fullfile( eph_path, "Figures", ... - sprintf( "%d-kfold cv error CW%.2f-%.2fms DW%.2f-%.2f BZ%.2f", ... - cvk, rel_win/m, del_win/m, bin_size/m ) ), true ) + join( [sprintf( "%d-fold cv error", cvk ), analysis_key] ) ), true ) %{ %% Multiple output linear regression cvk = 15; From 1d961a0bd550c7dfb0958c1b56f5a904fd5efadb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 27 Sep 2024 18:34:54 +0200 Subject: [PATCH 104/201] Trying to reduce disk memory --- Emilio/ephysBehaviourRegression.m | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index 1914060..0eddbb1 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -213,8 +213,8 @@ end analysis_key = sprintf( analysis_pttrn, rel_win/m, del_win/m, bin_size/m ); save( fullfile( data_path, join( ["Regression", analysis_key + ".mat"] ) ), ... - "-v7.3" ) -%% + "mdlAll_ind", "DX", "params", "-v7.3" ) +%% Weight matrices createtiles = @(f,nr,nc) tiledlayout( f, nr, nc, ... 'TileSpacing', 'Compact', 'Padding', 'tight'); cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); @@ -240,7 +240,9 @@ saveFigure( figWeight, fullfile( eph_path, "Figures", ... sprintf( "Regression weights CW%.2f-%.2fms DW%.2f-%.2f BZ%.2f", ... rel_win/m, del_win/m, bin_size/m ) ), true ) -%% +%% Reconstruction error (trial-wise) + +%% Total error per body part errFig = figure("color", "w"); t = createtiles( errFig, 1, 1 ); ax = nexttile(t); gray15pc = 0.15*ones(1,3); From 3b761961df358238a4885d2ad0847e51c30abdd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 4 Oct 2024 17:01:47 +0200 Subject: [PATCH 105/201] Create poolEphBeh_regression.m --- Emilio/poolEphBeh_regression.m | 111 +++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Emilio/poolEphBeh_regression.m diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m new file mode 100644 index 0000000..695cec7 --- /dev/null +++ b/Emilio/poolEphBeh_regression.m @@ -0,0 +1,111 @@ +%#ok<*AGROW,*SAGROW> +%% Auxiliary variables and functions +fnOpts = {'UniformOutput', false}; +expandName = @(x) fullfile(x.folder, x.name); +animalPattern = '[a-zA-Z]+\d{1,}'; +rsOpts = {animalPattern, 'SearchType', 'expression'}; +ctOpts = {'IgnoreCase', true}; +lsOpts = {'L\d+.\d+', 'match'}; +ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; +tblOpts = {'VariableNames', {'Conditions', 'MI'}}; +my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +getMI = @(x,d) diff(x, 1, d)./sum(x, d); +total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); +tocol = @(x) x(:); +m = 1e-3; +exclude_names = {'GADi13', 'GADi15', 'GADi53'}; + +iRN_mice = dir( "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch*\MC\GADi*" ); +animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); +exclude_flags = contains( animalFolders, exclude_names ); +params = struct( 'relative_window', [-1,1]*800*m, 'delay_window', ... + [-1,1]*100*m, 'bin_size', 5*m, 'kfold', 20 ); +%% Looping animals +oldMouse = ""; +mc = 0; mice = []; lp_mu = []; lPSTH = []; +for cad = tocol(animalFolders(~exclude_flags))' + [structPath, currMouse] = fileparts(cad); + [~, structName] = fileparts(structPath); + if string(oldMouse) ~= string(currMouse) + oldMouse = currMouse; + mice = [mice; struct('Name', currMouse, 'Sessions',[], ... + 'Structure', structName)]; + mc = mc + 1; + sc = 0; oldSess = ""; oldDepth = ""; + end + sessDirs = getSubFolds(cad); + % Just date sessions + onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... + 'match')), sessDirs, fnOpts{:}); + sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; + for csd = sessDirs(:)' + curDir = expandName(csd); + sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})?', 'tokens', 'once'); + if ~isempty( sessDateDepth ) + currSess = sessDateDepth{1}; + if isempty( sessDateDepth{2} ) + depthSess = ''; + else + depthSess = sessDateDepth{2}; + end + else + currSess = regexp(csd.name, '(\d{6})', 'tokens', 'once'); + depthSess = ''; + if isempty(currSess) + fprintf( 1, "Unable to get session date and depth\n" ); + fprintf( 1, "Skipping: %s %s\n", currMouse, csd.name ) + continue + end + end + childFolders = getSubFolds(curDir); + sessOrgDirs = arrayfun(@(d) string(d.name), childFolders ); + sessOrgDirs( ~contains(sessOrgDirs, {'behaviour', 'ephys', ... + 'figures', 'opto'}, ctOpts{:}) ) = []; + if isempty(sessOrgDirs) + continue + end + data_path = curDir; + + [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); + mdl_mu = squeeze( mean( mdl, 2 ) ); + y_trials = reshape( DX{1}, params.Nb, params.Nr, params.Ns ); + y_pred = DX{2} * mdl_mu; + y_ptrials = reshape( y_pred, params.Nb, params.Nr, params.Ns ); + + SSEt = squeeze( sum( ( y_trials - y_ptrials ).^2, 1 ) ); + SSTt = squeeze( sum( ( y_trials - mean( y_trials, 1 ) ).^2, 1 ) ); + r_sq_trials = 1 - (SSEt./SSTt); + + SSE = sum( (DX{1} - y_pred).^2 ); + SST = sum( (DX{1} - mean( DX{1}, 1 ) ).^2 ); + r_sq = 1 - ( SSE./ SST ); + + dataTable = table( r_sq, {r_sq_trials}, ... + 'VariableNames', {'R_squared', 'R_squared_trials'}); + if ( string(oldSess) ~= string(currSess) ) || ... + ( string(oldDepth) ~= string(depthSess) ) + oldSess = currSess; + oldDepth = depthSess; + auxStruct = struct('Date', currSess, ... + 'DataTable', dataTable, 'Type', sessType, ... + 'Depth', depthSess); + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + sc = sc + 1; + end + end +end +mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; + +behFP = fullfile( "Z:\Emilio\SuperiorColliculusExperiments\Roller", "MCiRNs_regression_sm.mat" ); +svOpts = {'-mat'}; +if exist(behFP, "file") + svOpts = {'-append'}; +end +% save(behFP, "mice", svOpts{:}) +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +cat( 1, habFlag{:} ) From c7c8480c521a2d6d0685326aaaeaee4f5c8c1380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 7 Nov 2024 09:40:16 +0100 Subject: [PATCH 106/201] Moved laser condition X2 to the end --- Emilio/ephysBehaviourRegression.m | 50 ++++++++++++++++--------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/Emilio/ephysBehaviourRegression.m b/Emilio/ephysBehaviourRegression.m index 0eddbb1..15fb03a 100644 --- a/Emilio/ephysBehaviourRegression.m +++ b/Emilio/ephysBehaviourRegression.m @@ -109,30 +109,6 @@ X = reshape( auX, Nb*Nr, Nu*Nd ); clearvars auX; Xp = [ ones( Nb*Nr, 1), X]; -%% Delay -delay_sub = cellfun(@(x) ~isempty(x), regexp( string( {Conditions.name} ), ... - 'Delay \d\.\d+\ss\s\+\sL' ) ); - -time_limits = Conditions(delay_sub).Triggers(:,1)./fs + rel_win; -Nr = size( time_limits, 1 ); -Nd = ceil( diff( del_win ) / bin_size ); -auX = zeros( Nb*Nr, Nu, Nd ); - -cwin = arrayfun(@(x) linspace( time_limits(x,1) + (bin_size/2), ... - time_limits(x,2) - (bin_size/2), Nb )', (1:Nr)', fnOpts{:} ); -cwin = cat( 1, cwin{:} ); - -bin_ax = cwin + linspace( del_win(1)+(bin_size/2), ... - del_win(2)-(bin_size/2), Nd ); -% tr_ID = ceil( ( 1:(Nr*Nb) )' / Nb ); -parfor r = 1:(Nr*Nb) - tempC = my_cat( arrayfun( @(u) interp1( bin_centres, binned_spikes(u,:), ... - bin_ax(r,:) ), 1:Nu, fnOpts{:} ), 1); - auX( r, :, :) = tempC; -end - -X = reshape( auX, Nb*Nr, Nu*Nd ); clearvars auX; -Xl = [ ones( Nb*Nr, 1), X]; %% Multivariate regression response matrix %X2 = [ ones( Nb*Nr, 1), X]; %lmObjs = cell( Ns, 1 ); @@ -255,6 +231,32 @@ saveFigure( errFig, fullfile( eph_path, "Figures", ... join( [sprintf( "%d-fold cv error", cvk ), analysis_key] ) ), true ) + +%% Delay +delay_sub = cellfun(@(x) ~isempty(x), regexp( string( {Conditions.name} ), ... + 'Delay \d\.\d+\ss\s\+\sL' ) ); + +time_limits = Conditions(delay_sub).Triggers(:,1)./fs + rel_win; +Nr = size( time_limits, 1 ); +Nd = ceil( diff( del_win ) / bin_size ); +auX = zeros( Nb*Nr, Nu, Nd ); + +cwin = arrayfun(@(x) linspace( time_limits(x,1) + (bin_size/2), ... + time_limits(x,2) - (bin_size/2), Nb )', (1:Nr)', fnOpts{:} ); +cwin = cat( 1, cwin{:} ); + +bin_ax = cwin + linspace( del_win(1)+(bin_size/2), ... + del_win(2)-(bin_size/2), Nd ); +% tr_ID = ceil( ( 1:(Nr*Nb) )' / Nb ); +parfor r = 1:(Nr*Nb) + tempC = my_cat( arrayfun( @(u) interp1( bin_centres, binned_spikes(u,:), ... + bin_ax(r,:) ), 1:Nu, fnOpts{:} ), 1); + auX( r, :, :) = tempC; +end + +X = reshape( auX, Nb*Nr, Nu*Nd ); clearvars auX; +Xl = [ ones( Nb*Nr, 1), X]; + %{ %% Multiple output linear regression cvk = 15; From 3963b492161d48fe1e7e89a0f6a2aba0de296ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 7 Nov 2024 09:52:17 +0100 Subject: [PATCH 107/201] Error validation --- Emilio/poolEphBeh_regression.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 695cec7..006ff56 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -23,6 +23,7 @@ %% Looping animals oldMouse = ""; mc = 0; mice = []; lp_mu = []; lPSTH = []; +sessType = 'single'; for cad = tocol(animalFolders(~exclude_flags))' [structPath, currMouse] = fileparts(cad); [~, structName] = fileparts(structPath); @@ -67,6 +68,9 @@ data_path = curDir; [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); + if isempty(DX) + continue + end mdl_mu = squeeze( mean( mdl, 2 ) ); y_trials = reshape( DX{1}, params.Nb, params.Nr, params.Ns ); y_pred = DX{2} * mdl_mu; @@ -96,6 +100,7 @@ end sc = sc + 1; end + close all end end mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; From 8dd75a26d31bfe4060584af0508501cf6e763529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 7 Nov 2024 09:55:24 +0100 Subject: [PATCH 108/201] Blank spaces clean up --- Emilio/poolEphBeh_regression.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 006ff56..31ad5a7 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -80,10 +80,10 @@ SSTt = squeeze( sum( ( y_trials - mean( y_trials, 1 ) ).^2, 1 ) ); r_sq_trials = 1 - (SSEt./SSTt); - SSE = sum( (DX{1} - y_pred).^2 ); + SSE = sum( (DX{1} - y_pred).^2 ); SST = sum( (DX{1} - mean( DX{1}, 1 ) ).^2 ); r_sq = 1 - ( SSE./ SST ); - + dataTable = table( r_sq, {r_sq_trials}, ... 'VariableNames', {'R_squared', 'R_squared_trials'}); if ( string(oldSess) ~= string(currSess) ) || ... From e9306e35c935cfbdcd25b2ccf0795551fee217b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 7 Nov 2024 12:16:53 +0100 Subject: [PATCH 109/201] HPC vs Windows --- Emilio/poolEphBeh_regression.m | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 31ad5a7..d4a4a3b 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -15,11 +15,22 @@ m = 1e-3; exclude_names = {'GADi13', 'GADi15', 'GADi53'}; -iRN_mice = dir( "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch*\MC\GADi*" ); -animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); -exclude_flags = contains( animalFolders, exclude_names ); params = struct( 'relative_window', [-1,1]*800*m, 'delay_window', ... [-1,1]*100*m, 'bin_size', 5*m, 'kfold', 20 ); + +pc = parcluster('local'); +if ~strcmp( computer, 'PCWIN64') + HPC_setup; + roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; + nprocs = str2double(getenv('SLURM_NPROCS')); + parpool( pc, nprocs) +else + roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; + parpool( pc ) +end +iRN_mice = dir( fullfile( roller_path, "Batch*", "MC", "GADi*" ) ); +animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); +exclude_flags = contains( animalFolders, exclude_names ); %% Looping animals oldMouse = ""; mc = 0; mice = []; lp_mu = []; lPSTH = []; From f4e81d433b1bdd7fd2d15687222b85f61fc30392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 7 Nov 2024 14:15:50 +0100 Subject: [PATCH 110/201] Explicit path configuration --- Emilio/poolEphBeh_regression.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index d4a4a3b..7588cb7 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -20,7 +20,10 @@ pc = parcluster('local'); if ~strcmp( computer, 'PCWIN64') - HPC_setup; + home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; + repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... + {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); + addpath( repo_paths{:} ) roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; nprocs = str2double(getenv('SLURM_NPROCS')); parpool( pc, nprocs) From 6fdcd363b699b7210414dbf71a3c9a53b5b741ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 7 Nov 2024 18:14:39 +0100 Subject: [PATCH 111/201] Testing if 16 workers are recruited --- Emilio/poolEphBeh_regression.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 7588cb7..9eb8dbf 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -25,12 +25,11 @@ {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); addpath( repo_paths{:} ) roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; - nprocs = str2double(getenv('SLURM_NPROCS')); - parpool( pc, nprocs) else roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; - parpool( pc ) end +parpool( pc ) + iRN_mice = dir( fullfile( roller_path, "Batch*", "MC", "GADi*" ) ); animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); exclude_flags = contains( animalFolders, exclude_names ); From aa4cd82ea057de3fc2b53d26354ef5c6a249b17f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 7 Nov 2024 18:18:03 +0100 Subject: [PATCH 112/201] Adding with subfolders --- Emilio/poolEphBeh_regression.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 9eb8dbf..ec2334e 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -23,7 +23,7 @@ home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); - addpath( repo_paths{:} ) + cellfun(@(x) addpath( genpath( x ) ), repo_paths ) roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; else roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; From a029a703a924144f185ee348d0193894010ea7de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 8 Nov 2024 14:42:33 +0100 Subject: [PATCH 113/201] Removed useless computation of PSTHs --- Jesus/DE_Jittering.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index e378868..791e526 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -534,8 +534,8 @@ % PSTH construction psthFP = fullfile(ephFigDir, psthFN); if any(arrayfun(@(x) ~exist(x+".fig","file"), psthFP)) - [PSTH, trig] = arrayfun(@(x) getPSTH(discStack(filterIdx,:,:), ... - timeLapse, ~delayFlags(:,x), binSz, fs), 1:Nccond, fnOpts{:}); + % [PSTH, trig] = arrayfun(@(x) getPSTH(discStack(filterIdx,:,:), ... + % timeLapse, ~delayFlags(:,x), binSz, fs), 1:Nccond, fnOpts{:}); if exist('cst', 'var') && ~isempty(cst) % Take into account covariance for signals. stims = arrayfun(@(x) mean(cst(:,:,delayFlags(:,x)),3), 1:Nccond, ... @@ -543,7 +543,7 @@ else stims = repmat({zeros(1,Ntc)}, Nccond, 1); end - psthFigs = gobjects( numel(PSTH), 1 ); + psthFigs = gobjects( numel(psthFP), 1 ); auxID = pclID(ordSubs); auxStack = discStack(filterIdx,:,:); PSTH = cell(Nccond,1); %trig = PSTH; parfor cf = 1:Nccond From 04b18620ceef8eb48e1a0cfc7280ce653405c589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 8 Nov 2024 14:42:37 +0100 Subject: [PATCH 114/201] Create logreg.m --- Emilio/logreg.m | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Emilio/logreg.m diff --git a/Emilio/logreg.m b/Emilio/logreg.m new file mode 100644 index 0000000..28af697 --- /dev/null +++ b/Emilio/logreg.m @@ -0,0 +1,4 @@ +function y_hat = logreg(Xtrain, ytrain, Xtest) +mdl = lassoglm( Xtrain, ytrain, 'Distribution', 'binomial', 'Link', 'logit' ); +y_hat = predict(mdl, Xtest); +end \ No newline at end of file From 44171f0647514231ed8a94f5ddb1698c65bec9ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 8 Nov 2024 14:42:40 +0100 Subject: [PATCH 115/201] Create Synchrony.m --- Emilio/Synchrony.m | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Emilio/Synchrony.m diff --git a/Emilio/Synchrony.m b/Emilio/Synchrony.m new file mode 100644 index 0000000..4579228 --- /dev/null +++ b/Emilio/Synchrony.m @@ -0,0 +1,26 @@ +time_scale = 2.5e-3; delta_t = 5e-4; synchTrial = []; + +for ccond = 1:length(relativeSpkTmsStruct) + for ctr = 1:size(relativeSpkTmsStruct(ccond).SpikeTimes,2) + spks_in_trial = [relativeSpkTmsStruct(ccond).SpikeTimes{:,ctr}]; + c_end = vw(1) + time_scale; c_init = vw(1); + while c_end <= vw(2) + spks_in_cons = spks_in_trial(spks_in_trial > c_init & ... + spks_in_trial < c_end); + if ~isempty(spks_in_cons) && numel(spks_in_cons) > 1 + dm = pdist([spks_in_cons(:)], "euclidean"); + if numel(dm) > 1 + lnorm_fit = fitdist(dm(:), "Normal"); + synchTrial = [synchTrial; ccond, ctr, ... + mean([c_init, c_end]), ... + log(lnorm_fit.ParameterValues(1))]; + else + synchTrial = [synchTrial; ccond, ctr, ... + mean([c_init, c_end]), log(dm(:))]; + end + end + c_init = c_init + delta_t; + c_end = c_end + delta_t; + end + end +end \ No newline at end of file From 45ea9d42938523e630c2165c899483dc96d7d914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 8 Nov 2024 14:42:42 +0100 Subject: [PATCH 116/201] Update chiCuadrado.m --- Jesus/chiCuadrado.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/chiCuadrado.m b/Jesus/chiCuadrado.m index 7e9bceb..c138bfb 100644 --- a/Jesus/chiCuadrado.m +++ b/Jesus/chiCuadrado.m @@ -1,5 +1,5 @@ tbl = [68, 33, 217;... - 33, 35, 180]; + 33, 35, 180]; sumCol = sum(tbl)'; sumFil = sum(tbl,2)'; multSum = (sumCol * sumFil)'; From 4784796aba2a800c271c3b54586101b279f1ba59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 11 Nov 2024 16:43:50 +0100 Subject: [PATCH 117/201] Error validation --- Emilio/poolEphBeh_regression.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index ec2334e..8c558e8 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -81,7 +81,7 @@ data_path = curDir; [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); - if isempty(DX) + if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 continue end mdl_mu = squeeze( mean( mdl, 2 ) ); From 339db77fab3cb89b0cf76d9a6e2894563f773735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 11 Nov 2024 16:44:07 +0100 Subject: [PATCH 118/201] OS figure parameter for HPC and Win --- Jesus/DE_Jittering.m | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 791e526..8a862a7 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -31,9 +31,14 @@ end fnOpts = {'UniformOutput', false}; axOpts = {'Box','off','Color','none'}; -fgOpts = {'new', 'visible'}; +ofgOpts = {'new', 'visible'}; spk_file_vars = {'spike_times','gclID','Nt','Ns','goods'}; owFlag = false; +figOpts = {'Visible','on'}; +if ~strcmp( computer, 'PCWIN64' ) + figOpts(2) = {'off'}; + ofgOpts(2) = {'invisible'}; +end %% Constructing the helper 'global' variables spkPttrn = "%s_Spike_Times.mat"; @@ -390,7 +395,7 @@ if exist(resFP,"file") && all(arrayfun(@(x) exist(x, "file"), stFigFN + ".fig")) load(resFP, "Results", "Counts") - arrayfun(@(x) openfig(x + ".fig", fgOpts{:}), stFigFN) + arrayfun(@(x) openfig(x + ".fig", ofgOpts{:}), stFigFN) else % Statistical tests [Results, Counts] = statTests(discStack, delayFlags, timeFlags); @@ -545,8 +550,15 @@ end psthFigs = gobjects( numel(psthFP), 1 ); auxID = pclID(ordSubs); auxStack = discStack(filterIdx,:,:); - PSTH = cell(Nccond,1); %trig = PSTH; + PSTH = cell(Nccond,1); trig = PSTH; + try + parpool('Processes', 2) + catch ME + delete(gcp('nocreate')) + parpool('Processes', 2) + end parfor cf = 1:Nccond + % for cf = 1:Nccond [PSTH{cf}, trig{cf}] = getPSTH(auxStack, timeLapse, ... ~delayFlags(:,cf), binSz, fs); psthFigs(cf) = plotClusterReactivity(PSTH{cf}(ordSubs,:), trig{cf},... @@ -558,8 +570,9 @@ set( psthFigs(cf), 'UserData', PSTH{cf} ) saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); end + else - psthFigs = arrayfun(@(f) openfig(f + ".fig", 'visible'), psthFP); + psthFigs = arrayfun(@(f) openfig(f + ".fig", ofgOpts{:} ), psthFP); PSTH = arrayfun(@(f) get( f, 'UserData' ), psthFigs, fnOpts{:} ); if all(cellfun(@(c)isempty(c),PSTH)) [PSTH, trig] = arrayfun(@(x) getPSTH(discStack(filterIdx,:,:), ... @@ -576,7 +589,7 @@ timeLapse, consCondNames); saveFigure(ppFig, ephysFile, 1, owFlag ); else - uiopen(ephysFile, true); + openfig( ephysFile, ofgOpts{:} ); end clearvars ppFig ephysPttrn ephysName ephysFile aux* %% Log PSTH @@ -617,10 +630,10 @@ end end else - logFigs = openfig(lpFP+".fig"); + logFigs = openfig(lpFP+".fig", ofgOpts{:} ); load(resFP, "MIstruct") if Nccond > 1 - logFigs(2) = openfig(lmiFP+".fig"); + logFigs(2) = openfig(lmiFP+".fig", ofgOpts{:} ); end end @@ -669,7 +682,7 @@ %% Plot proportional pies clrMap = lines(2); clrMap([3,4],:) = [0.65;0.8].*ones(2,3); % Responsive and non responsive clusters -respFig = figure("Color", "w"); +respFig = figure( "Color", "w", figOpts{:} ); pie([Ntn-Nrn, Nrn], [0, 1], {'Unresponsive', 'Responsive'}); pObj = findobj(respFig, "Type", "Patch"); arrayfun(@(x) set(x, "EdgeColor", "none"), pObj); @@ -680,7 +693,7 @@ saveFigure(respFig, propPieFileName, 1, owFlag ); % Potentiated, depressed and unmodulated clusters pie if Nccond == 2 - potFig = figure("Color", "w"); + potFig = figure("Color", "w", figOpts{:} ); pie([Nrn - Nrsn, Nrsp, Nrsn - Nrsp], [0, 1, 1], {'Non-modulated', ... 'Potentiated', 'Depressed'}); % set(potFig, axOpts{:}) pObj = findobj(potFig, "Type", "Patch"); @@ -691,7 +704,7 @@ C_key, Nrn - Nrsn, Nrsp, Nrsn - Nrsp)); saveFigure(potFig, modPropPieFigFileName, 1, owFlag ) % Modulation index histogram - MIFig = figure; histogram(MIspon, hsOpts{:}, "Spontaneous"); hold on; + MIFig = figure( figOpts{:} ); histogram(MIspon, hsOpts{:}, "Spontaneous"); hold on; histogram(MIevok, hsOpts{:}, "Evoked"); set(gca, axOpts{:}); title("Modulation index distribution"); xlabel("MI"); ylabel("Cluster proportion"); lgnd = legend("show"); @@ -760,7 +773,7 @@ clSub = clSub(rasOrd(rasIdx)); clSel = clSel(rasOrd(rasOrd ~= 0)); Nma = min(Na(rasCondSel)); - rasFig = figure; + rasFig = figure( figOpts{:} ); Nrcond = length(rasCond); ax = gobjects(Nrcond*Nrcl,1); timeFlags = all([tx(:) >= timeLapse(1), tx(:) <= timeLapse(2)],2); @@ -923,7 +936,7 @@ % [p_amp, h_amp] = ranksum(cat(1, zamp{1,:}), cat(1, zamp{2,:})); %% clrMap = lines(Nccond); - countFig = figure; ax(1) = subplot(10,1,1:8); + countFig = figure( figOpts{:} ); ax(1) = subplot(10,1,1:8); bar(ax(1), (0:4)', (hg./sum(hg,2))', 'EdgeColor', 'none'); hold on; poaDist = cellfun(@(bi) fitdist(bi,"Poisson"), BIscale); ylim(ax(1), [0,1]); set(ax(1), axOpts{:}); From ec494c9ebe7bd2b02f09349740c7d0f0feee2c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 12 Nov 2024 10:43:11 +0100 Subject: [PATCH 119/201] Saving structure --- Emilio/poolEphBeh_regression.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 8c558e8..b119dfc 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -123,7 +123,7 @@ if exist(behFP, "file") svOpts = {'-append'}; end -% save(behFP, "mice", svOpts{:}) +save(behFP, "mice", svOpts{:}) habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... m.Sessions), mice, fnOpts{:}); cat( 1, habFlag{:} ) From 96155afc034874313a923d4a6e6851a88f7a0f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 12 Nov 2024 16:48:59 +0100 Subject: [PATCH 120/201] Roller path error --- Emilio/poolEphBeh_regression.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index b119dfc..a743971 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -118,7 +118,7 @@ end mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; -behFP = fullfile( "Z:\Emilio\SuperiorColliculusExperiments\Roller", "MCiRNs_regression_sm.mat" ); +behFP = fullfile( roller_path, "MCiRNs_regression_sm.mat" ); svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From a7f6db9c295d1a86c5f5cd4d92dee2f41afc7b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 13 Nov 2024 11:41:28 +0100 Subject: [PATCH 121/201] No interest of seeing the pool --- Jesus/DE_Jittering.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 8a862a7..293f314 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -552,10 +552,10 @@ auxID = pclID(ordSubs); auxStack = discStack(filterIdx,:,:); PSTH = cell(Nccond,1); trig = PSTH; try - parpool('Processes', 2) + parpool('Processes', 2); catch ME delete(gcp('nocreate')) - parpool('Processes', 2) + parpool('Processes', 2); end parfor cf = 1:Nccond % for cf = 1:Nccond From 24307fae747950881bb28e044e9e703b1a5b97d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 19 Nov 2024 17:04:51 +0100 Subject: [PATCH 122/201] Create Reg_vs_RST.m --- Emilio/Reg_vs_RST.m | 126 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 Emilio/Reg_vs_RST.m diff --git a/Emilio/Reg_vs_RST.m b/Emilio/Reg_vs_RST.m new file mode 100644 index 0000000..5fcec0c --- /dev/null +++ b/Emilio/Reg_vs_RST.m @@ -0,0 +1,126 @@ +mID = 1; +Nm = numel( reg_mice ); +Ns = sum( arrayfun(@(m) numel( m.Sessions ), reg_mice ) ); +rst_reg_dt = zeros( Ns, 5 ); +rsq_dt = zeros( Ns, 10 ); +regMiceNames = [reg_mice.Name]'; +rstMiceNames = [rst_mice.Name]'; +cr = 1; +for cm = 1:numel(reg_mice) + sID = 1; + for cs = 1:numel(reg_mice(cm).Sessions) + dt = rst_mice(cm).Sessions(cs).DataTable; + rst_reg_dt(cr,:) = [cm, cs, dt.NUnits, dt.Proportion]; + dt = reg_mice(cm).Sessions(cs).DataTable; + rsq_dt(cr,:) = [cm, cs, dt.R_squared]; + cr = cr + 1; + end +end + +%% + +f = figure( "Color", "w" ); +createtiles = @(f,r,c) tiledlayout( f, r, c, 'TileSpacing', 'Compact', ... + 'Padding', 'tight'); +cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); +t = createtiles( f, 3, 1 ); + +ax = gobjects(3, 1); pl = ax; +clrMap = [0,0,0; 0.45*ones(1,3); 0,0,0]; +x = 0:0.05:0.8; +samples = [1e4, 1]; +ylbls = ["Recorded units", "Responsive 20 - 50 ms", "Responsive 50 - 200 ms"]; +for cp = 1:3 + ax(cp) = nexttile( t ); + pl(cp) = plot( ax(cp), rsq_dt(:,3), rst_reg_dt(:,2+cp), 'Marker', '.', ... + 'Color', clrMap(cp,:), 'MarkerSize', 16, 'LineStyle', 'none' ); + cleanAxis( ax(cp) ); + ylabel( ax(cp), ylbls(cp) ); + ft = fitlm( rsq_dt(:,3), rst_reg_dt(:, 2+cp ), 'poly1' ); + cCI = coefCI( ft ); sig = (ft.Coefficients{:,"Estimate"} - cCI(:,1))/2; + slope = makedist( "Normal", "mu", ft.Coefficients{"x1","Estimate"}, ... + "sigma", sig(2) ); + intercept = makedist( "Normal", "mu", ... + ft.Coefficients{"(Intercept)","Estimate"}, "sigma", sig(1) ); + y = random( slope, samples ) * x + random( intercept, samples ); + CI = quantile( y, [0.025, 0.975], 1 ); + hold( ax(cp), 'on' ); lobjs = line( x, CI', 'Color', 0.35*ones(1,3), ... + 'LineStyle', '--' ); + lobjs(1) = []; + lobjs = cat(1, lobjs, line( x, predict( ft, x' ), 'Color', 0.35*ones(1,3) )); + legend( lobjs, {'CI 95%', sprintf('Fit %.3f r^2', ... + ft.Rsquared.Ordinary)}, Box="off", Color='none', Location='best' ); +end +xlabel( ax(cp), "R^2_{SWM}" ) +set( ax, 'TickDir', 'out' ) +arrayfun(@(x) set( get( x, 'XAxis' ), 'Visible', 'off' ), ax(1:2) ) +%% +Nex = 3; +f = figure("Color", "w" ); +t = createtiles( f, Nex+2, 1 ); + +%clrMap = inferno( round( Nex*1.5) ); +ax = gobjects( Nex+1, 1 ); +[~, ord] = sort( rmse_trials, "ascend" ); +cpi = 1; +for cp = ord(1:round(end/Nex):end) + ax(cpi) = nexttile( t ); + set( ax(cpi), 'NextPlot', 'add' ); cleanAxis( ax(cpi) ); + line( ax(cpi), tr_tx, squeeze( y_trials(:,cp,1) ), 'Color', 0.15*ones(1,3), 'LineWidth', 0.5 ) + line( ax(cpi), tr_tx, squeeze( y_ptrials(:,cp,1) ), 'Color', 0.55*ones(1,3), 'LineWidth', 0.5 ) + yticklabels( ax(cpi), yticks(ax(cpi)) - 90) + set( get( ax(cpi), 'XAxis' ), 'Visible', 'off' ) + cpi = cpi + 1; +end +ax(cpi) = nexttile( t, [2, 1] ); +cleanAxis( ax(cpi) ) +line(ax(cpi), tr_tx, squeeze( mean( y_trials(:,:,1), 2 ) ), 'LineWidth', 2, 'Color', 0.15*ones(1,3) ) +line(ax(cpi), tr_tx, squeeze( mean( y_ptrials(:,:,1), 2 ) ), 'LineWidth', 2, 'Color', 0.55*ones(1,3) ) +yticklabels( ax(cpi), yticks(ax(cpi)) - 90); ylabel( ax(cpi), 'Angle [°]') +xticklabels( ax(cpi), xticks( ax(cpi) )*1e3 ); +xlabel(ax(cpi), 'Time [ms]') +legend( ax(cpi), flip({'Predicted', 'Observed'}), 'Box', 'off', 'Color', 'none', ... + 'Location', 'best' ); +set( ax, 'TickDir', 'out' ) +xline(ax(cpi), 0, 'k--') + +saveFigure( f, fullfile( "Z:\Emilio\SuperiorColliculusExperiments\" + ... + "Roller\Batch7_ephys\MC\GADi52\220808_C+F_2100\ephys_E1\Figures", ... + "Example reconstruction" ), true, false ) + +%% +f = figure("Color", "w"); +t = createtiles( f, 3, 1); +my_xor = @(x) xor( x(:,1), x(:,2) ); +lnOpts = {'LineStyle', 'none', 'Marker', '|', 'Color', 0.15*ones(1,3)}; +tlSelect = 9; +vWin = [-0.3,0.5]; +[~, ord2] = sort( cellfun(@(x) size(x, 1), spike_times ), "descend" ); +cni = 1; + +ax = gobjects( 2, 1 ); +ax(1) = nexttile( t, [2, 1] ); cleanAxis( ax(1) ); ylabel( ax(1), 'Units') +for cn = ord2(1:round(end/30):end)' + spkIdx = my_xor( spike_times{cn} > time_limits(tlSelect,:) ); + line( spike_times{cn}(spkIdx), cni+zeros(sum(spkIdx),1), lnOpts{:} ) + cni = cni + 1; +end +set( get( ax(1), 'XAxis' ), 'Visible', 'off' ) +bin_size = 0.02; +ax(2) = nexttile(t); +behIdx = my_xor( btx > time_limits(tlSelect,:) ); +line(ax(2), btx(behIdx), behSignals( behIdx, 1 ) ) +linkaxes( ax, 'x' ) +xline(ax(2), time_limits(tlSelect,1)+(bin_size/2):bin_size: ... + time_limits(tlSelect,2)-(bin_size/2), 'LineWidth', 0.1, 'Color', 0.5*ones(1,3) ) +xlim( ax(2), mean(time_limits(tlSelect,:)) + vWin) +xline( ax(2), mean( time_limits(tlSelect,:)), 'k--' ) +set( ax, 'TickDir', 'out' ) +xtv = mean( time_limits(tlSelect,:) ) + vWin; +xticks( ax(2), xtv(1):0.1:xtv(2) ); xlabel( ax(2), 'Time [ms]' ) +xticklabels( ax(2), round( ( xticks( ax(2) ) - xtv(1) + vWin(1) ) *1e3 ) ) +yticklabels( ax(2), yticks(ax(2)) - 90); ylabel( ax(2), 'Angle [°]') + +saveFigure( f, fullfile( "Z:\Emilio\SuperiorColliculusExperiments\" + ... + "Roller\Batch7_ephys\MC\GADi52\220808_C+F_2100\ephys_E1\Figures", ... + "Regression method" ), true, false ) \ No newline at end of file From 32172c2d5ab90e2b334d6579502bbe35d4619331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 19 Nov 2024 17:04:57 +0100 Subject: [PATCH 123/201] Create poolRespUnitProp.m --- Emilio/poolRespUnitProp.m | 151 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 Emilio/poolRespUnitProp.m diff --git a/Emilio/poolRespUnitProp.m b/Emilio/poolRespUnitProp.m new file mode 100644 index 0000000..39449d0 --- /dev/null +++ b/Emilio/poolRespUnitProp.m @@ -0,0 +1,151 @@ +%#ok<*AGROW,*SAGROW> +%% Auxiliary variables and functions +fnOpts = {'UniformOutput', false}; +expandName = @(x) fullfile(x.folder, x.name); +animalPattern = '[a-zA-Z]+\d{1,}'; +rsOpts = {animalPattern, 'SearchType', 'expression'}; +ctOpts = {'IgnoreCase', true}; +lsOpts = {'L\d+.\d+', 'match'}; +ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; +tblOpts = {'VariableNames', {'Conditions', 'MI'}}; +my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +getMI = @(x,d) diff(x, 1, d)./sum(x, d); +total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); +tocol = @(x) x(:); +my_xor = @(x) xor( x(:,1), x(:,2) ); +m = 1e-3; +exclude_names = {'GADi13', 'GADi15', 'GADi53'}; + +params = struct( 'relative_window', [-1,1]*800*m, 'delay_window', ... + [-1,1]*100*m, 'bin_size', 5*m, 'kfold', 20 ); + +pc = parcluster('local'); +if ~strcmp( computer, 'PCWIN64') + home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; + repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... + {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); + cellfun(@(x) addpath( genpath( x ) ), repo_paths ) + roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; +else + roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; +end +try + parpool( pc ); +catch + fprintf(1, 'Parallel pool already running ;-)\n') +end + +iRN_mice = dir( fullfile( roller_path, "Batch*", "MC", "GADi*" ) ); +animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); +exclude_flags = contains( animalFolders, exclude_names ); +%% Looping animals +oldMouse = ""; +mc = 0; mice = []; lp_mu = []; lPSTH = []; +sessType = 'single'; +for cad = tocol(animalFolders(~exclude_flags))' + [structPath, currMouse] = fileparts(cad); + [~, structName] = fileparts(structPath); + if string(oldMouse) ~= string(currMouse) + oldMouse = currMouse; + mice = [mice; struct('Name', currMouse, 'Sessions',[], ... + 'Structure', structName)]; + mc = mc + 1; + sc = 0; oldSess = ""; oldDepth = ""; + end + fprintf(1, 'Mouse %s', currMouse) + sessDirs = getSubFolds(cad); + % Just date sessions + onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... + 'match')), sessDirs, fnOpts{:}); + sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; + for csd = sessDirs(:)' + curDir = expandName(csd); + sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})?', 'tokens', 'once'); + if ~isempty( sessDateDepth ) + currSess = sessDateDepth{1}; + if isempty( sessDateDepth{2} ) + depthSess = ''; + else + depthSess = sessDateDepth{2}; + end + else + currSess = regexp(csd.name, '(\d{6})', 'tokens', 'once'); + depthSess = ''; + if isempty(currSess) + fprintf( 1, '\n' ) + fprintf( 1, "Unable to get session date and depth\n" ); + fprintf( 1, "Skipping: %s %s\n", currMouse, csd.name ) + continue + end + end + fprintf(1, ', Session %s\n', currSess ) + childFolders = getSubFolds(curDir); + sessOrgDirs = arrayfun(@(d) string(d.name), childFolders ); + sessOrgDirs( ~contains(sessOrgDirs, {'behaviour', 'ephys', ... + 'figures', 'opto'}, ctOpts{:}) ) = []; + if isempty(sessOrgDirs) + continue + end + data_path = curDir; + + mapFile = dir( fullfile( curDir, "ephys*", "Results", "Map *.mat" ) ); + rstFile = dir( fullfile( curDir, "ephys*", "*RW20.00-200.00*.mat" ) ); + rstFile( ~contains({rstFile.name}, 'PuffAll (unfiltered)') ) = []; + if numel( mapFile ) ~= 1 + fprintf(1, '%s\ndoesn''t have result map... skipping...\n', curDir ) + continue + end + if numel( rstFile ) ~= 1 + fprintf(1, '%s\ndoesn''t have relative spikes... skipping...\n', curDir ) + continue + end + % load( expandName(mapFile), 'keyCell', 'resMap' ) + load( expandName(rstFile), 'relativeSpkTmsStruct' ) + Ncl = size( relativeSpkTmsStruct(1).SpikeTimes, 1 ); + Na = arrayfun(@(x) size( x.SpikeTimes, 2 ), relativeSpkTmsStruct); + respWins = [20, 50; 50, 200]*1e-3; + sponWins = -flip( respWins, 2 ) - 0.1; + + countSpks = @(win) arrayfun(@(c) arrayfun(@(t) ... + sum( my_xor( tocol(relativeSpkTmsStruct(1).SpikeTimes{c,t}) > ... + win ) ), 1:Na(1) ), (1:Ncl)', fnOpts{:} ); + rCounts = cellfun(@(x) cat( 1, x{:}), arrayfun(@(x) ... + countSpks(respWins(x,:)), 1:2, fnOpts{:} ), fnOpts{:} ); + sCounts = cellfun(@(x) cat( 1, x{:}), arrayfun(@(x) ... + countSpks(sponWins(x,:)), 1:2, fnOpts{:} ), fnOpts{:} ); + testPairedMedians = @(x,y) arrayfun(@(u) signrank( ... + tocol( x(u,:) ), tocol( y(u,:) ) ), (1:Ncl)' ) < 0.05; + h = cellfun( @(x,y) testPairedMedians(x,y), sCounts, rCounts, ... + fnOpts{:} ); h = cat( 2, h{:} ); + + dataTable = table( Ncl, Na(1), sum(h), sum(h)/Ncl, ... + 'VariableNames', ["NUnits", "NTrials", ... + "Modulated_sens_motr", "Proportion"] ); + if ( string(oldSess) ~= string(currSess) ) || ... + ( string(oldDepth) ~= string(depthSess) ) + oldSess = currSess; + oldDepth = depthSess; + auxStruct = struct('Date', currSess, ... + 'DataTable', dataTable, 'Type', sessType, ... + 'Depth', depthSess); + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + sc = sc + 1; + end + clearvars rCounts sCounts h relativeSpkTmsStruct + end +end +mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; + +behFP = fullfile( roller_path, "MCiRNs_respUnitProp.mat" ); +svOpts = {'-mat'}; +if exist(behFP, "file") + svOpts = {'-append'}; +end +save(behFP, "mice", svOpts{:}) +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +cat( 1, habFlag{:} ) From 603f6c9cc7bed290d565c77cae59f88099193239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 19 Nov 2024 17:05:08 +0100 Subject: [PATCH 124/201] Included RMSE from control and laser --- Emilio/poolEphBeh_regression.m | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index a743971..9fd0934 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -8,9 +8,10 @@ lsOpts = {'L\d+.\d+', 'match'}; ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; tblOpts = {'VariableNames', {'Conditions', 'MI'}}; -my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); -getMI = @(x,d) diff(x, 1, d)./sum(x, d); -total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); +% my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +% getMI = @(x,d) diff(x, 1, d)./sum(x, d); +% total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); +getRMSE = @( r, x, d ) sqrt( mean( ( r - x ).^2, d, "omitmissing" ) ); tocol = @(x) x(:); m = 1e-3; exclude_names = {'GADi13', 'GADi15', 'GADi53'}; @@ -28,7 +29,7 @@ else roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; end -parpool( pc ) +parpool( pc ); iRN_mice = dir( fullfile( roller_path, "Batch*", "MC", "GADi*" ) ); animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); @@ -96,9 +97,14 @@ SSE = sum( (DX{1} - y_pred).^2 ); SST = sum( (DX{1} - mean( DX{1}, 1 ) ).^2 ); r_sq = 1 - ( SSE./ SST ); - - dataTable = table( r_sq, {r_sq_trials}, ... - 'VariableNames', {'R_squared', 'R_squared_trials'}); + + y_lpred = DX{3} * mdl_mu; + + rmse_laser = getRMSE( DX{4}, y_lpred, 1 ); + + dataTable = table( r_sq, {r_sq_trials}, {params.fit_error}, ... + rmse_laser, 'VariableNames', {'R_squared', 'R_squared_trials', ... + 'RMSE_c', 'RMSE_l'} ); if ( string(oldSess) ~= string(currSess) ) || ... ( string(oldDepth) ~= string(depthSess) ) oldSess = currSess; From 5185542c7e005522da2b33870633c430ac638186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 19 Nov 2024 18:05:57 +0100 Subject: [PATCH 125/201] Verbose messages --- Emilio/poolEphBeh_regression.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 9fd0934..4a69cd8 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -48,6 +48,7 @@ mc = mc + 1; sc = 0; oldSess = ""; oldDepth = ""; end + fprintf(1, 'Mouse %s ', currMouse) sessDirs = getSubFolds(cad); % Just date sessions onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... @@ -80,7 +81,7 @@ continue end data_path = curDir; - + fprintf(1, ', Session %s\n', currSess ) [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 continue @@ -97,11 +98,11 @@ SSE = sum( (DX{1} - y_pred).^2 ); SST = sum( (DX{1} - mean( DX{1}, 1 ) ).^2 ); r_sq = 1 - ( SSE./ SST ); - + y_lpred = DX{3} * mdl_mu; - + rmse_laser = getRMSE( DX{4}, y_lpred, 1 ); - + dataTable = table( r_sq, {r_sq_trials}, {params.fit_error}, ... rmse_laser, 'VariableNames', {'R_squared', 'R_squared_trials', ... 'RMSE_c', 'RMSE_l'} ); From bb7f6d0cad4673bbba54fb9c12c0e0d207ed4a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 19 Nov 2024 20:20:34 +0100 Subject: [PATCH 126/201] Shadow in mean plot --- Emilio/Reg_vs_RST.m | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/Emilio/Reg_vs_RST.m b/Emilio/Reg_vs_RST.m index 5fcec0c..f327b0e 100644 --- a/Emilio/Reg_vs_RST.m +++ b/Emilio/Reg_vs_RST.m @@ -55,38 +55,49 @@ set( ax, 'TickDir', 'out' ) arrayfun(@(x) set( get( x, 'XAxis' ), 'Visible', 'off' ), ax(1:2) ) %% +Bsel = 1; Nex = 3; f = figure("Color", "w" ); t = createtiles( f, Nex+2, 1 ); -%clrMap = inferno( round( Nex*1.5) ); +getSEM = @(x) [mean( x, 2 ), std( x, 1, 2 )./sqrt( size( x, 2 ) )]; +mat2ptch = @(x) [x(1:end,:)*[1;1]; x(end:-1:1,:)*[1;-1]]; +phOpts = {'EdgeColor', 'none', 'FaceAlpha', 0.25, 'FaceColor'}; + +clrMap = brighten( blues(2), -0.8 ); ax = gobjects( Nex+1, 1 ); -[~, ord] = sort( rmse_trials, "ascend" ); +[~, ord] = sort( rmse_ltrials, "ascend" ); cpi = 1; for cp = ord(1:round(end/Nex):end) ax(cpi) = nexttile( t ); set( ax(cpi), 'NextPlot', 'add' ); cleanAxis( ax(cpi) ); - line( ax(cpi), tr_tx, squeeze( y_trials(:,cp,1) ), 'Color', 0.15*ones(1,3), 'LineWidth', 0.5 ) - line( ax(cpi), tr_tx, squeeze( y_ptrials(:,cp,1) ), 'Color', 0.55*ones(1,3), 'LineWidth', 0.5 ) + line( ax(cpi), tr_tx, squeeze( y_ltrials(:,cp,Bsel) ), 'Color', 0.15*ones(1,3), 'LineWidth', 0.5 ) + line( ax(cpi), tr_tx, squeeze( y_lptrials(:,cp,Bsel) ), 'Color', 0.55*ones(1,3), 'LineWidth', 0.5 ) yticklabels( ax(cpi), yticks(ax(cpi)) - 90) + ax(cpi).YTickLabelRotation = 90; set( get( ax(cpi), 'XAxis' ), 'Visible', 'off' ) cpi = cpi + 1; end ax(cpi) = nexttile( t, [2, 1] ); cleanAxis( ax(cpi) ) -line(ax(cpi), tr_tx, squeeze( mean( y_trials(:,:,1), 2 ) ), 'LineWidth', 2, 'Color', 0.15*ones(1,3) ) -line(ax(cpi), tr_tx, squeeze( mean( y_ptrials(:,:,1), 2 ) ), 'LineWidth', 2, 'Color', 0.55*ones(1,3) ) +sem_lshadow = getSEM( y_ltrials ); +sem_lpshadow = getSEM( y_lptrials ); +line(ax(cpi), tr_tx, squeeze( mean( y_ltrials(:,:,Bsel), 2 ) ), 'LineWidth', 2, 'Color', clrMap(1,:) ) +line(ax(cpi), tr_tx, squeeze( mean( y_lptrials(:,:,Bsel), 2 ) ), 'LineWidth', 2, 'Color', clrMap(2,:) ) +patch( ax(cpi), [tr_tx(:); flip( tr_tx(:) )], mat2ptch( sem_lshadow(:,:,Bsel) ), 1, phOpts{:}, clrMap(1,:) ) +patch( ax(cpi), [tr_tx(:); flip( tr_tx(:) )], mat2ptch( sem_lpshadow(:,:,Bsel) ), 1, phOpts{:}, clrMap(2,:) ) yticklabels( ax(cpi), yticks(ax(cpi)) - 90); ylabel( ax(cpi), 'Angle [°]') xticklabels( ax(cpi), xticks( ax(cpi) )*1e3 ); xlabel(ax(cpi), 'Time [ms]') legend( ax(cpi), flip({'Predicted', 'Observed'}), 'Box', 'off', 'Color', 'none', ... - 'Location', 'best' ); + 'Location', 'best', 'AutoUpdate', 'off' ); set( ax, 'TickDir', 'out' ) xline(ax(cpi), 0, 'k--') +xline( ax(cpi), [-0.1, 0.2], 'b') saveFigure( f, fullfile( "Z:\Emilio\SuperiorColliculusExperiments\" + ... "Roller\Batch7_ephys\MC\GADi52\220808_C+F_2100\ephys_E1\Figures", ... - "Example reconstruction" ), true, false ) + "Example reconstruction laser" ), true, false ) %% f = figure("Color", "w"); From 0685ef6b43e2f49f0207fd87e4580d4de1d094b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 21 Nov 2024 11:43:11 +0100 Subject: [PATCH 127/201] Validation for pool and empty matrix --- Emilio/poolEphBeh_regression.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 4a69cd8..5cc6406 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -29,7 +29,10 @@ else roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; end -parpool( pc ); +try + parpool( pc ); +catch +end iRN_mice = dir( fullfile( roller_path, "Batch*", "MC", "GADi*" ) ); animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); @@ -83,7 +86,8 @@ data_path = curDir; fprintf(1, ', Session %s\n', currSess ) [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); - if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 + if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 || ... + any( cellfun(@isempty, DX) ) continue end mdl_mu = squeeze( mean( mdl, 2 ) ); From c9a34f1a4d2924ca17f72957a3b98ce0617291e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 21 Nov 2024 14:22:36 +0100 Subject: [PATCH 128/201] Trying to run the regression on pool --- Emilio/poolEphBeh_regression.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 5cc6406..36277c8 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -85,7 +85,12 @@ end data_path = curDir; fprintf(1, ', Session %s\n', currSess ) - [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); + try + [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); + catch ME + display(ME.message) + continue + end if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 || ... any( cellfun(@isempty, DX) ) continue From e601dcd6c51b52e343cad8b1efb96c9c977f8a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 21 Nov 2024 18:36:00 +0100 Subject: [PATCH 129/201] Create AnBeh_Bypass.m --- Emilio/AnBeh_Bypass.m | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Emilio/AnBeh_Bypass.m diff --git a/Emilio/AnBeh_Bypass.m b/Emilio/AnBeh_Bypass.m new file mode 100644 index 0000000..36cdf5c --- /dev/null +++ b/Emilio/AnBeh_Bypass.m @@ -0,0 +1,54 @@ +function [outputArg1,outputArg2] = AnBeh_Bypass(inputArg1,inputArg2) +%UNTITLED Summary of this function goes here +% Detailed explanation goes here + +rel_win = params.relative_window; % [-1, 1]*0.8; +del_win = params.delay_window; % [-100, 100]*m; +bin_size = params.bin_size; % 10*m; + +% Spontaneous flags +bsWin = -flip(brWin); +bsFlag = behTx < bsWin; bsFlag = xor(bsFlag(:,1), bsFlag(:,2)); + +brWin_aux = brWin; +if brWin(1) < 0.12 + brWin_aux = brWin + 0.1; +end + +brWin = [brWin_aux; repmat( brWin, Nbs-1, 1 )]; + +brFlag = arrayfun(@(x) behTx < brWin(x,:), 1:Nbs, fnOpts{:} ); +brFlag = cellfun(@(x) xor(x(:,1), x(:,2) ), brFlag, fnOpts{:} ); +brFlag = cat( 2, brFlag{:} ); + +%% Organising figures in subfolders +vwKey = sprintf("V%.2f - %.2f s", bvWin); +rwKey = sprintf("R%.2f - %.2f ms", brWin(2,:)*k); +subFig = "Beh %s %s"; +% Configuration subfolder +subfigDir = fullfile(figureDir, sprintf(subFig, vwKey, rwKey)); +metaNameFlag = false; +if exist(subfigDir, "dir") + figureDir = subfigDir; +else + if ~mkdir(subfigDir) + % Print metadata on figure name + metaNameFlag = true; + if verbose + fprintf(1, "Error while creating subfolder!\n") + fprintf(1, "Placing the figures in 'Figure' directory.\n") + end + else + figureDir = subfigDir; + end +end + +trial_tx = (rel_win(1) + bin_size/2):bin_size:(rel_win(2) - bin_size/2); + + +% Getting maximum speed per trial +mvpt = arrayfun(@(c) arrayfun( @(b) ... + getMaxAbsPerTrial( behStack{b}(:, xtf(:, b, c)), brWin(b,:), behTx ), ... + 1:Nbs, fnOpts{:} ), 1:Nccond, fnOpts{:} ); +mvpt = cat(1, mvpt{:}); +end \ No newline at end of file From caca1c523e20be2c12bb6c1ad03cd4ce72b876ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 22 Nov 2024 19:12:26 +0100 Subject: [PATCH 130/201] Added a spontaneous window for comparison --- Emilio/AKK/getMaxAbsPerTrial.m | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Emilio/AKK/getMaxAbsPerTrial.m b/Emilio/AKK/getMaxAbsPerTrial.m index 0ba1c99..732520a 100644 --- a/Emilio/AKK/getMaxAbsPerTrial.m +++ b/Emilio/AKK/getMaxAbsPerTrial.m @@ -1,9 +1,10 @@ -function [mavpt, mxT] = getMaxAbsPerTrial(inStack, responseWindow, timeAxis) +function [mavpt, mxT] = getMaxAbsPerTrial(inStack, responseWindow, spontWindow, timeAxis) %GETMAXABSPERTRIAL gets as the name suggests, the maximum absolute %amplitude per trial in the given input stack % Detailed explanation goes here, later. %% +my_xor = @(x) xor( x(:,1), x(:,2) ); % Size of the stack: Number of signals (e.g. nose, left whisker), number of % time samples, and number of triggers (trials) [Nts, Ntg] = size(inStack); @@ -18,13 +19,13 @@ fprintf(1, "Please, verify they are the same size!\n"); return end -% Response period for all trials -responseFlags = timeAxis >= responseWindow; -responseFlags = xor(responseFlags(:,1), responseFlags(:,2)); +% Response and spontaneous periods for all trials +responseFlags = my_xor( timeAxis(:) >= responseWindow ); +spontaneousFlags = my_xor( timeAxis(:) >= spontWindow ); % mavpt = max(abs(inStack(responseFlags, :)-median(inStack,1))); -[mavpt, ps] = max(abs(inStack(responseFlags,:) - ... - median(inStack(timeAxis<0,:),1))); +[mavpt, ps] = max( abs( inStack(responseFlags,:) - ... + median( inStack(spontaneousFlags,:), 1 ) ) ); % mavpt = arrayfun(@(mp, tr) ... % inStack(find(responseFlags,1,'first')+mp-1, tr), ps(:), (1:Ntg)'); mxT = timeAxis(ps+find(responseFlags,1,"first")-1); From cba498f1f6befd445acf996442023b84d7f324c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 22 Nov 2024 19:12:47 +0100 Subject: [PATCH 131/201] Might be useful again --- Emilio/popPolygon.m | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Emilio/popPolygon.m b/Emilio/popPolygon.m index c0bf6fd..30a1443 100644 --- a/Emilio/popPolygon.m +++ b/Emilio/popPolygon.m @@ -7,7 +7,11 @@ expMice = summMice{4}(2); aux = expMice.PolygonUnfoldAmplIndx([1,8],:,:,:); %% - +createtiles = @(f,r,c) tiledlayout( f, r, c, ... + 'TileSpacing', 'Compact', 'Padding', 'tight'); +cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); +vaxOpts = cellstr( ["HorizontalAlignment", "center", ... + "VerticalAlignment", "baseline", "Rotation"] ); med_AI_pbp = squeeze( median( aux, 2, "omitmissing" ) ); med_AI_all = median( med_AI_pbp, 3, "omitmissing" ); clrMap = [0.15*ones(1,3); 0, 0.51, 1]; @@ -23,8 +27,8 @@ iqr_coords = iqr_AI .* transp( z_axis ); poly_coords = med_AI_all .* transp( z_axis ); -figure('Color', 'w'); hold on; -line( [-real(z_axis(1:4)), real(z_axis(1:4))]', ... +f = figure('Color', 'w'); t = createtiles( f, 1, 1 ); ax = nexttile(t); +line(ax, [-real(z_axis(1:4)), real(z_axis(1:4))]', ... [-imag(z_axis(1:4)), imag(z_axis(1:4))]', 'LineWidth', 0.1, ... 'Color', 0.45*ones(1,3)); arrayfun(@(x) rectangle('Position', [repmat(-x,1,2),repmat(x*2,1,2)], ... @@ -44,7 +48,7 @@ arrayfun(@(x,z) line( squeeze( real( iqr_coords(x,:,:) * z ) )', ... squeeze( imag( iqr_coords(x,:,:) * z ) )', 'LineWidth', 2, ... 'Color', clrMap(x,:) ), 1:2, [z_rot, z_rot'] ) -text( 0.25:0.25:1, zeros(1,4), string( ( 1:4 )'/4 ), ... +text(ax, 0.25:0.25:1, zeros(1,4), string( ( 1:4 )'/4 ), ... "HorizontalAlignment", "left", "VerticalAlignment", "cap" ) title('Population Polygons for MC\rightarrowiRNs' ) legend( findobj( gca, 'Type', 'Patch' ), {'Laser OFF', 'Laser ON'}, ... @@ -58,6 +62,5 @@ (180*angle( transp(z_axis) )/pi) - 90 ); arrayfun(@(v,b,y) text( real( z_axis(v) ), ... - imag( z_axis(v) ), b, "HorizontalAlignment", "center", "Rotation", y, ... - "VerticalAlignment", "baseline" ), 1:8, bodypart_names, ... + imag( z_axis(v) ), b, vaxOpts{:}, y ), 1:8, bodypart_names, ... (180*angle( transp(z_axis) )/pi) - 90 ) \ No newline at end of file From 73a65b7dd4d30de165cc181fa17f1bf6dac96184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 22 Nov 2024 19:13:02 +0100 Subject: [PATCH 132/201] Getting ready for loop --- Emilio/AnBeh_Bypass.m | 115 +++++++++++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 17 deletions(-) diff --git a/Emilio/AnBeh_Bypass.m b/Emilio/AnBeh_Bypass.m index 36cdf5c..920dd7e 100644 --- a/Emilio/AnBeh_Bypass.m +++ b/Emilio/AnBeh_Bypass.m @@ -1,29 +1,68 @@ -function [outputArg1,outputArg2] = AnBeh_Bypass(inputArg1,inputArg2) +function [outputArg1,outputArg2] = AnBeh_Bypass(data_path, resWin) %UNTITLED Summary of this function goes here % Detailed explanation goes here +%% Input validation + +checkDir = @(x) (ischar(x) || isstring(x)) && exist(x, 'dir'); +checkRW = @(x) isnumeric(x) & numel(x) == 2 & (x(2) > x(1)); + +p = inputParser; + +addRequired(p, 'data_path', checkDir) +addRequired(p, 'resWin', checkRW) + +parse(p, data_path, resWin); + +data_path = p.Results.data_path; +brWin = p.Results.resWin; +%% Auxiliary variables and functions +fnOpts = {'UniformOutput', false}; +createtiles = @(f,r,c) tiledlayout( f, r, c, ... + 'TileSpacing', 'Compact', 'Padding', 'tight'); +lgOpts = {'Box', 'off', 'Color', 'none', 'Location', 'best'}; +cleanAxis = @(x) set( x, lgOpts{1:4} ); +vaxOpts = cellstr( ["HorizontalAlignment", "center", ... + "VerticalAlignment", "baseline", "Rotation"] ); +%TODO: Get bodypart names from somewhere else! +bodypart_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... +"Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... +"Symmetry", "Nose", "Roller speed"]; +expandName = @(x) fullfile( x.folder, x.name ); +m = 1e-3; k = 1e3; +%% Load regression file +regFile = dir( fullfile( data_path, "Regression CW*.mat" ) ); +if ~isempty( regFile ) && numel( regFile ) == 1 + load( expandName( regFile ), 'DX', 'mdlAll_ind', 'params') +else + %TODO: Being able to select a regression for specific parameters + fprintf(1, 'Regression either didn''t work or have different files\n') + return +end +% Colormap: grey for original and PCB-green for reconstructed +clrMap = flip([0.15*ones(1,3); 0, 51/255, 0], 1); +% Getting parameter values rel_win = params.relative_window; % [-1, 1]*0.8; -del_win = params.delay_window; % [-100, 100]*m; bin_size = params.bin_size; % 10*m; +Nb = params.Ns; +% Computing time axis for trials +trial_tx = (rel_win(1) + bin_size/2):bin_size:(rel_win(2) - bin_size/2); -% Spontaneous flags +% Spontaneous window bsWin = -flip(brWin); -bsFlag = behTx < bsWin; bsFlag = xor(bsFlag(:,1), bsFlag(:,2)); brWin_aux = brWin; if brWin(1) < 0.12 brWin_aux = brWin + 0.1; end +brWin = [brWin_aux; repmat( brWin, Nb-1, 1 )]; -brWin = [brWin_aux; repmat( brWin, Nbs-1, 1 )]; - -brFlag = arrayfun(@(x) behTx < brWin(x,:), 1:Nbs, fnOpts{:} ); -brFlag = cellfun(@(x) xor(x(:,1), x(:,2) ), brFlag, fnOpts{:} ); -brFlag = cat( 2, brFlag{:} ); %% Organising figures in subfolders -vwKey = sprintf("V%.2f - %.2f s", bvWin); -rwKey = sprintf("R%.2f - %.2f ms", brWin(2,:)*k); +vwKey = sprintf("V%.2f - %.2f s", rel_win); +dwKey = sprintf("D%.2f - %.2f ms", del_win*k); +rwKey = sprintf("R%.2f - %.2f ms", brWin(end,:)*k); +bsKey = sprintf("B%.2f ms", bin_size*k); subFig = "Beh %s %s"; % Configuration subfolder subfigDir = fullfile(figureDir, sprintf(subFig, vwKey, rwKey)); @@ -42,13 +81,55 @@ figureDir = subfigDir; end end +vec2tr = @(x) reshape( x, params.Nb, [], params.Ns ); + +% Reconstructing behaviour (Laser OFF only) +mdl_mu = squeeze( mean( mdlAll_ind, 2 ) ); +rb = cellfun(@(x) x * mdl_mu, DX([2,3]), fnOpts{:} ); +% Reorganising to have trials +rbStack = cellfun(vec2tr, rb, fnOpts{:} ); +obStack = cellfun(vec2tr, DX([1,4]), fnOpts{:} ); +[Nts, Nr, Nb] = size( rbStack{1} ); +stk = cat( 1, rbStack(1), obStack(1) ); +mvpt = zeros( Nb, Nr, 2 ); +up_pc = 1.15; +for cs = 1:2 + % Getting maximum speed per trial + mvpt_aux = arrayfun(@(b) getMaxAbsPerTrial( squeeze( stk{cs}(:,:,b) ), ... + brWin(b,:), bsWin, trial_tx ), 1:Nb, fnOpts{:} ); + mvpt(:,:,cs) = cat( 1, mvpt_aux{:} ); +end +% Normalising each +mvps = max( mvpt, [], 2 ) * up_pc; +ai = squeeze( mean( mvpt ./ mvps, 2 ) ); + +radAxis = (0:Nb-1)*(2*pi/Nb); +z_axis = exp(1i*radAxis(:)); + +poly_coords = ai .* z_axis; + +f = figure('Color', 'w'); t = createtiles( f, 1, 1 ); ax = nexttile(t); +% Drawing polar axis +line(ax, [-real(z_axis(1:4)), real(z_axis(1:4))]', ... + [-imag(z_axis(1:4)), imag(z_axis(1:4))]', 'LineWidth', 0.1, ... + 'Color', 0.45*ones(1,3)); +arrayfun(@(x) rectangle(ax, 'Position', [repmat(-x,1,2), repmat(x*2,1,2)], ... + 'Curvature', [1,1], 'EdgeColor', 0.45*ones( 1, 3 ) ), 1:-0.25:0.25 ); +text( ax, 0.25:0.25:1, zeros(1,4), string( ( 1:4 )'/4 ), ... + "HorizontalAlignment", "left", "VerticalAlignment", "cap" ) + +pchObj = arrayfun(@(c) patch( ax, real( poly_coords(:,c) )', ... + imag( poly_coords(:,c) )', clrMap(c,:), 'EdgeColor', 'none', ... + 'FaceAlpha', 0.5 ), 1:2 ); + +legend( ax, pchObj, {'Reconstructed', 'Observed'}, lgOpts{:} ); + +arrayfun(@(v,b,y) text( ax, real( z_axis(v) ), ... + imag( z_axis(v) ), b, vaxOpts{:}, y ), 1:Nb, bodypart_names, ... + (180*angle( transp( z_axis ) )/pi) - 90 ) + +axis(ax, 'off', 'equal'); cleanAxis( ax ); -trial_tx = (rel_win(1) + bin_size/2):bin_size:(rel_win(2) - bin_size/2); -% Getting maximum speed per trial -mvpt = arrayfun(@(c) arrayfun( @(b) ... - getMaxAbsPerTrial( behStack{b}(:, xtf(:, b, c)), brWin(b,:), behTx ), ... - 1:Nbs, fnOpts{:} ), 1:Nccond, fnOpts{:} ); -mvpt = cat(1, mvpt{:}); end \ No newline at end of file From 44ae2c64aed1b9dfd6bf815bfc10005c05dabd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Sat, 23 Nov 2024 19:05:40 +0100 Subject: [PATCH 133/201] Create poolEphBeh_reconstruction.m --- Emilio/poolEphBeh_reconstruction.m | 146 +++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 Emilio/poolEphBeh_reconstruction.m diff --git a/Emilio/poolEphBeh_reconstruction.m b/Emilio/poolEphBeh_reconstruction.m new file mode 100644 index 0000000..0e3a351 --- /dev/null +++ b/Emilio/poolEphBeh_reconstruction.m @@ -0,0 +1,146 @@ +%#ok<*AGROW,*SAGROW> +%% Auxiliary variables and functions +fnOpts = {'UniformOutput', false}; +expandName = @(x) fullfile(x.folder, x.name); +animalPattern = '[a-zA-Z]+\d{1,}'; +rsOpts = {animalPattern, 'SearchType', 'expression'}; +ctOpts = {'IgnoreCase', true}; +lsOpts = {'L\d+.\d+', 'match'}; +ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; +tblOpts = {'VariableNames', {'Conditions', 'MI'}}; +% my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +% getMI = @(x,d) diff(x, 1, d)./sum(x, d); +% total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); +getRMSE = @( r, x, d ) sqrt( mean( ( r - x ).^2, d, "omitmissing" ) ); +tocol = @(x) x(:); +m = 1e-3; +exclude_names = {'GADi13', 'GADi15', 'GADi53'}; + +params = struct( 'relative_window', [-1,1]*800*m, 'delay_window', ... + [-1,1]*100*m, 'bin_size', 5*m, 'kfold', 20 ); + +pc = parcluster('local'); +if ~strcmp( computer, 'PCWIN64') + home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; + repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... + {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); + cellfun(@(x) addpath( genpath( x ) ), repo_paths ) + roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; +else + roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; +end +try + parpool( pc ); +catch +end + +iRN_mice = dir( fullfile( roller_path, "Batch*", "MC", "GADi*" ) ); +animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); +exclude_flags = contains( animalFolders, exclude_names ); +%% Looping animals +oldMouse = ""; +mc = 0; mice = []; lp_mu = []; lPSTH = []; +sessType = 'single'; +for cad = tocol(animalFolders(~exclude_flags))' + [structPath, currMouse] = fileparts(cad); + [~, structName] = fileparts(structPath); + if string(oldMouse) ~= string(currMouse) + oldMouse = currMouse; + mice = [mice; struct('Name', currMouse, 'Sessions',[], ... + 'Structure', structName)]; + mc = mc + 1; + sc = 0; oldSess = ""; oldDepth = ""; + end + fprintf(1, 'Mouse %s ', currMouse) + sessDirs = getSubFolds(cad); + % Just date sessions + onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... + 'match')), sessDirs, fnOpts{:}); + sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; + for csd = sessDirs(:)' + curDir = expandName(csd); + sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})?', 'tokens', 'once'); + if ~isempty( sessDateDepth ) + currSess = sessDateDepth{1}; + if isempty( sessDateDepth{2} ) + depthSess = ''; + else + depthSess = sessDateDepth{2}; + end + else + currSess = regexp(csd.name, '(\d{6})', 'tokens', 'once'); + depthSess = ''; + if isempty(currSess) + fprintf( 1, "Unable to get session date and depth\n" ); + fprintf( 1, "Skipping: %s %s\n", currMouse, csd.name ) + continue + end + end + childFolders = getSubFolds(curDir); + sessOrgDirs = arrayfun(@(d) string(d.name), childFolders ); + sessOrgDirs( ~contains(sessOrgDirs, {'behaviour', 'ephys', ... + 'figures', 'opto'}, ctOpts{:}) ) = []; + if isempty(sessOrgDirs) + continue + end + data_path = curDir; + fprintf(1, ', Session %s\n', currSess ) + try + [results, f] = AnBeh_Bypass(data_path, [25, 350]*m); + catch ME + [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); + display(ME.message) + continue + end + if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 || ... + any( cellfun(@isempty, DX) ) + continue + end + mdl_mu = squeeze( mean( mdl, 2 ) ); + y_trials = reshape( DX{1}, params.Nb, params.Nr, params.Ns ); + y_pred = DX{2} * mdl_mu; + y_ptrials = reshape( y_pred, params.Nb, params.Nr, params.Ns ); + + SSEt = squeeze( sum( ( y_trials - y_ptrials ).^2, 1 ) ); + SSTt = squeeze( sum( ( y_trials - mean( y_trials, 1 ) ).^2, 1 ) ); + r_sq_trials = 1 - (SSEt./SSTt); + + SSE = sum( (DX{1} - y_pred).^2 ); + SST = sum( (DX{1} - mean( DX{1}, 1 ) ).^2 ); + r_sq = 1 - ( SSE./ SST ); + + y_lpred = DX{3} * mdl_mu; + + rmse_laser = getRMSE( DX{4}, y_lpred, 1 ); + + dataTable = table( r_sq, {r_sq_trials}, {params.fit_error}, ... + rmse_laser, 'VariableNames', {'R_squared', 'R_squared_trials', ... + 'RMSE_c', 'RMSE_l'} ); + if ( string(oldSess) ~= string(currSess) ) || ... + ( string(oldDepth) ~= string(depthSess) ) + oldSess = currSess; + oldDepth = depthSess; + auxStruct = struct('Date', currSess, ... + 'DataTable', dataTable, 'Type', sessType, ... + 'Depth', depthSess); + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + sc = sc + 1; + end + close all + end +end +mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; + +behFP = fullfile( roller_path, "MCiRNs_regression_sm.mat" ); +svOpts = {'-mat'}; +if exist(behFP, "file") + svOpts = {'-append'}; +end +save(behFP, "mice", svOpts{:}) +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +cat( 1, habFlag{:} ) From 3d8cecff3b462bc4c71520104bf1e5f8b034532f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Sat, 23 Nov 2024 19:05:42 +0100 Subject: [PATCH 134/201] Delete AnBeh_Bypass.m --- Emilio/AnBeh_Bypass.m | 135 ------------------------------------------ 1 file changed, 135 deletions(-) delete mode 100644 Emilio/AnBeh_Bypass.m diff --git a/Emilio/AnBeh_Bypass.m b/Emilio/AnBeh_Bypass.m deleted file mode 100644 index 920dd7e..0000000 --- a/Emilio/AnBeh_Bypass.m +++ /dev/null @@ -1,135 +0,0 @@ -function [outputArg1,outputArg2] = AnBeh_Bypass(data_path, resWin) -%UNTITLED Summary of this function goes here -% Detailed explanation goes here - -%% Input validation - -checkDir = @(x) (ischar(x) || isstring(x)) && exist(x, 'dir'); -checkRW = @(x) isnumeric(x) & numel(x) == 2 & (x(2) > x(1)); - -p = inputParser; - -addRequired(p, 'data_path', checkDir) -addRequired(p, 'resWin', checkRW) - -parse(p, data_path, resWin); - -data_path = p.Results.data_path; -brWin = p.Results.resWin; -%% Auxiliary variables and functions -fnOpts = {'UniformOutput', false}; -createtiles = @(f,r,c) tiledlayout( f, r, c, ... - 'TileSpacing', 'Compact', 'Padding', 'tight'); -lgOpts = {'Box', 'off', 'Color', 'none', 'Location', 'best'}; -cleanAxis = @(x) set( x, lgOpts{1:4} ); -vaxOpts = cellstr( ["HorizontalAlignment", "center", ... - "VerticalAlignment", "baseline", "Rotation"] ); -%TODO: Get bodypart names from somewhere else! -bodypart_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... -"Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... -"Symmetry", "Nose", "Roller speed"]; -expandName = @(x) fullfile( x.folder, x.name ); -m = 1e-3; k = 1e3; -%% Load regression file -regFile = dir( fullfile( data_path, "Regression CW*.mat" ) ); -if ~isempty( regFile ) && numel( regFile ) == 1 - load( expandName( regFile ), 'DX', 'mdlAll_ind', 'params') -else - %TODO: Being able to select a regression for specific parameters - fprintf(1, 'Regression either didn''t work or have different files\n') - return -end -% Colormap: grey for original and PCB-green for reconstructed -clrMap = flip([0.15*ones(1,3); 0, 51/255, 0], 1); -% Getting parameter values -rel_win = params.relative_window; % [-1, 1]*0.8; -bin_size = params.bin_size; % 10*m; -Nb = params.Ns; -% Computing time axis for trials -trial_tx = (rel_win(1) + bin_size/2):bin_size:(rel_win(2) - bin_size/2); - -% Spontaneous window -bsWin = -flip(brWin); - -brWin_aux = brWin; -if brWin(1) < 0.12 - brWin_aux = brWin + 0.1; -end -brWin = [brWin_aux; repmat( brWin, Nb-1, 1 )]; - - -%% Organising figures in subfolders -vwKey = sprintf("V%.2f - %.2f s", rel_win); -dwKey = sprintf("D%.2f - %.2f ms", del_win*k); -rwKey = sprintf("R%.2f - %.2f ms", brWin(end,:)*k); -bsKey = sprintf("B%.2f ms", bin_size*k); -subFig = "Beh %s %s"; -% Configuration subfolder -subfigDir = fullfile(figureDir, sprintf(subFig, vwKey, rwKey)); -metaNameFlag = false; -if exist(subfigDir, "dir") - figureDir = subfigDir; -else - if ~mkdir(subfigDir) - % Print metadata on figure name - metaNameFlag = true; - if verbose - fprintf(1, "Error while creating subfolder!\n") - fprintf(1, "Placing the figures in 'Figure' directory.\n") - end - else - figureDir = subfigDir; - end -end -vec2tr = @(x) reshape( x, params.Nb, [], params.Ns ); - -% Reconstructing behaviour (Laser OFF only) -mdl_mu = squeeze( mean( mdlAll_ind, 2 ) ); -rb = cellfun(@(x) x * mdl_mu, DX([2,3]), fnOpts{:} ); -% Reorganising to have trials -rbStack = cellfun(vec2tr, rb, fnOpts{:} ); -obStack = cellfun(vec2tr, DX([1,4]), fnOpts{:} ); -[Nts, Nr, Nb] = size( rbStack{1} ); -stk = cat( 1, rbStack(1), obStack(1) ); -mvpt = zeros( Nb, Nr, 2 ); -up_pc = 1.15; -for cs = 1:2 - % Getting maximum speed per trial - mvpt_aux = arrayfun(@(b) getMaxAbsPerTrial( squeeze( stk{cs}(:,:,b) ), ... - brWin(b,:), bsWin, trial_tx ), 1:Nb, fnOpts{:} ); - mvpt(:,:,cs) = cat( 1, mvpt_aux{:} ); -end -% Normalising each -mvps = max( mvpt, [], 2 ) * up_pc; -ai = squeeze( mean( mvpt ./ mvps, 2 ) ); - -radAxis = (0:Nb-1)*(2*pi/Nb); -z_axis = exp(1i*radAxis(:)); - -poly_coords = ai .* z_axis; - -f = figure('Color', 'w'); t = createtiles( f, 1, 1 ); ax = nexttile(t); -% Drawing polar axis -line(ax, [-real(z_axis(1:4)), real(z_axis(1:4))]', ... - [-imag(z_axis(1:4)), imag(z_axis(1:4))]', 'LineWidth', 0.1, ... - 'Color', 0.45*ones(1,3)); -arrayfun(@(x) rectangle(ax, 'Position', [repmat(-x,1,2), repmat(x*2,1,2)], ... - 'Curvature', [1,1], 'EdgeColor', 0.45*ones( 1, 3 ) ), 1:-0.25:0.25 ); -text( ax, 0.25:0.25:1, zeros(1,4), string( ( 1:4 )'/4 ), ... - "HorizontalAlignment", "left", "VerticalAlignment", "cap" ) - -pchObj = arrayfun(@(c) patch( ax, real( poly_coords(:,c) )', ... - imag( poly_coords(:,c) )', clrMap(c,:), 'EdgeColor', 'none', ... - 'FaceAlpha', 0.5 ), 1:2 ); - -legend( ax, pchObj, {'Reconstructed', 'Observed'}, lgOpts{:} ); - -arrayfun(@(v,b,y) text( ax, real( z_axis(v) ), ... - imag( z_axis(v) ), b, vaxOpts{:}, y ), 1:Nb, bodypart_names, ... - (180*angle( transp( z_axis ) )/pi) - 90 ) - -axis(ax, 'off', 'equal'); cleanAxis( ax ); - - - -end \ No newline at end of file From 466d4a477c3e42cd18b2bfb212852feef803418d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 26 Nov 2024 11:09:57 +0100 Subject: [PATCH 135/201] Set up the reconstruction section --- Emilio/poolEphBeh_reconstruction.m | 69 ++++++++++++++++-------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/Emilio/poolEphBeh_reconstruction.m b/Emilio/poolEphBeh_reconstruction.m index 0e3a351..41a30d5 100644 --- a/Emilio/poolEphBeh_reconstruction.m +++ b/Emilio/poolEphBeh_reconstruction.m @@ -29,10 +29,9 @@ else roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; end -try - parpool( pc ); -catch -end + +[~, ofgOpts] = checkSystem4Figures(); +ovwFlag = true; iRN_mice = dir( fullfile( roller_path, "Batch*", "MC", "GADi*" ) ); animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); @@ -85,37 +84,40 @@ end data_path = curDir; fprintf(1, ', Session %s\n', currSess ) - try - [results, f] = AnBeh_Bypass(data_path, [25, 350]*m); - catch ME - [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); - display(ME.message) - continue + fig_path = dir( fullfile( data_path, 'ephys*', 'Fig*') ); + if isempty( fig_path ) + fig_path = data_path; + else + fig_path = expandName( fig_path ); end - if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 || ... - any( cellfun(@isempty, DX) ) - continue + aiFN = fullfile( fig_path, 'Amplitude index model'); + if ~exist( [aiFN, '.fig'], 'file' ) || ovwFlag + try + [results, f] = AnBeh_Bypass(data_path, [25, 350]*m); + catch ME + fprintf(1, 'Regression ongoing...\n') + DX = cell(4,1); + try + parpool( pc ); + catch + end + % [~, ~, DX] = regressEphysVSBehaviour( data_path, params ); + if ~all( cellfun(@isempty, DX ) ) + [results, f] = AnBeh_Bypass(data_path, [25, 350]*m ); + else + display(ME.message) + continue + end + end + saveFigure( f, [aiFN, '.fig'], true, ovwFlag ) + else + f = openfig( [aiFN, '.fig'], ofgOpts{:} ); + results = get( f, 'UserData' ); end - mdl_mu = squeeze( mean( mdl, 2 ) ); - y_trials = reshape( DX{1}, params.Nb, params.Nr, params.Ns ); - y_pred = DX{2} * mdl_mu; - y_ptrials = reshape( y_pred, params.Nb, params.Nr, params.Ns ); - - SSEt = squeeze( sum( ( y_trials - y_ptrials ).^2, 1 ) ); - SSTt = squeeze( sum( ( y_trials - mean( y_trials, 1 ) ).^2, 1 ) ); - r_sq_trials = 1 - (SSEt./SSTt); - - SSE = sum( (DX{1} - y_pred).^2 ); - SST = sum( (DX{1} - mean( DX{1}, 1 ) ).^2 ); - r_sq = 1 - ( SSE./ SST ); - - y_lpred = DX{3} * mdl_mu; - - rmse_laser = getRMSE( DX{4}, y_lpred, 1 ); - dataTable = table( r_sq, {r_sq_trials}, {params.fit_error}, ... - rmse_laser, 'VariableNames', {'R_squared', 'R_squared_trials', ... - 'RMSE_c', 'RMSE_l'} ); + dataTable = table( {results.AmplitudeIndex_pbp}, ... + results.AmplitudeIndex, results.AI_perCond(:)', ... + 'VariableNames', {'AI_pbp', 'AmplitudeIndex','Names'} ); if ( string(oldSess) ~= string(currSess) ) || ... ( string(oldDepth) ~= string(depthSess) ) oldSess = currSess; @@ -133,9 +135,10 @@ close all end end +close all mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; -behFP = fullfile( roller_path, "MCiRNs_regression_sm.mat" ); +behFP = fullfile( roller_path, "MCiRNs_reconstruction_sm.mat" ); svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From fb4bdf2caa277726607c71adcef90e81c44edb8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 26 Nov 2024 11:10:23 +0100 Subject: [PATCH 136/201] Functional prototype for population polygon --- Emilio/popPolygon.m | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/Emilio/popPolygon.m b/Emilio/popPolygon.m index 30a1443..69a3ef8 100644 --- a/Emilio/popPolygon.m +++ b/Emilio/popPolygon.m @@ -9,7 +9,7 @@ %% createtiles = @(f,r,c) tiledlayout( f, r, c, ... 'TileSpacing', 'Compact', 'Padding', 'tight'); -cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); + vaxOpts = cellstr( ["HorizontalAlignment", "center", ... "VerticalAlignment", "baseline", "Rotation"] ); med_AI_pbp = squeeze( median( aux, 2, "omitmissing" ) ); @@ -20,33 +20,23 @@ "Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... "Symmetry", "Nose", "Roller speed"]; -radAxis = (0:Nb-1)*(2*pi/Nb); -z_axis = exp(1i*radAxis(:)); - iqr_AI = quantile( med_AI_pbp, [1,3]/4, 3 ); -iqr_coords = iqr_AI .* transp( z_axis ); -poly_coords = med_AI_all .* transp( z_axis ); +iqr_coords = iqr_AI .* reshape(z_axis,1,[],1); + +[f, z_axis, poly_coords] = createPolarPlotPolygons( med_AI_pbp ); -f = figure('Color', 'w'); t = createtiles( f, 1, 1 ); ax = nexttile(t); -line(ax, [-real(z_axis(1:4)), real(z_axis(1:4))]', ... - [-imag(z_axis(1:4)), imag(z_axis(1:4))]', 'LineWidth', 0.1, ... - 'Color', 0.45*ones(1,3)); -arrayfun(@(x) rectangle('Position', [repmat(-x,1,2),repmat(x*2,1,2)], ... - 'Curvature', [1,1], 'EdgeColor', 0.45*ones( 1, 3 ) ), 1:-0.25:0.25 ); -arrayfun(@(c) patch( real( poly_coords(c,:) )', ... - imag( poly_coords(c,:) )', clrMap(c,:), 'EdgeColor', 'none', ... - 'FaceAlpha', 0.8 ), 1:2 ); +[pchObj, ax] = plotPolygons( poly_coords, f, 'clrMap', clrMap ); z_rot = exp( 1i*pi/32 ); % Dots by the polygon -arrayfun(@(c,z) line( real( poly_coords(c,:) * z)', ... - imag( poly_coords(c,:) * z )', 'LineStyle', 'none', ... +arrayfun(@(c,z) line( real( poly_coords(:,c) * z)', ... + imag( poly_coords(:,c) * z )', 'LineStyle', 'none', ... 'Marker', '.', 'Color', clrMap(c,:), 'MarkerSize', 20 ), ... 1:2, [z_rot, z_rot'] ) set( gca, 'Box', 'off', 'Color', 'none', "Visible", "off" ); % Lines for IQR -arrayfun(@(x,z) line( squeeze( real( iqr_coords(x,:,:) * z ) )', ... - squeeze( imag( iqr_coords(x,:,:) * z ) )', 'LineWidth', 2, ... +arrayfun(@(x,z) line( squeeze( real( iqr_coords(:,:,x) * z ) )', ... + squeeze( imag( iqr_coords(:,:,x) * z ) )', 'LineWidth', 2, ... 'Color', clrMap(x,:) ), 1:2, [z_rot, z_rot'] ) text(ax, 0.25:0.25:1, zeros(1,4), string( ( 1:4 )'/4 ), ... "HorizontalAlignment", "left", "VerticalAlignment", "cap" ) From 0a340d79f1f3378599d28a3e9372aeafef999b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 26 Nov 2024 11:10:30 +0100 Subject: [PATCH 137/201] Create GatherAI_reconstruction.m --- GatherAI_reconstruction.m | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 GatherAI_reconstruction.m diff --git a/GatherAI_reconstruction.m b/GatherAI_reconstruction.m new file mode 100644 index 0000000..b8abb14 --- /dev/null +++ b/GatherAI_reconstruction.m @@ -0,0 +1,15 @@ +Nm = numel(mice); +Ns = arrayfun(@(m) numel( m.Sessions ), mice ); +aiPop = zeros( sum( Ns ), 4 ); +aiPbp = zeros( sum( Ns ), 8, 2 ); +aiPbp2 = zeros( 8, 2, sum( Ns ) ); +cr = 1; +for cm = 1:Nm + for cs = 1:Ns(cm) + dt = mice(cm).Sessions(cs).DataTable; + aiPop(cr,:) = [cm, cs, dt.AmplitudeIndex]; + aiPbp(cr,:,:) = reshape( dt.AI_pbp{:}, 1, [], 2 ); + aiPbp2(:,:,cr) = dt.AI_pbp{:}; + cr = cr + 1; + end +end \ No newline at end of file From 1a44f57ede97f339bc311a67868e5831c964f037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 27 Nov 2024 14:58:30 +0100 Subject: [PATCH 138/201] Create BehaviourAnalysis_James.m --- James/BehaviourAnalysis_James.m | 447 ++++++++++++++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 James/BehaviourAnalysis_James.m diff --git a/James/BehaviourAnalysis_James.m b/James/BehaviourAnalysis_James.m new file mode 100644 index 0000000..f0f8777 --- /dev/null +++ b/James/BehaviourAnalysis_James.m @@ -0,0 +1,447 @@ +%% Analysing behaviour alone + +%roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; +% exp_path = ... +% fullfile( roller_path, "Batch2_ephys/MC/GADi18/211205_C_2450" ); +roller_path = fullfile("Z:\James\Practice Data\m7 (training)\"); +exp_path = ... + fullfile( roller_path, "behavior/" ); +% Figure overwrite flag +fowFlag = false; +% Annonymus function +expandPath = @(x) fullfile( x.folder, x.name); +% Milli factor +m = 1e-3; +% Looks in the experiment path for objects called ephys* (* is a wild card) +eph_path = dir( fullfile( exp_path, "ephys*" ) ); +% Delete everything that is not a folder +eph_path( ~[eph_path.isdir] ) = []; +% Looking folder 'Behaviour' +beh_path = fullfile( exp_path, "Behaviour" ); +% If the ephys path is empty, look for *analysis.mat file in the behaviour +% folder. +if ~isempty( eph_path ) + eph_path = expandPath( eph_path ); + figure_path = fullfile( eph_path, "Figures" ); + af_path = dir( fullfile( eph_path , "*analysis.mat" ) ); + af_path = expandPath( af_path ); +elseif exist( beh_path, "dir" ) + af_path = expandPath( dir( fullfile( beh_path, "*analysis.mat") ) ); + figure_path = fullfile( beh_path, "Figures" ); +else + % If there is no organisation in the folders, look for the file in the + % 'root' folder a.k.a. experiment folder. Then give up. + beh_path = exp_path; + af_path = expandPath( dir( fullfile( beh_path, "*analysis.mat") ) ); + figure_path = fullfile( beh_path, "Figures" ); +end + +[~, af_name] = fileparts( af_path ); +expName = extractBefore(af_name, "analysis"); +load( af_path, "Conditions", "fs") + +fnOpts = {'UniformOutput', false}; +axOpts = {'Box','off','Color','none'}; +lgOpts = cat( 2, axOpts{1:2}, {'Location','best'} ); + +open Conditions +ldFlag = false; +try + load( expandPath( dir( fullfile( beh_path, "RollerSpeed*.mat" ) ) ), "fr") +catch + ldFlag = true; +end + +%% Run independently +% User input!! +consCond = 1; +Nccond = length( consCond ); +%prmSubs = nchoosek( 1:Nccond, 2 ); + +% pairedStimFlags = arrayfun(@(c) any( ... +% Conditions(1).Triggers(:,1) == ... +% reshape( Conditions(c).Triggers(:,1), 1, [] ), 2 ), consCond, fnOpts{:} ); +% pairedStimFlags = cat( 2, pairedStimFlags{:} ); + +consCondNames = string( { Conditions( consCond ).name } ); + +% [behRes, behFig_path, behData, aInfo] = analyseBehaviour( beh_path, ... +% "ConditionsNames", cellstr( consCondNames ), ... +% "PairedFlags", pairedStimFlags, ... +% "FigureDirectory", figure_path, ... +% "ResponseWindow", [25, 350] * m, ... +% "ViewingWindow", [-450, 500] * m, ... +% "figOverWrite", fowFlag ); +[behRes, behFig_path, behData, aInfo] = analyseBehaviour( beh_path, ... + "ConditionsNames", cellstr( consCondNames ), ... + "FigureDirectory", figure_path, ... + "ResponseWindow", [25, 350] * m, ... + "ViewingWindow", [-450, 500] * m, ... + "figOverWrite", fowFlag ); + +if ldFlag + load( expandPath( dir( fullfile( beh_path, "RollerSpeed*.mat" ) ) ), "fr") +end +[Ns, Nt, Nb] = size( behData.Data ); + +vwin = sscanf( aInfo.VieWin, "V%f - %f s")'; +mdlt = fit_poly( [1, Ns], vwin + [1,-1] * (1/(2 * fr) ), 1 ); +txb = ( (1:Ns)'.^[1,0] ) * mdlt; +behNames = string( { behRes(1).Results.BehSigName } ); + +%% Normalised amplitud by absolute maximum + +rollYL = "Roller speed [cm/s]"; +yLabels = [repmat("Angle [°]", 1, Nb-1), rollYL]; +sym_flag = contains( behNames, "symmetry", "IgnoreCase", true ); +yLabels(sym_flag) = "Symmetry [a.u.]"; +cbLabels = strings(Nb, 2); +cbLabels([1,3],:) = repmat(["Retract", "Protract"],2,1); +cbLabels([2,4,5],:) = repmat(["Closed", "Opened"],3,1); +cbLabels(6,:) = ["Away", "Puff"]; +cbLabels(7,:) = ["Puff", "Away"]; +cbLabels(8,:) = ["Backward", "Forward"]; +screen_size = get(0, 'ScreenSize' ); +pxHeight = screen_size(4)*0.7; +lowBound = screen_size(4)*1/5; + +possCols = [2,3,5]; +Ncols = possCols( find( mod( Nb, possCols ) == 0, 1, 'first' ) ); +Nrows = Nb / Ncols; + +newAx = @(f) subplot( Nrows, Ncols, ix, "NextPlot", "add", "Parent", f ); + +createtiles = @(f) tiledlayout( f, Nrows, Ncols, ... + 'TileSpacing', 'Compact', 'Padding', 'tight'); + +isendrow = @(ix) ( (ix/Ncols) + 1) > Nrows; + +newFigure = @(x,y,fn) figure( "Color", "w", "Position", ... + [x, y, pxHeight/sqrt(2), pxHeight], "Name", fn ); + +fig = newFigure(0, lowBound, ""); + +t = createtiles( fig ); +for cbi = 1:Nb + ax = nexttile(t); + auxStack = squeeze( behData.Data(:,:,cbi) )'; + if cbi ~= 6 + auxStack = ( auxStack - median( auxStack, 2) ); + auxStack = auxStack ./ max( abs( auxStack ), [], 2 ); + end + imagesc( ax, txb*1e3, [], auxStack ); xline(ax, 0, 'k'); + xline( ax, [20, 120], 'LineWidth', 1, 'Color', 'b') + title( ax, behNames(cbi) ) + if mod( cbi, Ncols ) == 1 + ylabel(ax, 'Trials'); + else + ax.YAxis.Visible = 'off'; + end + if isendrow( cbi ) + xlabel(ax, 'Time [ms]'); + else + ax.XAxis.Visible = 'off'; + end + set( ax, axOpts{:} ) + + cb = colorbar(ax, "Box", "off", "Location", "west"); + cb.Ticks = [min(auxStack(:)), max(auxStack(:))] * 0.85; + cb.Label.String = yLabels(cbi); + cb.TickLabels = cellstr(cbLabels(cbi,:)); + cb.TickDirection = "none"; +end +axis( findobj( fig, "Type", "Axes" ), ... + [1e3*txb([1,end])', [1,Nt] + [-1,1]*(1/2)] ) +%cb.TickLabels = {'Backward', 'Forward'}; +linkaxes( findobj(fig, "Type", "Axes"), "xy") + +saveFigure(fig, fullfile( behFig_path, ... + "All trials all body parts normalised" ), true, fowFlag) + +clearvars auxStack + +%% L-norms and derivative +my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); + +respWin = sscanf( aInfo.Evoked, "R%f - %f ms")' * 1e-3; +% respWin = [30, 400]*1e-3; +sponWin = -flip(respWin); +n = getHesseLineForm([1,0]); + +% Spontaneous window +sponFlag = txb > sponWin; +sponFlag = xor( sponFlag(:,1), sponFlag(:,2) ); + +% Responsive window +respWin_aux = respWin; +if respWin(1) < 0.12 + respWin_aux = respWin + 0.1; +end + +if respWin_aux(2) > vwin(2) + respWin_aux(2) = vwin(2); +end +respWin = [repmat(respWin_aux,2,1); repmat( respWin, Nb-2, 1)]; + +evokFlags = arrayfun(@(x) txb > respWin(x,:), 1:Nb, fnOpts{:} ); +evokFlags = cellfun(@(x) xor(x(:,1), x(:,2) ), evokFlags, fnOpts{:} ); +evokFlags = cat( 2, evokFlags{:} ); + +myNorm = @(x, l) vecnorm(x, l, 1); +funcs = {@(x) x, @(x) diff(x, 1, 1) }; +app = [ repmat("", 1,Nb); repmat( "diff", 1, Nb) ]; + +Nfgs = numel(funcs); +figs = gobjects(Nfgs, 2); + +for l = [1, 2, inf] + + for cf = 1:Nfgs + figs(cf, 1) = newFigure(0, lowBound, ""); + %figure( "Color", "w", "Position", ... + % [0, 20, pxHeight/sqrt(2), pxHeight] ); + figs(cf, 2) = newFigure(pxHeight/sqrt(2), lowBound, "");... figure( "Color", "w", "Position", ... + %[pxHeight/sqrt(2), 20, pxHeight/sqrt(2), pxHeight] ); + t1 = createtiles( figs(cf, 1) ); + t2 = createtiles( figs(cf, 2) ); + for cb = 1:Nb + + ax = nexttile(t1); + if cb == 1 + ylabel(ax, 'Evoked') + elseif cb == Nb + xlabel(ax, 'Spontaneous') + lgObj = legend( ax, scObj, consCondNames, lgOpts{:}, ... + "AutoUpdate", "off" ); + end + + aux_x = myNorm( funcs{cf}(behData.Data( sponFlag, :, cb ) ), l ); + aux_y = myNorm( funcs{cf}( ... + behData.Data( evokFlags(:, cb), :, cb ) ), l ); + + scObj = arrayfun(@(c) line(ax, aux_x(pairedStimFlags(:,c)), ... + aux_y(pairedStimFlags(:,c)), "LineStyle", "none", ... + "Marker", "." ), 1:Nccond); + + title(ax, join( [sprintf("L%d", l), behNames(cb), ... + app(cf,cb)] ) ); + set( get(ax, "XAxis"), "Scale", "log"); + set( get(ax, "YAxis"), "Scale", "log") + line(ax, xlim(ax), xlim(ax), "LineStyle", "--", ... + "Color", 0.45*ones(1,3) ); + xticklabels( ax, xticks(ax) ); + yticklabels( ax, yticks(ax) ); + % text( ax, aux_x, aux_y, num2str( (1:Nt)' ), ... + % 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle') + set(ax, axOpts{:}, "XGrid", "on", "YGrid", "on") + Dyx = [aux_x(:), aux_y(:)] * n; + % [~, d_centre, d_scale] = zscore( double( Dyx(pairedStimFlags(:,1)) ) ); + + ax = nexttile(t2); + % boxchart(ax, pairedStimFlags * (1:Nccond)', Dyx, "Notch", "on" ) + trFlag = any( pairedStimFlags, 2 ); + boxchart( ax, pairedStimFlags(trFlag,:) * (1:Nccond)', ... + Dyx(trFlag), "Notch", "on", "JitterOutliers", "on", ... + "MarkerStyle", "." ) + % yyaxis(ax, "right"); line( ax, pairedStimFlags * (1:Nccond)', ... + % my_zscore(Dyx, d_centre, d_scale), "LineStyle", "none") + % yyaxis(ax, "left"); + yline( ax, 0, 'k' ) + title(ax, join( [sprintf("L%d", l), ... + behNames(cb), app(cf,cb)] ) ); + set( ax, axOpts{:} ); % set( ax.YAxis, "Scale", "log" ) + xticks(ax, 1:Nccond ); + if isendrow( cb ) + xticklabels( ax, consCondNames ) + else + ax.XAxis.Visible = 'off'; + end + + end + saveFigure( figs(cf, 1), fullfile(behFig_path, ... + join([sprintf("L%d norm", l), app(cf,1)]) ), true, fowFlag ) + + saveFigure( figs(cf, 2), fullfile(behFig_path, ... + regexprep( join( [sprintf( "L%d norm", l ), app(cf,2), ... + "boxplots"] ), ' +', ' ' ) ), true, fowFlag ) + end + clearvars aux_* ax figs +end + +%% Weigthed mean +sponWeight = (1:sum(sponFlag))/sum(1:sum(sponFlag)); +ln1 = log10( 1:sum(evokFlags(:,1)) ); +ln2 = sum( evokFlags(:,1) ):-1:1; +evokWeight = ln1 .* ln2; evokWeight = evokWeight / sum( evokWeight ); + +clrMap = lines(Nccond); + +xPos = (0:2)*pxHeight/sqrt(2); +Na = sum( pairedStimFlags ); +figs = gobjects( 3, 1 ); +ts = figs; +figNames = ["Weighted mean"; "Line distance boxplots"; + "Vector magnitude boxplots"]; + +for cf = 1:numel(figs) + figs(cf) = newFigure( xPos(cf), lowBound, figNames(cf) ); + ts(cf) = createtiles( figs( cf ) ); +end + + +for cb = 1:Nb + w_smu = reshape( sponWeight * behData.Data(sponFlag,:,cb), [], 1 ); + + w_emu = reshape( evokWeight * behData.Data( ... + evokFlags(:,cb), :, cb ), [], 1 ); + + + ax = nexttile( ts(1) ); set(ax, 'NextPlot', 'add' ); + scObj = arrayfun(@(c) scatter(ax, w_smu(pairedStimFlags(:,c)), ... + w_emu(pairedStimFlags(:,c)), '.', "MarkerEdgeColor", clrMap(c,:) ), ... + 1:Nccond); + + if cb == Nb + xlabel( ax, 'Spontaneous', 'FontSize', 8 ); + legend( ax, scObj, consCondNames, lgOpts{:}, "AutoUpdate", "off"); + elseif cb == 1 + ylabel( ax, 'Evoked', 'FontSize', 8 ); + end + + title(ax, behNames(cb) ); + set( ax, axOpts{:}, "XAxisLocation", "origin", ... + "YAxisLocation", "origin" ); grid( ax, "on" ); %axis( ax, 'square' ) + line(ax, xlim(ax), xlim(ax), 'LineStyle', '--', 'Color', 0.45*ones(1,3)) + + ax = nexttile( ts(2) ); set(ax, 'NextPlot', 'add' ); + + bxObj = boxchart(ax, pairedStimFlags(trFlag,:) * (1:Nccond)', ... + [w_smu(trFlag), w_emu(trFlag)] * n, ... + "Notch", "on", "JitterOutlier", "on", "MarkerStyle", ".", ... + "Boxfacecolor", "k", "Markercolor", "k" ); + + if cb == Nb + legend( ax, bxObj, '$\vec{x} \cdot n + d$', ... + 'Interpreter' ,'latex' , lgOpts{:}, "AutoUpdate", "off" ); + elseif cb == 1 + ylabel( ax, 'Distance from line' ) + end + + xticks( ax, 1:Nccond ); + if isendrow(cb) + xticklabels( ax, consCondNames ) + else + ax.XAxis.Visible = 'off'; + end + + title(ax, behNames(cb) ); + set( ax, axOpts{:} ); yline( ax, 0, 'Color', 0.75*ones(1,3), ... + 'LineWidth', 1/3); + + ax = nexttile( ts(3) ); set(ax, 'NextPlot', 'add' ); + bxObj = boxchart(ax, pairedStimFlags(trFlag,:) * (1:Nccond)', ... + vecnorm( [w_smu(trFlag), w_emu(trFlag)], 2, 2 ), ... + "Notch", "on", "JitterOutlier", "on", "MarkerStyle", "." ); + if cb == Nb + legend( ax, bxObj, 'L-2 norm', ... + lgOpts{:}, "AutoUpdate", "off", "interpreter", "latex" ); + elseif cb == 1 + ylabel( ax, 'Distance from origin' ) + end + + xticks( ax, 1:Nccond ); + if isendrow(cb) + xticklabels( ax, consCondNames ) + else + ax.XAxis.Visible = 'off'; + end + + title(ax, behNames(cb) ); %axis( ax, 'square' ) + set( ax, axOpts{:} ); + + for cc = 1:Nccond + behRes(cc).Results(cb).Puff_Effect = ... + [w_smu( pairedStimFlags(:,cc) ), ... + w_emu( pairedStimFlags(:,cc) )] * n; + behRes(cc).Results(cb).Baseline_L2 = ... + vecnorm( [w_smu( pairedStimFlags(:,cc) ), ... + w_emu( pairedStimFlags(:,cc) )], 2, 2); + end +end + +wmFigNames = ["Weighted mean scatter"; ... + "Line distance boxplots"; ... + "Origin distance"]; + +arrayfun(@(x, f) saveFigure( x, fullfile( behFig_path, f ), true, fowFlag), ... + figs(:), wmFigNames(:)) + +clearvars ax figs + +%% Amplitude index and trial proportion + +if ~exist( "fr", "var" ) && ldFlag + load( expandPath( dir( fullfile( beh_path, "RollerSpeed*.mat" ) ) ), "fr") + ldFlag = false; +end + +[pAreas, ~, behAreaFig] = createBehaviourIndex(behRes); +behMeasures = string({behAreaFig.Name}); +biFigPttrn = behMeasures+"%s"; +biFigPttrn = arrayfun(@(s) sprintf(s, sprintf(" %s (%%.3f)", ... + consCondNames ) ), biFigPttrn ); + +for it = 1:numel(behMeasures) + behRes = arrayfun(@(bs, ba) setfield( bs, ... + strrep( behMeasures(it), " ", "_" ), ba), behRes(:), pAreas(:,it) ); +end + +arrayfun(@(f) set( f, 'UserData', behRes ), behAreaFig ); + +biFN = arrayfun(@(s) sprintf( biFigPttrn(s), pAreas(:,s) ), 1:numel(behMeasures) ); + +arrayfun(@(f, fn) saveFigure(f, fullfile(behFig_path, fn), true, fowFlag), ... + behAreaFig(:), biFN(:) ); + + + +%% Count figure +trMvFlag = arrayfun(@(cr) behRes(1).Results(cr).MovStrucure.MovmentFlags, ... + 1:size(behRes(1).Results,2), fnOpts{:}); trMvFlag = cat(3, trMvFlag{:}); +BIscaleMat = sum(trMvFlag,3); +BIscale = arrayfun(@(cc) BIscaleMat(pairedStimFlags(:,cc), cc), 1:Nccond, ... + fnOpts{:}); +hstOpts = {'BinMethod', 'integers', 'BinLimits', [0,Nb] + [-1,1]/2}; +[hg, hg_bin] = cellfun(@(c) histcounts(c, hstOpts{:}), ... + BIscale, fnOpts{:}); +hg = cat(1, hg{:}); hg_bin = cat(1, hg_bin{:}); + +% [p_amp, h_amp] = ranksum(cat(1, zamp{1,:}), cat(1, zamp{2,:})); + +clrMap = lines(Nccond); +countFig = figure; ax(1) = subplot(10,1,1:8); +bar(ax(1), (0:Nb)', (hg./sum(hg,2))', 'EdgeColor', 'none'); hold on; +poaDist = cellfun(@(bi) fitdist(bi,"Poisson"), BIscale); +ylim(ax(1), [0,1]); set(ax(1), axOpts{:}); +legend(ax(1), consCondNames, 'AutoUpdate','off', lgOpts{:}) +lmbdaHeight = 0.95-(0.15/Nccond)*(0:Nccond-1); +arrayfun(@(pd) scatter(ax(1), poaDist(pd).lambda, lmbdaHeight(pd), '|',... + 'MarkerEdgeColor', clrMap(pd,:)), 1:Nccond) +arrayfun(@(pd) line(ax(1), paramci(poaDist(pd)), ... + lmbdaHeight([pd,pd]), 'Color', clrMap(pd,:), ... + 'Marker', '|'), 1:Nccond) +[p, chiVal] = arrayfun(@(ps) chi2test(hg(prmSubs(ps,:), :)), ... + 1:size(prmSubs,1)); +ax(2) = subplot(10,1,9:10); +signBeh = arrayfun(@(x) sprintf("%s vs %s p=%.3f", ... + consCondNames(prmSubs(x,:)), p(x)), 1:size(prmSubs,1)); +text(ax(2), 0, -0.3, sprintf('%s vs. %s P=%.3f\n', ... + [consCondNames(prmSubs), string(p(:))]')) +set(ax(2), 'Visible', 'off') +set(countFig, 'UserData', {signBeh, p}) +title(ax(1), strrep(expName, '_',' ')); xlabel(ax(1),'Moving body parts') +ylabel(ax(1),'Trial proportion') +countFigName = sprintf("Count distributions P%s", ... + sprintf(" %.3f", p(:))); + +saveFigure(countFig, fullfile(behFig_path, countFigName), true, fowFlag); \ No newline at end of file From b60c79078fe81687beb699fdbf8153ee7027a8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 29 Nov 2024 11:03:56 +0100 Subject: [PATCH 139/201] Create Figure5A.m --- Emilio/Figure5A.m | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Emilio/Figure5A.m diff --git a/Emilio/Figure5A.m b/Emilio/Figure5A.m new file mode 100644 index 0000000..b022ecb --- /dev/null +++ b/Emilio/Figure5A.m @@ -0,0 +1,68 @@ +data_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch18_ephys\MC\GADi43\240227_C+F_2200"; +load( fullfile( data_path, "Regression CW-800.00-800.00ms " + ... + "DW-100.00-100.00 BZ5.00.mat"), 'DX', 'mdlAll_ind', 'params') +load( fullfile( data_path, "ephys_E1", ... + "GADi43_C+F_2200 RW20.00-200.00 SW-300.00--120.00 " + ... + "VW-300.00-400.00 ms PuffAll (unfiltered) RelSpkTms.mat"), ... + 'relativeSpkTmsStruct' ) +fnOpts = {'UniformOutput', false}; +vec2trials = @(x) reshape( x, params.Nb, params.Nr, params.Ns ); +bpn_abb = {'SWM', 'SWF', 'NWM', 'NWF', 'WA', 'S', 'N', 'RS'}; +m = 1e-3; k = 1e3; +nox = @(x) set( get( x, 'XAxis' ), 'Visible', 'off' ); +lnOpts = {'Marker', '|', 'MarkerSize', 12, 'LineStyle', 'none', 'Color', 'k'}; +%% Auxiliary variables for decisions and plotting +rel_win = params.relative_window; +bin_size = params.bin_size; + +mdl_mu = squeeze( mean( mdlAll_ind, 2 ) ); +y_trials = vec2trials( DX{1} ); +y_pred = DX{2} * mdl_mu; +y_ptrials = vec2trials( y_pred ); +trial_tx = (rel_win(1) + bin_size/2):bin_size:(rel_win(2) - bin_size/2); + +SSEt = squeeze( sum( ( y_trials - y_ptrials ).^2, 1 ) ); +SSTt = squeeze( sum( ( y_trials - mean( y_trials, 1 ) ).^2, 1 ) ); +r_sq_trials = 1 - (SSEt./SSTt); + +% Decide based on which trial has the highest R²: trial 6, NWM (3) +[~, ord] = sort( r_sq_trials, "descend" ); +rst = relativeSpkTmsStruct(1).SpikeTimes; +%% +f = figure( "Color", "w" ); t = createtiles( f, 4, 1 ); +ax = gobjects( 3, 1 ); + +ax(1) = nexttile( t ); +line( ax(1), k*trial_tx, y_trials(:,6,3), 'LineWidth', 2, 'Color', 0.15*ones(1,3) ) +cleanAxis(ax(1)); nox(ax(1)); +yticklabels( ax(1), yticks(ax(1))-90 ) +ylabel( ax(1), 'Angle [°]'); ytickangle( ax(1), 90 ) + +ax(2) = nexttile( t, [2,1] ); hold( ax(2), "on" ) +Nu = size( rst, 1 ); +Npu = 15; +if Npu > Nu + Npu = Nu; +end +ct = 1; +for cu = round(linspace(1, Nu, Npu)) + if cu > Nu + break + end + rst_aux = rst{cu,6}; + line( ax(2), k*rst_aux, ct+zeros( size( rst_aux, 2 ), 1 ), lnOpts{:} ) + ct = ct + 1; +end +nox(ax(2)); cleanAxis(ax(2)); +ylabel(ax(2), 'Units'); ytickangle( ax(2), 90 ) + +ax(3) = nexttile( t ); +line( ax(3), k*trial_tx, y_ptrials(:,6,3), 'LineWidth', 2, 'Color', [0,0.6,0] ) +cleanAxis(ax(3)); +yticklabels( ax(3), yticks(ax(3))-90 ) +ylabel( ax(3), 'Angle [°]'); ytickangle( ax(3), 90 ) +set( ax, 'TickDir', 'out' ) +linkaxes( ax, 'x'); xlim( ax(3), [-200, 400] ) +xlabel( ax(3), 'Time [ms]' ) + +xline( ax(3), -200:20:400, 'Color', 0.5*ones(1,3) ) From a16fd4d6add9bcd9535913493f9cdba04cd0fcdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Dec 2024 08:54:37 +0100 Subject: [PATCH 140/201] Create Spontaneous_eOPN3_Figure3.m --- Emilio/Spontaneous_eOPN3_Figure3.m | 124 +++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Emilio/Spontaneous_eOPN3_Figure3.m diff --git a/Emilio/Spontaneous_eOPN3_Figure3.m b/Emilio/Spontaneous_eOPN3_Figure3.m new file mode 100644 index 0000000..b911509 --- /dev/null +++ b/Emilio/Spontaneous_eOPN3_Figure3.m @@ -0,0 +1,124 @@ +%% +fnOpts = {'UniformOutput', false}; +my_xor = @(x) xor( x(:,1), x(:,2) ); +ovwFlag = false; + +getMI = @(x,d) diff(x, 1, d)./sum(x, d).*(sum(x,d)>0) + (1.*(sum(x,d)==0 | sum(x,d)< 1e-12)); +% getMI = @(ctr, cnd) (cnd - ctr) ./ ( (cnd + ctr).*((cnd + ctr)>0) + (1.*((cnd + ctr)==0 | (cnd + ctr)<1e-9) )); +load(['C:\Users\jefe_\seadrive_root\Emilio U\FĂĽr meine Gruppen\GDrive ' ... + 'GrohLab\Projects\00 SC\SC Behaviour\Figures\Figure 3\Matlab ' ... + 'figures\Data\Spontaneous FR.mat']) +expandName = @(x) fullfile( x.folder, x.name ); + +sessions_per_mouse = arrayfun(@(x) dir( fullfile( expandName( x ) ) ), ... + animalFolders, fnOpts{:} ); +sessions_per_mouse = cellfun(@(x) x([x.isdir] & ... + ~ismember( {x.name}, {'.','..'} )), sessions_per_mouse, fnOpts{:} ); +Nsess = sum( cellfun(@numel, sessions_per_mouse ) ); +% 1. Mouse and session number, 2. spike count per spontaneous window, 3. +% spontaneous window limits, 4. firing frequency per window per unit, 5. +% treatment start, 6. conditions indicator, 7. median firing rate per unit, +% 8. p-value of modulation index +results = cell(Nsess, 8 ); +cr = 1; +for ca = 1:numel(animalFolders) + fprintf(1, 'Animal: %s\n', animalFolders(ca).name ) + sessions = sessions_per_mouse{ca}; + ce = 1; + for cs = 1:numel(sessions) + results{cr,1} = [ca,cs]; + fprintf(1, 'Session: %s\n', sessions(cs).name ); + spkFN = dir( fullfile( expandName( sessions(cs) ), 'ephys*', ... + '*spike_times.mat' ) ); + anFN = dir( fullfile( expandName( sessions(cs) ), '*', ... + '*analysis.mat' ) ); + if ~isempty( spkFN ) + load( expandName(spkFN ) ) + else + fprintf(1, "%s: ", sessions(cs).name ) + fprintf(1, 'No spike_times file found!\n') + fprintf(1, 'Skipping!\n') + continue + end + if ~isempty( anFN ) + load( expandName(anFN ), 'Conditions', 'fs' ) + else + fprintf(1, "%s: ", sessions(cs).name ) + fprintf(1, 'No analysis file found!\n') + fprintf(1, 'Skipping!\n') + continue + end + FigureDir = fullfile( spkFN.folder, "Figures" ); + Nu = numel( spike_times ); + Topn = Conditions(2).Triggers(1,1)/fs; + Texp = Conditions(4).Triggers(end,2)/fs; + allTrigs = sortrows( cat(1, Conditions(2:4).Triggers ), 1, "ascend" ); + + lmts = [[0; allTrigs(:,2)/fs + 0.2], [allTrigs(:,1)/fs;Texp]]; + lmts(diff( lmts, 1, 2 ) < 0,:) = []; + + treat_sub = find( lmts(:,1) < Topn, 1, "last" ); + Nt = size(lmts, 1); + Nsp = cellfun(@(u) arrayfun(@(t) sum( my_xor( u < lmts(t,:) ) ), ... + 1:size( lmts, 1 ) ), spike_times, fnOpts{:} ); + Nsp = cat( 1, Nsp{:} ); + + fr_sp = Nsp ./ diff( lmts, 1, 2 )'; + + cndID = [ones( 1, treat_sub), 1+ones(1, Nt-treat_sub)]; + cndID = repmat( cndID, Nu, 1 ); + + medFr = arrayfun(@(c) median( fr_sp(:,cndID(1,:)==c), 2 ), 1:2, fnOpts{:} ); + medFr = cat(2, medFr{:}); + + medMI = getMI( medFr, 2 ); + p = signrank( medMI ); + + results(cr,2:8) = {Nsp, ... Spike cound per window per unit + lmts, ... Window limits + fr_sp, ... Firing rate per unit per window + treat_sub, ... Subscript when treatment started + cndID(1,:), ... Condition membership indicator + medFr, ... Median firing rate per unit over each condition windows + [p, median( medMI( ~isnan( medMI ) ) )] }; % p-value and median MI for all units per condition. + cr = cr + 1; + %% + + f = figure("Color", "w"); t = createtiles( f, 1, 4 ); + ax(1) = nexttile(t,[1,3]); + + loglog(ax(1), medFr(:,1), medFr(:,2), "k." ); + hold(ax(1), 'on'); line(ax(1), xlim, xlim, 'Color', 'k', 'LineStyle', ':' ) + xticklabels(ax(1), xticks(ax(1)) ); yticklabels(ax(1), yticks(ax(1)) ) + xlabel(ax(1), 'Control [Hz]', 'interpreter', 'latex' ); + ylabel(ax(1), 'eOPN3 [Hz]', 'interpreter', 'latex' ) + axis( ax(1), 'square' ) + ytickangle(ax(1), 90 ) + + ax(2) = nexttile(t); + boxchart(ax(2), getMI(medFr, 2), 'Notch', 'on', ... + 'BoxFaceColor', 0.15*ones(1,3), 'JitterOutliers', 'on', ... + 'MarkerStyle', '.', 'MarkerColor', 0.15*ones(1,3) ) + text( ax(2), 1, -1.1, sprintf("$p=%.3g$", p), 'Interpreter', 'latex', ... + "HorizontalAlignment", "center" ) + ylabel(ax(2), 'Decrease $\leftarrow$ Modulation index $\rightarrow$ Increase', ... + 'Interpreter', 'latex' ) + yline( ax(2) , 0, 'k:' ) + disappearAxis(ax(2)) + ylim( ax(2), [-1,1] ) + cleanAxis(ax); + set( ax, 'TickDir', 'out' ) + set( f, 'UserData', {cndID(1,:), medFr, medMI, p} ) + title(t, 'Spontaneous firing rate per unit', 'interpreter', 'latex') + saveFigure(f, fullfile( FigureDir, 'Spontaneous firing rate pre and post eOPN3' ), true, ovwFlag ) + end + close all + fprintf(1, 'Complete!\n' ) +end +%% +results( all( cellfun(@isempty, results ), 2 ), : ) = []; +rTable = cell2table( results, "VariableNames", {'ID', 'SpikeCounts', 'SpontaneousWindows', ... + 'FR', 'TreatmentStart', 'ConditionID', 'MedianFR_pu', 'p_MedianTot'} ); +save( "c:\Users\jefe_\seadrive_root\Emilio U\FĂĽr meine Gruppen\GDrive " + ... + "GrohLab\Projects\00 SC\SC Behaviour\Figures\Figure 3\Matlab " + ... + "figures\Data\Spontaneous FR.mat", "rTable", "animalFolders" ) \ No newline at end of file From eb2ea1a253db02c3ef7456f6af010dfa0d492553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 4 Dec 2024 10:31:23 +0100 Subject: [PATCH 141/201] Update BehaviourAnalysis_James.m --- James/BehaviourAnalysis_James.m | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/James/BehaviourAnalysis_James.m b/James/BehaviourAnalysis_James.m index f0f8777..5e9cd07 100644 --- a/James/BehaviourAnalysis_James.m +++ b/James/BehaviourAnalysis_James.m @@ -3,9 +3,9 @@ %roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; % exp_path = ... % fullfile( roller_path, "Batch2_ephys/MC/GADi18/211205_C_2450" ); -roller_path = fullfile("Z:\James\Practice Data\m7 (training)\"); -exp_path = ... - fullfile( roller_path, "behavior/" ); +exp_path = fullfile( "Z:\James\Learning Experiments\28-11-24_AM\m1" ); +% exp_path = ... +% fullfile( roller_path, "behavior/" ); % Figure overwrite flag fowFlag = false; % Annonymus function @@ -90,11 +90,16 @@ behNames = string( { behRes(1).Results.BehSigName } ); %% Normalised amplitud by absolute maximum - -rollYL = "Roller speed [cm/s]"; -yLabels = [repmat("Angle [°]", 1, Nb-1), rollYL]; +rollYL = ""; +rsFlag = false; +if contains( behNames, "Roller speed", "IgnoreCase", true) + rollYL = "Roller speed [cm/s]"; + rsFlag = true; +end +yLabels = [repmat("Angle [°]", 1, Nb-rsFlag), rollYL]; sym_flag = contains( behNames, "symmetry", "IgnoreCase", true ); yLabels(sym_flag) = "Symmetry [a.u.]"; +yLabels(~strlength(yLabels)) = []; cbLabels = strings(Nb, 2); cbLabels([1,3],:) = repmat(["Retract", "Protract"],2,1); cbLabels([2,4,5],:) = repmat(["Closed", "Opened"],3,1); @@ -107,12 +112,15 @@ possCols = [2,3,5]; Ncols = possCols( find( mod( Nb, possCols ) == 0, 1, 'first' ) ); -Nrows = Nb / Ncols; +if isempty( Ncols ) + Ncols = 2; +end +Nrows = ceil( Nb / Ncols ); -newAx = @(f) subplot( Nrows, Ncols, ix, "NextPlot", "add", "Parent", f ); +% newAx = @(f) subplot( Nrows, Ncols, ix, "NextPlot", "add", "Parent", f ); -createtiles = @(f) tiledlayout( f, Nrows, Ncols, ... - 'TileSpacing', 'Compact', 'Padding', 'tight'); +% createtiles = @(f) tiledlayout( f, Nrows, Ncols, ... + % 'TileSpacing', 'Compact', 'Padding', 'tight'); isendrow = @(ix) ( (ix/Ncols) + 1) > Nrows; @@ -121,7 +129,7 @@ fig = newFigure(0, lowBound, ""); -t = createtiles( fig ); +t = createtiles( fig, Nrows, Ncols ); for cbi = 1:Nb ax = nexttile(t); auxStack = squeeze( behData.Data(:,:,cbi) )'; From a40e4b3e13ff049a4780cd9fcec692edf693eb27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 9 Dec 2024 20:16:59 +0100 Subject: [PATCH 142/201] Create script_learning_experiments.m --- James/script_learning_experiments.m | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 James/script_learning_experiments.m diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m new file mode 100644 index 0000000..ec88766 --- /dev/null +++ b/James/script_learning_experiments.m @@ -0,0 +1,65 @@ +%% Call function +dt= datetime(2024,11,25); + +dt.Format = 'dd-MM-yy'; + +daytime = ["AM","PM"]; + +mice_number= ["m1", + "m2", + "m3", + "m4", + "m5", + "m6"] + +data_path = "Z:\James\Learning Experiments"; +ss_means = NaN(24,6,8); +ss_max = NaN(6,8); + +expandName = @(x) fullfile( x.folder, x.name ); + +for h = 0:11 + for x = 1:2 + for m = 1:6 + ss_Data = fullfile(data_path, sprintf("%s_%s\\%s\\%s",string(dt+h),daytime(x),mice_number(m),"Simple summary.mat")); + ss_Path = fullfile(data_path, sprintf("%s_%s\\%s",string(dt+h),daytime(x),mice_number(m))); + try + load(ss_Data) + catch + try + ss_Data = dir( fullfile(ss_Path, 'BehaviourResults*.mat') ); + load( expandName( ss_Data ), 'behRes' ) + summStruct = behRes; + catch + rec_file = dir(fullfile(ss_Path, 'Recording*.bin')); + fID = fopen( expandName( rec_file ) , 'w' ); + fwrite( fID, [], 'int16' ); + fclose(fID); + + prepare64ChanBin4KS( ss_Path, 'BinFileName', sprintf("%s_%s_%s",mice_number(m),string(dt+h),daytime(x)), 'AllBinFiles', true ); + + pgObj = ProtocolGetter(ss_Path); + pgObj.getConditionSignals; + pgObj.getSignalEdges; + pgObj.getFrequencyEdges(0.8); + pgObj.pairStimulus(0.2); + pgObj.saveConditions; + + [summStruct, behFig_path, behData, aInfo] = analyseBehaviour( ss_Path, ... + "ConditionsNames", "Puff", ... + "ResponseWindow", [25, 350] * 1e-3, ... + "ViewingWindow", [-450, 500] * 1e-3, ... + "figOverWrite", false ); + + close all; + end + end + r = ((x-1)*12)+(h+1); + N_att = numel(summStruct.Results); + ss_means(r,m,1:N_att) = mean(cat(1,summStruct.Results.MaxValuePerTrial),2); + if h == 0 && x==1 + ss_max(m,1:N_att) = max(cat(1,summStruct.Results.MaxValuePerTrial),[],2); + end + end + end +end From 564b1413a6c8d090ebab35235b599a2c3b76bce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 9 Dec 2024 20:42:34 +0100 Subject: [PATCH 143/201] Remove pool to create more powerful --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 293f314..f29dca6 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -570,7 +570,7 @@ set( psthFigs(cf), 'UserData', PSTH{cf} ) saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); end - + delete( gcp( 'nocreate' ) ) else psthFigs = arrayfun(@(f) openfig(f + ".fig", ofgOpts{:} ), psthFP); PSTH = arrayfun(@(f) get( f, 'UserData' ), psthFigs, fnOpts{:} ); From 6d3ab8c4532a64cabcecea8cf397a8183db4f462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 11 Dec 2024 12:33:33 +0100 Subject: [PATCH 144/201] Memory validation --- Jesus/DE_Jittering.m | 52 +++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index f29dca6..59a1375 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -551,26 +551,38 @@ psthFigs = gobjects( numel(psthFP), 1 ); auxID = pclID(ordSubs); auxStack = discStack(filterIdx,:,:); PSTH = cell(Nccond,1); trig = PSTH; - try - parpool('Processes', 2); - catch ME - delete(gcp('nocreate')) - parpool('Processes', 2); - end - parfor cf = 1:Nccond - % for cf = 1:Nccond - [PSTH{cf}, trig{cf}] = getPSTH(auxStack, timeLapse, ... - ~delayFlags(:,cf), binSz, fs); - psthFigs(cf) = plotClusterReactivity(PSTH{cf}(ordSubs,:), trig{cf},... - Na(cf), timeLapse, binSz, [consCondNames(cf); auxID], strrep(expName,'_',' '), ... - stims{cf}, csNames); - ylabel(psthFigs(cf).Children(end), ... - [psthFigs(cf).Children(end).YLabel.String, ... - sprintf('^{%s}',orderedStr)]) - set( psthFigs(cf), 'UserData', PSTH{cf} ) - saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); - end - delete( gcp( 'nocreate' ) ) + try + parfor cf = 1:Nccond + % for cf = 1:Nccond + [PSTH{cf}, trig{cf}] = getPSTH(auxStack, timeLapse, ... + ~delayFlags(:,cf), binSz, fs); + psthFigs(cf) = plotClusterReactivity(PSTH{cf}(ordSubs,:), trig{cf},... + Na(cf), timeLapse, binSz, [consCondNames(cf); auxID], strrep(expName,'_',' '), ... + stims{cf}, csNames); + ylabel(psthFigs(cf).Children(end), ... + [psthFigs(cf).Children(end).YLabel.String, ... + sprintf('^{%s}',orderedStr)]) + set( psthFigs(cf), 'UserData', PSTH{cf} ) + saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); + end + catch + fprintf(1, 'Not enough memory to run PSTH building in parallel!\n') + for cf = 1:Nccond + % for cf = 1:Nccond + [PSTH{cf}, trig{cf}] = getPSTH(auxStack, timeLapse, ... + ~delayFlags(:,cf), binSz, fs); + psthFigs(cf) = plotClusterReactivity(PSTH{cf}(ordSubs,:), trig{cf},... + Na(cf), timeLapse, binSz, [consCondNames(cf); auxID], strrep(expName,'_',' '), ... + stims{cf}, csNames); + ylabel(psthFigs(cf).Children(end), ... + [psthFigs(cf).Children(end).YLabel.String, ... + sprintf('^{%s}',orderedStr)]) + set( psthFigs(cf), 'UserData', PSTH{cf} ) + end + parfor cf = 1:Nccond + saveFigure( psthFigs(cf), psthFP(cf), true, owFlag ); + end + end else psthFigs = arrayfun(@(f) openfig(f + ".fig", ofgOpts{:} ), psthFP); PSTH = arrayfun(@(f) get( f, 'UserData' ), psthFigs, fnOpts{:} ); From 1d8cc99bc5da00c2b667fc3c446b9e6aed912d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 11 Dec 2024 12:33:44 +0100 Subject: [PATCH 145/201] ctrl + a, ctrl + i --- Jesus/DE_Jittering.m | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 59a1375..23c9df7 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -378,7 +378,7 @@ stFigSubfix = stFigSubfix + " " + RW_key + " " + SW_key; end -cmbSubs = 0; snglSubs = 1; +cmbSubs = 0; snglSubs = 1; cmpCondNames = string(consCondNames(:)); prmSubs = ones(1,2); if Nccond > 1 prmSubs = nchoosek(1:Nccond,2); Nsf = size(prmSubs,1) + Nccond; @@ -389,7 +389,7 @@ end stFigFN = fullfile(ephFigDir, "Stat " + cmpCondNames + stFigSubfix); if cmbSubs - cmpCondNames_aux([snglSubs, cmbSubs]) = stFigFN; + cmpCondNames_aux([snglSubs, cmbSubs]) = stFigFN; stFigFN = cmpCondNames_aux; end @@ -470,8 +470,8 @@ relSpkFN = string(expName) + " " + RW_key + " " + SW_key + " " + ... VW_key + " ms " + C_key + " (" + string(filtStr) + ") RelSpkTms.mat"; consVars = {'relativeSpkTmsStruct', 'firstSpkStruct', ... - 'SpontaneousStruct', 'configStructure'}; -rspMF = matfile(fullfile(dataDir, relSpkFN)); + 'SpontaneousStruct', 'configStructure'}; +rspMF = matfile(fullfile(dataDir, relSpkFN)); if ~exist( fullfile( dataDir, relSpkFN ),'file') || ... any(~contains(who(rspMF), consVars)) @@ -481,7 +481,7 @@ relativeSpkTmsStruct = struct('name', cellstr(consCondNames), ... 'SpikeTimes', rst); firstSpkStruct = getFirstSpikeInfo(relativeSpkTmsStruct, configStructure); - + % Spontaneous firing rates Texp = Ns/fs; trainDuration = 1; @@ -531,7 +531,7 @@ end %psthTx = (0:Nbn-1) * binSz + timeLapse(1); - Ntc = size(cst,2); +Ntc = size(cst,2); psthFN = "PSTH " + consCondNames(:) + " " + BZ_key + " " + string(orderedStr); if filtFlag psthFN = psthFN + " " + filtStr; @@ -619,7 +619,7 @@ end if filtFlag lpFN = lpFN + " (" + filtStr + ")"; - if Nccond > 1 + if Nccond > 1 lmiFP = lmiFP + " (" + filtStr + ")"; end end @@ -627,7 +627,7 @@ if ~exist(lpFP+".fig", "file") logFigs = plotLogPSTH(logPSTH); saveFigure(logFigs(1), lpFP, true, owFlag ) if numel(logFigs) > 1 - popEffects = logFigs(2).UserData; + popEffects = logFigs(2).UserData; MIStruct = struct('ConditionNames', consCondNames, ... 'MI', arrayfun(@(x) struct('Comparative', ... string(popEffects{x,1})+" vs "+... @@ -932,16 +932,16 @@ [pAreas, ~, behAreaFig] = createBehaviourIndex(behRes); behRes = arrayfun(@(bs, ba) setfield(bs,'BehIndex', ba), behRes, pAreas); set(behAreaFig, 'UserData', behRes) - + biFN = sprintf(biFigPttrn, pAreas); - + trMvFlag = arrayfun(@(cr) behRes(1).Results(cr).MovStrucure.MovmentFlags, ... 1:size(behRes(1).Results,2), fnOpts{:}); trMvFlag = cat(3, trMvFlag{:}); BIscaleMat = sum(trMvFlag,3); BIscale = arrayfun(@(cc) BIscaleMat(delayFlags(:,cc), cc), 1:Nccond, ... fnOpts{:}); [hg, hg_bin] = cellfun(@(c) histcounts(c, hstOpts{:}), ... - BIscale, fnOpts{:}); + BIscale, fnOpts{:}); hg = cat(1, hg{:}); hg_bin = cat(1, hg_bin{:}); @@ -951,7 +951,7 @@ countFig = figure( figOpts{:} ); ax(1) = subplot(10,1,1:8); bar(ax(1), (0:4)', (hg./sum(hg,2))', 'EdgeColor', 'none'); hold on; poaDist = cellfun(@(bi) fitdist(bi,"Poisson"), BIscale); - ylim(ax(1), [0,1]); set(ax(1), axOpts{:}); + ylim(ax(1), [0,1]); set(ax(1), axOpts{:}); legend(ax(1), consCondNames, 'AutoUpdate','off', lgOpts{:}) lmbdaHeight = 0.95-(0.15/Nccond)*(0:Nccond-1); arrayfun(@(pd) scatter(ax(1), poaDist(pd).lambda, lmbdaHeight(pd), '|',... From bdf6466a0783a816e770f7a22b76bcf6e1e0a021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 10 Jan 2025 00:46:35 -0600 Subject: [PATCH 146/201] Removed output --- James/script_learning_experiments.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index ec88766..1652b55 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -10,7 +10,7 @@ "m3", "m4", "m5", - "m6"] + "m6"]; data_path = "Z:\James\Learning Experiments"; ss_means = NaN(24,6,8); From 36e7113a721fbe7a757ffcc9df7e1b17232ca92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 23 Jan 2025 15:30:58 +0100 Subject: [PATCH 147/201] Updated the behaviour analysis --- Jesus/DE_Jittering.m | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 23c9df7..9e66d00 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -910,7 +910,7 @@ pointFlag = arrayfun(@(x) any(strcmpi(x.name, {'.','..'})), flds); flds(pointFlag) = []; behFoldFlag = arrayfun(@(x) any(strcmpi(x.name, 'Behaviour')), flds); -possNames = ["P", "L"]; +possNames = ["P", "L"]; m = 1e-3; if any(behFoldFlag) && sum(behFoldFlag) == 1 % If only one folder named Behaviour exists, chances are that this is % an awake experiment. @@ -922,18 +922,30 @@ hstOpts = {'BinMethod', 'integers', 'BinLimits', [-0.5,4.5]}; behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); - [behRes, behFigDir, behData, aInfo] = analyseBehaviour(behDir, ... - 'Condition', possNames(behChCond), ... - 'PairedFlags', delayFlags, ... - 'FigureDirectory', FigureDir, ... - 'ConditionsNames', cellstr(consCondNames)); - biFigPttrn = "BehIndex%s"; - biFigPttrn = sprintf(biFigPttrn, sprintf(" %s (%%.3f)", consCondNames)); + + [behRes, behFig_path, behData, aInfo] = analyseBehaviour( beh_path, ... + "Condition", possNames(behChCond), ... + "ConditionsNames", cellstr( consCondNames ), ... + "PairedFlags", delayFlags, ... + "FigureDirectory", FigureDir, ... + "ResponseWindow", [25, 350] * m, ... + "ViewingWindow", [-450, 500] * m, ... + "figOverWrite", owFlag ); + [pAreas, ~, behAreaFig] = createBehaviourIndex(behRes); - behRes = arrayfun(@(bs, ba) setfield(bs,'BehIndex', ba), behRes, pAreas); - set(behAreaFig, 'UserData', behRes) + behMeasures = string({behAreaFig.Name}); + biFigPttrn = behMeasures+"%s"; + biFigPttrn = arrayfun(@(s) sprintf(s, sprintf(" %s (%%.3f)", ... + consCondNames ) ), biFigPttrn ); + + for it = 1:numel(behMeasures) + behRes = arrayfun(@(bs, ba) setfield( bs, ... + strrep( behMeasures(it), " ", "_" ), ba), behRes(:), pAreas(:,it) ); + end + + arrayfun(@(f) set( f, 'UserData', behRes ), behAreaFig ); - biFN = sprintf(biFigPttrn, pAreas); + biFN = arrayfun(@(s) sprintf( biFigPttrn(s), pAreas(:,s) ), 1:numel(behMeasures) ); trMvFlag = arrayfun(@(cr) behRes(1).Results(cr).MovStrucure.MovmentFlags, ... 1:size(behRes(1).Results,2), fnOpts{:}); trMvFlag = cat(3, trMvFlag{:}); @@ -944,7 +956,7 @@ BIscale, fnOpts{:}); hg = cat(1, hg{:}); hg_bin = cat(1, hg_bin{:}); - + % [p_amp, h_amp] = ranksum(cat(1, zamp{1,:}), cat(1, zamp{2,:})); %% clrMap = lines(Nccond); @@ -973,7 +985,8 @@ countFigName = sprintf("Count distributions P%s", ... sprintf(" %.3f", p(:))); %% - saveFigure(behAreaFig, fullfile(behFigDir, biFN), true, true, owFlag ); - saveFigure(countFig, fullfile(behFigDir, countFigName), true, owFlag ); + arrayfun(@(f, fn) saveFigure(f, fullfile(behFig_path, fn), true, owFlag), ... + behAreaFig(:), biFN(:) ); + saveFigure(countFig, fullfile(behFig_path, countFigName), true, owFlag ); end end \ No newline at end of file From e92acb9ec96bdf022516acb2dafbb46348e709b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 09:15:26 +0100 Subject: [PATCH 148/201] Error validation --- James/script_learning_experiments.m | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index 1652b55..2da1a3d 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -44,7 +44,8 @@ pgObj.getFrequencyEdges(0.8); pgObj.pairStimulus(0.2); pgObj.saveConditions; - + + try [summStruct, behFig_path, behData, aInfo] = analyseBehaviour( ss_Path, ... "ConditionsNames", "Puff", ... "ResponseWindow", [25, 350] * 1e-3, ... @@ -52,6 +53,14 @@ "figOverWrite", false ); close all; + catch ME + disp( ME.message ) + disp( ME.identifier ) + disp( ME.cause ) + fprintf( 1, ['Debugging necessary perhaps?\n',... + 'Will continue with the loop...\n'] ) + summStruct.Results = NaN; + end end end r = ((x-1)*12)+(h+1); @@ -63,3 +72,5 @@ end end end + +save( fullfile( data_path, 'AmplitudeIndices.mat' ), 'ss_max', "ss_means" ) From ea25c2cf9e9f55d7154048960b52f2069570a569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 10:06:06 +0100 Subject: [PATCH 149/201] Nothing written in the matrix --- James/script_learning_experiments.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index 2da1a3d..9bd5fbd 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -50,7 +50,8 @@ "ConditionsNames", "Puff", ... "ResponseWindow", [25, 350] * 1e-3, ... "ViewingWindow", [-450, 500] * 1e-3, ... - "figOverWrite", false ); + "figOverWrite", false, ... + "showPlots", false ); close all; catch ME @@ -59,7 +60,7 @@ disp( ME.cause ) fprintf( 1, ['Debugging necessary perhaps?\n',... 'Will continue with the loop...\n'] ) - summStruct.Results = NaN; + continue; end end end From ac988f56e3f616c68570409d3d1c8ba090b044cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 10:44:51 +0100 Subject: [PATCH 150/201] HPC adaptation --- James/script_learning_experiments.m | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index 9bd5fbd..639f025 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -13,6 +13,17 @@ "m6"]; data_path = "Z:\James\Learning Experiments"; +% HPC snipet +if ~strcmp( computer, 'PCWIN64' ) + data_path = "/mnt/sds-hd/sd19b001/James/Learning Experiments"; + fnOpts = {'UniformOutput', false}; + + home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; + repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... + {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); + addpath( repo_paths{:} ) +end + ss_means = NaN(24,6,8); ss_max = NaN(6,8); @@ -36,7 +47,9 @@ fwrite( fID, [], 'int16' ); fclose(fID); - prepare64ChanBin4KS( ss_Path, 'BinFileName', sprintf("%s_%s_%s",mice_number(m),string(dt+h),daytime(x)), 'AllBinFiles', true ); + prepare64ChanBin4KS( ss_Path, 'BinFileName', ... + sprintf("%s_%s_%s",mice_number(m),string(dt+h),daytime(x)), ... + 'AllBinFiles', true, 'Overwrite', true ); pgObj = ProtocolGetter(ss_Path); pgObj.getConditionSignals; From 255bc7b868c2f5458e593402d008803c109cb774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 10:45:00 +0100 Subject: [PATCH 151/201] ctrl+i --- James/script_learning_experiments.m | 35 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index 639f025..008f5e6 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -1,15 +1,16 @@ %% Call function + dt= datetime(2024,11,25); dt.Format = 'dd-MM-yy'; daytime = ["AM","PM"]; -mice_number= ["m1", - "m2", - "m3", - "m4", - "m5", +mice_number= ["m1", ... + "m2", ... + "m3", ... + "m4", ... + "m5", ... "m6"]; data_path = "Z:\James\Learning Experiments"; @@ -32,8 +33,12 @@ for h = 0:11 for x = 1:2 for m = 1:6 - ss_Data = fullfile(data_path, sprintf("%s_%s\\%s\\%s",string(dt+h),daytime(x),mice_number(m),"Simple summary.mat")); - ss_Path = fullfile(data_path, sprintf("%s_%s\\%s",string(dt+h),daytime(x),mice_number(m))); + ss_Data = fullfile( data_path, ... + sprintf( "%s_%s", string(dt+h), daytime(x) ), ... + mice_number(m), "Simple summary.mat" ); + ss_Path = fullfile(data_path, ... + sprintf("%s_%s",string(dt+h),daytime(x)), ... + mice_number(m) ); try load(ss_Data) catch @@ -57,16 +62,16 @@ pgObj.getFrequencyEdges(0.8); pgObj.pairStimulus(0.2); pgObj.saveConditions; - + try - [summStruct, behFig_path, behData, aInfo] = analyseBehaviour( ss_Path, ... - "ConditionsNames", "Puff", ... - "ResponseWindow", [25, 350] * 1e-3, ... - "ViewingWindow", [-450, 500] * 1e-3, ... - "figOverWrite", false, ... - "showPlots", false ); + [summStruct, behFig_path, behData, aInfo] = analyseBehaviour( ss_Path, ... + "ConditionsNames", "Puff", ... + "ResponseWindow", [25, 350] * 1e-3, ... + "ViewingWindow", [-450, 500] * 1e-3, ... + "figOverWrite", false, ... + "showPlots", false ); - close all; + close all; catch ME disp( ME.message ) disp( ME.identifier ) From e9e0f9fb01da0e6f12023b19058f0b4a9f6e10d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 10:54:04 +0100 Subject: [PATCH 152/201] Added folders and subfolders to the path --- James/script_learning_experiments.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index 008f5e6..4ce4d9b 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -16,13 +16,12 @@ data_path = "Z:\James\Learning Experiments"; % HPC snipet if ~strcmp( computer, 'PCWIN64' ) - data_path = "/mnt/sds-hd/sd19b001/James/Learning Experiments"; fnOpts = {'UniformOutput', false}; - + unpackCell = @(x) {:}; home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); - addpath( repo_paths{:} ) + addpath( unpackCell( cellfun(@(x) genpath(x), repo_paths, fnOpts{:} ) ) ) end ss_means = NaN(24,6,8); From cdfbb08e2711432586be5605451f7a7d5b4e6039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 10:54:45 +0100 Subject: [PATCH 153/201] Little bug fix --- James/script_learning_experiments.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index 4ce4d9b..09c3f15 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -17,7 +17,7 @@ % HPC snipet if ~strcmp( computer, 'PCWIN64' ) fnOpts = {'UniformOutput', false}; - unpackCell = @(x) {:}; + unpackCell = @(x) x{:}; home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); From bed5209998c51aac9ad575e9d64f8ffc1b834315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 11:04:00 +0100 Subject: [PATCH 154/201] Perhaps working HPC snippet --- James/script_learning_experiments.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index 09c3f15..6799f97 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -16,12 +16,16 @@ data_path = "Z:\James\Learning Experiments"; % HPC snipet if ~strcmp( computer, 'PCWIN64' ) + fnOpts = {'UniformOutput', false}; unpackCell = @(x) x{:}; home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); - addpath( unpackCell( cellfun(@(x) genpath(x), repo_paths, fnOpts{:} ) ) ) + sf_repo_paths = cellfun(@(x) genpath(x), repo_paths, fnOpts{:} ); + addpath( sf_repo_paths{:} ); + data_path = '/mnt/sds-hd/sd19b001/James/Learning Experiments'; + end ss_means = NaN(24,6,8); From 7e3664f3f377e088a7168b1b2349a17b2054353c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 11:28:29 +0100 Subject: [PATCH 155/201] Fixed unreadable paths --- James/script_learning_experiments.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index 6799f97..fb285f8 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -2,7 +2,7 @@ dt= datetime(2024,11,25); -dt.Format = 'dd-MM-yy'; +dt.Format = 'd-MM-yy'; daytime = ["AM","PM"]; From 4471b27f8aa5fec5aeb3e46ce8c0e34302232db1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 24 Jan 2025 11:28:36 +0100 Subject: [PATCH 156/201] ctrl+i --- James/script_learning_experiments.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/James/script_learning_experiments.m b/James/script_learning_experiments.m index fb285f8..610f909 100644 --- a/James/script_learning_experiments.m +++ b/James/script_learning_experiments.m @@ -25,7 +25,7 @@ sf_repo_paths = cellfun(@(x) genpath(x), repo_paths, fnOpts{:} ); addpath( sf_repo_paths{:} ); data_path = '/mnt/sds-hd/sd19b001/James/Learning Experiments'; - + end ss_means = NaN(24,6,8); From 2293639b5b51b93d23d3d178dde2a710d0eee03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 7 Feb 2025 13:59:39 +0100 Subject: [PATCH 157/201] Create ephysVSai.m --- Emilio/ephysVSai.m | 284 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 Emilio/ephysVSai.m diff --git a/Emilio/ephysVSai.m b/Emilio/ephysVSai.m new file mode 100644 index 0000000..7f3335e --- /dev/null +++ b/Emilio/ephysVSai.m @@ -0,0 +1,284 @@ +fnOpts = {'UniformOutput', false}; +expandName = @(x) fullfile(x.folder, x.name); +animalPattern = '[a-zA-Z]+\d{1,}'; +rsOpts = {animalPattern, 'SearchType', 'expression'}; +ctOpts = {'IgnoreCase', true}; +lsOpts = {'L\d+.\d+', 'match'}; +ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; +cond_exp = {'^Delay\s\d[.]\d{3}\s\w\s[+]\sL[0-9.]', ... iRNs + '^Delay\s\d[.]\d{3}\s\w'}; % Continuous +cond_sel = 2; +tblOpts = {'VariableNames', {'Conditions', 'MI'}}; +my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +owfFlag = false; +m = 1e-3; k = 1e3; + +cellcat = @(x,d) cat( d, x{:} ); +tocol = @(x) x(:); +getMI = @(x,d) diff(x, 1, d) ./ ... + sum(x, d).*(sum(x,d)>0) + (1.*(sum(x,d)==0 | sum(x,d)< 1e-12)); +% total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); + +% exclude_names = {'GADi13', 'GADi15', 'GADi53'}; +exclude_names = { }; +vWin = [-300, 400]*m; +% iRN_mice = dir( "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch*\MC\GADi*" ); +iRN_mice = dir( "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch*\eOPN3\*" ); +iRN_mice = iRN_mice( ~cellfun('isempty', regexp({iRN_mice.name}, '^\w{2}\d{2}' ) ) ); +animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); +exclude_flags = contains( animalFolders, exclude_names ); +animalFolders = animalFolders( ~exclude_flags ); +%% +% asPaths = arrayfun(@(a) dir( fullfile( a, '*F*', 'ephys*', 'cluster_info.tsv' ) ), ... +% animalFolders, fnOpts{:} ); +asPaths = arrayfun(@(a) dir( fullfile( a, '*', 'ephys*', 'cluster_info.tsv' ) ), ... + animalFolders, fnOpts{:} ); +bad_flag = cellfun(@(x) contains( {x.folder}, 'bad' ), asPaths, fnOpts{:} ); +notF_flag = cellfun(@(x) contains( {x.folder}, 'f' ), asPaths, fnOpts{:} ); +asPaths = cellfun(@(a,f,w) a(~f&~w), asPaths, bad_flag, notF_flag, fnOpts{:} ); +empty_flag = cellfun('isempty', asPaths ); +asPaths = asPaths(~empty_flag); animalFolders = animalFolders(~empty_flag); +clInfo = cellfun(@(a) arrayfun(@(s) getClusterInfo( expandName( s ) ), ... + a, fnOpts{:} ), asPaths, fnOpts{:} ); + +%% +Nu = cellfun(@(x) cellfun(@(y) sum( y.ActiveUnit ), x ), clInfo, fnOpts{:} ); +low_unit_flag = cellfun(@(x) x < 10, Nu, fnOpts{:} ); +low_unit_animal = cellfun(@(x) all(x < 10), Nu ); +asPaths = cellfun(@(a,f) a(~f), asPaths, low_unit_flag , fnOpts{:} ); +animalFolders = animalFolders( ~low_unit_animal ); +clInfo = cellfun(@(a,f) a(~f), clInfo, low_unit_flag , fnOpts{:} ); +Nm = numel( clInfo ); +Nu = cellfun(@(a,f) a(~f), Nu, low_unit_flag , fnOpts{:} ); +% clInfo = arrayfun(@(x) getClusterInfo( expandName( ... +% dir( fullfile( x, '*F*', 'ephys*', 'cluster_info.tsv' ) ) ) ), animalFolders, ... +% fnOpts{:}); +%% Pooling ephys and behaviour +% Initialising +Nspm = cellfun("size", clInfo, 1 ); % Number of sessions per mouse +Nexp = sum( Nspm ); +Nu_all = cat( 1, Nu{:} ); +Nuinit = cumsum( [1; Nu_all(1:end-1) ] ); +Nuend = cumsum( Nu_all ); +PSTHall_mu = zeros( 700, sum( Nu_all ), 2 ); +brAll = []; +PSTHall = cell( Nexp, 2 ); +uSig = cell( Nexp, 1 ); uID = uSig; +uMod = uSig; +uMI = uSig; ce = 1; +%% +rstVars2load = {'relativeSpkTmsStruct', 'configStructure'}; +afVars2load = {'Conditions', 'fs'}; +for ca = 1:Nm + for cs = 1:Nspm(ca) + data_dir = string( getParentDir( asPaths{ca}(cs).folder, 1 ) ); + % condStruct = load( expandName( dir( fullfile( data_dir, "*\*analysis.mat" ) ) ), afVars2load{:} ); + rstPath = dir( fullfile( data_dir, "*", "*RW20.00-200.00*(unfiltered) RelSpkTms.mat" ) ); + brPath = dir( fullfile( data_dir, "*","BehaviourResult*.mat" ) ); + mfPath = dir( fullfile( data_dir, "ephys*", "Results", "Res VW* RW20.00-200.00 ms SW*PuffAll.mat") ); + brVars2load = 'behRes'; + if isempty( brPath ) + brPath = dir( fullfile( data_dir, "*\Simple summary.mat" ) ); + brVars2load = 'summStruct'; + end + brStruct = load( expandName( brPath ), brVars2load ); + behRes = brStruct.(brVars2load); + ctrlSub = ismember( string( {behRes.ConditionName} ), 'Control Puff' ); + % cf_flags = regexp( string( {behRes.ConditionName} ), {'Control Puff', ... + % 'Delay\s\d[.]\d{3}\s\w\s[+]\sL[0-9.]'} ); + % cf_flags = contains( string( {behRes.ConditionName} ), 'Control Puff'); + cf_flags = regexp( string( {behRes.ConditionName} ), ... + cond_exp{cond_sel} ); + cf_flags = ctrlSub | ~cellfun( 'isempty', cf_flags ); + + brAll = cat( 1, brAll, behRes(cf_flags) ); + if ~isempty(rstPath) || numel( rstPath ) == 1 + rstCont = load( expandName( rstPath ), rstVars2load{:} ); + else + fprintf(1, 'Either empty or more than 1 file found!\n'); + disp( {rstPath.name} ) + continue + end + mftype = 1; + mfVars2load = {'Results', 'gclID', 'Counts', 'configStructure'}; + if isempty( mfPath ) + fprintf( 1, 'Res file not found!\n') + mfPath = dir( fullfile( data_dir, "ephys*", "Results", "Map*.mat") ); + mfVars2load = {'keyCell', 'resMap'}; + if isempty( mfPath ) + fprintf( 1, 'Unable to load unit response information!\n') + disp( mfPath ) + continue + end + mftype = 2; + end + mfStruct = load( expandName( mfPath ), mfVars2load{:} ); + if mftype == 1 + Results = mfStruct.Results; + % Taking only control and laser frequency + cnfStruct = mfStruct.configStructure; + Nccond = numel( cnfStruct.ConsideredConditions ); + valid_cond_subs = 1:Nccond; + ctrlSub = ismember( cnfStruct.ConsideredConditions, 'Control Puff' ); + cf_flags = regexp( cnfStruct.ConsideredConditions, ... + cond_exp{cond_sel} ); + cf_flags = ctrlSub | ~cellfun( 'isempty', cf_flags ); + valid_cond_subs = valid_cond_subs( cf_flags ); + cmbSubs = cellcat(arrayfun(@(x) sscanf( x.Combination, '%d %d'), ... + Results , fnOpts{:} ), 2 ); + configFlag = cmbSubs(1,:) == cmbSubs(2,:) & ... + any(cmbSubs(1,:) == valid_cond_subs(:), 1); + cond_ordr = cmbSubs( 1, configFlag ); + gclID = mfStruct.gclID; + + Counts = mfStruct.Counts; + Counts = arrayfun(@(c) squeeze( mean( cellcat( Counts(c,:), 3 ), 2 ) ), ... + valid_cond_subs, fnOpts{:} ); + % configFlag = cellfun(@(x) ~isempty(x), regexp( {Results.Combination}, ... + % '1\s1\ssignrank', 'ignorecase' ) ); + sig_aux = arrayfun(@(x) x.Activity(1).Pvalues, Results(configFlag), fnOpts{:} ); + mod_aux = arrayfun(@(x) x.Activity(1).Direction, Results(configFlag), fnOpts{:} ); + mi_aux = cellfun(@(x) getMI( x, 2 ), Counts, fnOpts{:} ); + uSig{ce} = cellcat( sig_aux(cond_ordr), 2); + uMod{ce} = cellcat( mod_aux(cond_ordr), 2); + uMI{ce} = cellcat( mod_aux(cond_ordr), 2 ); + uID{ce} = gclID; + else + resMap = mfStruct.resMap; keyCell = mfStruct.keyCell; + configFlag = contains( keyCell(:,1), 'RW20.00-200.00' ) & ... + contains( keyCell(:,4), 'Control Puff' ); + if sum( configFlag ) ~= 1 + fprintf( 1, 'Cannot process this keycell... \n') + disp( keyCell ) + end + uSig{ce} = resMap( keyCell{configFlag,:} ); + uMod{ce} = zeros( Nu(ca), 1 ); uMI{ca} = uMod{ca}; + uID{ce} = clInfo{ca}{clInfo{ca}.ActiveUnit==1, "cluster_id" }; + end + rstStruct = rstCont.relativeSpkTmsStruct; + confStruct = rstCont.configStructure; + % Conditions = condStruct.Conditions; + % fs = condStruct.fs; + if any( confStruct.Viewing_window_s ~= vWin ) + confStruct.Viewing_window_s = vWin; + end + [PSTH, trial_tx, Na] = getPSTH_perU_perT( ... + rstStruct(valid_cond_subs), confStruct ); + a = Nuinit(ce); b = Nuend(ce); + idx = a:b; + PSTHall_mu(:,idx,:) = cellcat( cellfun(@(x) squeeze( mean( x, 1 ) ), ... + PSTH, fnOpts{:} ), 3 ); + PSTHall(ce,:) = PSTH; + ce = ce + 1; + end +end +clearvars PSTH brStruct ctrlSub rstStruct confStruct brPath brVars2load ... + rstCont a b idx; +ai_pt = arrayfun(@(s) getAIperTrial( s ), brAll, fnOpts{:} ); + +%% Sliding window analysis for behaviour correlation +% Idea is to slide a time window per unit per trial for getting an R² +slid_win_length = 20*m; time_slide = 5*m; +time_init = -50*m; time_stop = 400*m; +Nrs = (time_stop - time_init - slid_win_length) / time_slide; +r_squared = cell( Nexp, 1 ); +Nt = cellfun( "size", PSTHall, 1 ); +parfor cexp = 1:Nexp + r_squared{cexp} = zeros( Nu_all(cexp), Nrs, 2 ); + for cu = 1:Nu_all(cexp) + aux_rs = zeros(1, Nrs, 2 ); + for ct = 1:2 + cw = time_init + [0, slid_win_length]; + ci = 1; + aux_trial = cellcat( arrayfun(@(t) conv( PSTHall{cexp,ct}(t, :, cu ), ... + gausswin( 5 ), "same" ), 1:Nt(cexp,ct), 'UniformOutput', false ), 1 ); + while cw(2) <= time_stop + act_mu = mean( aux_trial(:, my_xor( trial_tx < cw ) ) , 2 ); + if ( sum( act_mu == 0 ) / numel(act_mu ) ) < 0.4 + aux_mdl = fitlm( zscore( act_mu )', zscore( ai_pt{cexp,ct} )', 'poly1' ); + aux_rs(1,ci,ct) = aux_mdl.Rsquared.Ordinary; + end + cw = cw + time_slide; ci = ci + 1; + end + end + r_squared{cexp}(cu,:,:) = aux_rs; + end +end +% r_squared_cat = cat( 1, r_squared{:} ); +%% Time resolved boxplots for all experiments +td = 30; +slid_win_length = td*m; time_slide = td*m; +time_init = -160*m; time_stop = 400*m; +Nrs = floor( (time_stop - time_init - slid_win_length) / time_slide ); +r_squared_pexp = zeros( Nexp, Nrs, 2 ); +parfor cexp = 1:Nexp + for ct = 1:2 + cw = time_init + [0, slid_win_length]; + for ci = 1:Nrs + act_mu = mean( PSTHall{cexp,ct}(:, my_xor( trial_tx < cw ),: ) , [2,3] ); + aux_mdl = fitlm( zscore( act_mu )', zscore( ai_pt{cexp,ct} )', 'poly1' ); + r_squared_pexp(cexp,ci,ct) = aux_mdl.Rsquared.Ordinary; + cw = cw + time_slide; + end + end +end +aux_mdl = fit_poly( [1,Nrs], [time_init, time_init + Nrs*slid_win_length] ... + + (slid_win_length/2)*[1,-1], 1 ); +b_tx = ( ( 1:Nrs )'.^[1,0] ) * aux_mdl; +% r_squared_cat = cat( 1, r_squared_pexp{:} ); +%% +bxOpts = {'JitterOutliers', 'on', 'MarkerStyle', '.', 'MarkerColor', 'k',... + 'BoxFaceColor', 'k', 'BoxWidth', k*(time_slide)/2, ... + 'Notch', 'off' }; +ttl = ["Laser OFF", "Laser ON"]; +f = figure('Color', 'w'); t = createtiles(f, 2, 2); +ax = gobjects( 3, 1 ); +for ct = 1:2 + ax(ct) = nexttile( t ); + boxchart(ax(ct), tocol( ones(Nexp,1)*b_tx' * k ), ... + tocol(r_squared_pexp(:,:,ct)), bxOpts{:} ) + hold( ax(ct), 'on'); + line(ax(ct), k*b_tx, median( r_squared_pexp(:,:,ct), 1 ), 'Color', 'k', ... + 'LineWidth', 2 ) + xline( ax(ct), [0,50,200], 'r--') + xlabel( ax(ct), 'Time [ms]' ) + xlim( ax(ct), k*(b_tx([1,end]) + [-1;1]*slid_win_length/2) ) + if ct ~=2 + ylabel( ax(ct), 'R² per window' ) + else + set( get( ax(ct), 'YAxis'), 'Visible', 'off' ) + end + cleanAxis( ax(ct) ); + title( ax(ct), ttl(ct) ) + +end +ct = ct + 1; +title( t, sprintf('Time-resolved_{%d ms} R² population (per experiment, eOPN3)', td ) ) +ax(ct) = nexttile( t, [1,2] ); +lObjs = line( ax(ct), b_tx*k, squeeze( median( r_squared_pexp, 1 ) ) ); +legend( lObjs, ttl, 'Color', 'none', 'Box', 'off', 'Location', 'best'); +xlabel( ax(ct), 'Time [ms]' ) +ylabel( ax(ct), 'R²' ) +ytickangle( ax, 90 ) +set( ax, 'TickDir', 'out' ) +linkaxes(ax, 'x'); linkaxes( ax(1:2), 'y' ) + +%% +% Comparing conditions agains each other +p_cond_per_window = arrayfun(@(x) signrank( ... + squeeze( r_squared_pexp(:,x,1) ), ... + squeeze( r_squared_pexp(:,x,2) ) ), ... + 1:Nrs ); +p_th = [0.05; 0.01; 0.001]; +astk = sum( p_cond_per_window < p_th ); +text( ax(ct), b_tx*k, max( median( r_squared_pexp ), [], 3 ) * 1.15, ... + cellfun(@(x) join(x), arrayfun(@(x) repmat( "\ast", 1, x ), astk, fnOpts{:} ) ), ... + "HorizontalAlignment", "center", "VerticalAlignment", "middle", "FontSize", 17 ) +%% Statistics on the time-resolved R² +tbl2 = cell(2, 1 ); +for ct = 1:2 + [p, tbl, stats] = kruskalwallis( squeeze(r_squared_pexp(:,:,ct) ), ... + string( b_tx(:) * k ) ); + figure; tbl2{ct} = multcompare( stats ); + sum( tbl2{ct}(:,end) < 0.05 ) +end From 1118c2a39419aff621f5e5a1feb9cda7d4f2b700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 7 Feb 2025 16:08:27 +0100 Subject: [PATCH 158/201] Bug fix for behaviour data folder --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 9e66d00..874bbb4 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -923,7 +923,7 @@ behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); - [behRes, behFig_path, behData, aInfo] = analyseBehaviour( beh_path, ... + [behRes, behFig_path, behData, aInfo] = analyseBehaviour( behDir, ... "Condition", possNames(behChCond), ... "ConditionsNames", cellstr( consCondNames ), ... "PairedFlags", delayFlags, ... From cebec3a2cb293f2b9171505d8248f4c1b88cc83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 13 Feb 2025 18:58:56 +0100 Subject: [PATCH 159/201] Adding laser ON reconstruction --- Emilio/poolEphBeh_regression.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 36277c8..a262729 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -108,8 +108,9 @@ SST = sum( (DX{1} - mean( DX{1}, 1 ) ).^2 ); r_sq = 1 - ( SSE./ SST ); - y_lpred = DX{3} * mdl_mu; - + y_lpred = reshape( DX{3} * mdl_mu, params.Nb, [], params.Ns ); + y_ltrials = reshape( DX{end}, params.Nb, [], params.Ns ); + rmse_laser = getRMSE( DX{4}, y_lpred, 1 ); dataTable = table( r_sq, {r_sq_trials}, {params.fit_error}, ... From a23f9e3ad7b5ed57d1363c082431d1a0f99829a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 13 Feb 2025 18:59:17 +0100 Subject: [PATCH 160/201] =?UTF-8?q?Needed=20for=20specifying=20R=C2=B2=20i?= =?UTF-8?q?n=20diff=20windows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Emilio/poolEphBeh_regression.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index a262729..b0ebac0 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -18,7 +18,10 @@ params = struct( 'relative_window', [-1,1]*800*m, 'delay_window', ... [-1,1]*100*m, 'bin_size', 5*m, 'kfold', 20 ); - +Nbins = diff(params.relative_window)/params.bin_size; +time_mdl = fit_poly( [1,Nbins], params.relative_window + ... + [1,-1]*(params.bin_size/2), 1 ); +tx = ( ( 1:Nbins)'.^[1,0] ) * time_mdl; pc = parcluster('local'); if ~strcmp( computer, 'PCWIN64') home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; From a4fd71d2d6f61c8109ddf8194349aaaab20f52fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 13 Feb 2025 18:59:37 +0100 Subject: [PATCH 161/201] Overwrite flag as part of the condition --- Jesus/DE_Jittering.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 874bbb4..270076e 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -613,6 +613,7 @@ 'normalization', 'fr'); lpFN = sprintf("Log-likePSTH %s %d-conditions NB%d",... logPSTH.Normalization, Nccond, Nbin); +%% Saving Log PSTH figures if Nccond > 1 lmiFN = sprintf("LogMI %d-conditions NB%d", Nccond, Nbin); lmiFP = fullfile(ephFigDir, lmiFN); @@ -624,7 +625,7 @@ end end lpFP = fullfile(ephFigDir, lpFN); -if ~exist(lpFP+".fig", "file") +if ~exist(lpFP+".fig", "file") || owFlag logFigs = plotLogPSTH(logPSTH); saveFigure(logFigs(1), lpFP, true, owFlag ) if numel(logFigs) > 1 popEffects = logFigs(2).UserData; @@ -648,7 +649,7 @@ logFigs(2) = openfig(lmiFP+".fig", ofgOpts{:} ); end end - +%% Save log MI results logRF = fullfile( ephFigDir, ... sprintf( "LogPSTH_Structure %s %d-conditions NB%d", ... logPSTH.Normalization, Nccond, Nbin ) ); From cd3345dd4d517c98a6c04090ce7a9b68a6223f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 14 Feb 2025 12:22:26 +0100 Subject: [PATCH 162/201] =?UTF-8?q?Added=20R=C2=B2=20for=20Laser=20ON=20tr?= =?UTF-8?q?ials?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Emilio/poolEphBeh_regression.m | 39 +++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index b0ebac0..17fd3af 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -22,6 +22,9 @@ time_mdl = fit_poly( [1,Nbins], params.relative_window + ... [1,-1]*(params.bin_size/2), 1 ); tx = ( ( 1:Nbins)'.^[1,0] ) * time_mdl; +sponFlags = tx < 0; +getTimeBoAT = @(s,f,p) reshape( s(f,:,:), size(s,2) * sum( f ), p.Ns ); + pc = parcluster('local'); if ~strcmp( computer, 'PCWIN64') home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; @@ -98,26 +101,42 @@ any( cellfun(@isempty, DX) ) continue end + %% mdl_mu = squeeze( mean( mdl, 2 ) ); y_trials = reshape( DX{1}, params.Nb, params.Nr, params.Ns ); y_pred = DX{2} * mdl_mu; y_ptrials = reshape( y_pred, params.Nb, params.Nr, params.Ns ); + + r_sq_trials = goodnessFit2( y_trials, y_ptrials, 1 ); + r_sq = goodnessFit2( DX{1}, y_pred, 1 ); + + y_trials_pre = getTimeBoAT(y_trials, sponFlags, params); + y_ptrials_pre = getTimeBoAT(y_ptrials, sponFlags, params); + r_sq_pre = goodnessFit2(y_trials_pre, y_ptrials_pre, 1); - SSEt = squeeze( sum( ( y_trials - y_ptrials ).^2, 1 ) ); - SSTt = squeeze( sum( ( y_trials - mean( y_trials, 1 ) ).^2, 1 ) ); - r_sq_trials = 1 - (SSEt./SSTt); + y_trials_post = getTimeBoAT( y_trials, ~sponFlags, params ); + y_ptrials_post = getTimeBoAT( y_ptrials, ~sponFlags, params ); + r_sq_post = goodnessFit2(y_trials_post, y_ptrials_post, 1); + + y_lpred = DX{3} * mdl_mu; + y_lptrials = reshape( y_lpred, params.Nb, [], params.Ns ); + y_ltrials = reshape( DX{4}, size( y_lptrials ) ); + + r_sq_l = goodnessFit2( DX{4}, y_lpred, 1 ); - SSE = sum( (DX{1} - y_pred).^2 ); - SST = sum( (DX{1} - mean( DX{1}, 1 ) ).^2 ); - r_sq = 1 - ( SSE./ SST ); + y_trials_pre = getTimeBoAT(y_ltrials, sponFlags, params); + y_ptrials_pre = getTimeBoAT(y_lptrials, sponFlags, params); + r_sq_lpre = goodnessFit2(y_trials_pre, y_ptrials_pre, 1); - y_lpred = reshape( DX{3} * mdl_mu, params.Nb, [], params.Ns ); - y_ltrials = reshape( DX{end}, params.Nb, [], params.Ns ); + y_trials_post = getTimeBoAT( y_ltrials, ~sponFlags, params ); + y_ptrials_post = getTimeBoAT( y_lptrials, ~sponFlags, params ); + r_sq_lpost = goodnessFit2(y_trials_post, y_ptrials_post, 1); rmse_laser = getRMSE( DX{4}, y_lpred, 1 ); - dataTable = table( r_sq, {r_sq_trials}, {params.fit_error}, ... - rmse_laser, 'VariableNames', {'R_squared', 'R_squared_trials', ... + dataTable = table( {[r_sq;r_sq_pre;r_sq_post],[r_sq_l;r_sq_lpre;r_sq_post]}, ... + {r_sq_trials}, {params.fit_error}, ... + rmse_laser, 'VariableNames', {'R_2_p_L', 'R_squared_trials', ... 'RMSE_c', 'RMSE_l'} ); if ( string(oldSess) ~= string(currSess) ) || ... ( string(oldDepth) ~= string(depthSess) ) From f119e5826343bf3a27f3f9a83aad6b90ab522db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 14 Feb 2025 12:39:02 +0100 Subject: [PATCH 163/201] Create helix_BehReconstruct.sh --- Emilio/helix_BehReconstruct.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Emilio/helix_BehReconstruct.sh diff --git a/Emilio/helix_BehReconstruct.sh b/Emilio/helix_BehReconstruct.sh new file mode 100644 index 0000000..ebad542 --- /dev/null +++ b/Emilio/helix_BehReconstruct.sh @@ -0,0 +1,9 @@ +#!/bin/bash +#SBATCH --partition=cpu-single +#SBATCH --ntasks=32 +#SBATCH --time=24:00:00 +#SBATCH --mem=128gb + +module load math/matlab/R2023a + +matlab -nodisplay -r poolEphBeh_regression > results.out 2>&1 \ No newline at end of file From bb30da7b96101da105802b6e08a85d02d4a5d0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 14 Feb 2025 12:40:05 +0100 Subject: [PATCH 164/201] Update poolEphBeh_regression.m --- Emilio/poolEphBeh_regression.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 17fd3af..3c69aea 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -157,7 +157,7 @@ end mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; -behFP = fullfile( roller_path, "MCiRNs_regression_sm.mat" ); +behFP = fullfile( roller_path, "MCiRNs_reconstruction_sm.mat" ); svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From db302bb9b2340d4379d305fa4e2f151c14671f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 14 Feb 2025 12:42:06 +0100 Subject: [PATCH 165/201] Logical bug for HPC --- Emilio/poolEphBeh_regression.m | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 3c69aea..c684144 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -16,6 +16,16 @@ m = 1e-3; exclude_names = {'GADi13', 'GADi15', 'GADi53'}; +if ~strcmp( computer, 'PCWIN64') + home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; + repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... + {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); + cellfun(@(x) addpath( genpath( x ) ), repo_paths ) + roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; +else + roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; +end + params = struct( 'relative_window', [-1,1]*800*m, 'delay_window', ... [-1,1]*100*m, 'bin_size', 5*m, 'kfold', 20 ); Nbins = diff(params.relative_window)/params.bin_size; @@ -26,15 +36,7 @@ getTimeBoAT = @(s,f,p) reshape( s(f,:,:), size(s,2) * sum( f ), p.Ns ); pc = parcluster('local'); -if ~strcmp( computer, 'PCWIN64') - home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; - repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... - {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); - cellfun(@(x) addpath( genpath( x ) ), repo_paths ) - roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; -else - roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; -end + try parpool( pc ); catch From da6686ba7e142fd78249826e03d2fd0e34fd74a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 14 Feb 2025 14:57:56 +0100 Subject: [PATCH 166/201] Renamed Figure5A to FigureReconsA --- Emilio/{Figure5A.m => FigureReconsA.m} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Emilio/{Figure5A.m => FigureReconsA.m} (100%) diff --git a/Emilio/Figure5A.m b/Emilio/FigureReconsA.m similarity index 100% rename from Emilio/Figure5A.m rename to Emilio/FigureReconsA.m From 9ea2282b03dcc993c5fb3ae629dcdc04fed2adbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 14 Feb 2025 14:58:00 +0100 Subject: [PATCH 167/201] Create compareR2_preVSpost_reconstruction.m --- Emilio/compareR2_preVSpost_reconstruction.m | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Emilio/compareR2_preVSpost_reconstruction.m diff --git a/Emilio/compareR2_preVSpost_reconstruction.m b/Emilio/compareR2_preVSpost_reconstruction.m new file mode 100644 index 0000000..f952923 --- /dev/null +++ b/Emilio/compareR2_preVSpost_reconstruction.m @@ -0,0 +1,22 @@ +mice_results = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs"; +load( fullfile( mice_results, 'iRNs\MCiRNs_reconstruction_sm.mat') ) + +Nm = numel( mice ); % Numer of mice +Nspm = arrayfun(@(x) numel( x.Sessions ), mice ); % Number of sessions per mouse +Nexp = sum( Nspm ); +r2_res_c = zeros( 3, 8, Nexp ); +r2_res_l = zeros( 3, 8, Nexp ); +ce = 1; +mouseID = zeros( Nexp, 1 ); +sessID = zeros( Nexp, 1 ); +for cm = 1:Nm + for cs = 1:Nspm(cm) + dt = mice(cm).Sessions(cs).DataTable; + r2 = dt.R_2_p_L; + r2_res_c(:,:,ce) = r2{1}; + r2_res_l(:,:,ce) = r2{2}; + mouseID(ce) = cm; + sessID(ce) = cs; + ce = ce + 1; + end +end \ No newline at end of file From 52046d8461a88e4469895ca26d18356717398d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 14 Feb 2025 18:44:44 +0100 Subject: [PATCH 168/201] Plotting results --- Emilio/compareR2_preVSpost_reconstruction.m | 52 ++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/Emilio/compareR2_preVSpost_reconstruction.m b/Emilio/compareR2_preVSpost_reconstruction.m index f952923..57a7193 100644 --- a/Emilio/compareR2_preVSpost_reconstruction.m +++ b/Emilio/compareR2_preVSpost_reconstruction.m @@ -1,5 +1,11 @@ +%% mice_results = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs"; +pool_fig_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs\iRNs"; + load( fullfile( mice_results, 'iRNs\MCiRNs_reconstruction_sm.mat') ) +bp_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... + "Nonstim-whisker mean", "Nonstim-whisker fan arc", ... + "Interwhisker arc", "Symmetry", "Nose", "Roller speed"]; Nm = numel( mice ); % Numer of mice Nspm = arrayfun(@(x) numel( x.Sessions ), mice ); % Number of sessions per mouse @@ -19,4 +25,48 @@ sessID(ce) = cs; ce = ce + 1; end -end \ No newline at end of file +end +[Nep, Ns] = size( r2_res_c, [1,2] ); + +%% +fnOpts = {'UniformOutput', false}; +tocol = @(x) x(:); +r2_mean_c = cellcat( arrayfun(@(x) mean( r2_res_c(:,:,mouseID==x), 3 ), ... + 1:Nm, fnOpts{:} ), 3 ); +r2_mean_l = cellcat( arrayfun(@(x) mean( r2_res_l(:,:,mouseID==x), 3 ), ... + 1:Nm, fnOpts{:} ), 3 ); +f = figure("Color", "w"); t = createtiles( f, 1, 1); +ax = nexttile( t ); +bpID = repmat( ones( Nep, 1 ) * (1:Ns), 1, 1, Nm); +preVSpostID = repmat( (1:Nep)' * ones( 1, Ns ), 1, 1, Nm ); +boxchart( ax, bpID(:), tocol( r2_mean_c ), 'GroupByColor', preVSpostID(:), ... + 'Notch', 'on' ) +xline( ax, (1:Ns-1) + 1/2, '--', 'Color', 0.45*ones(1,3) ); +legend( {'Overall', 'Pre', 'Post'}, "Box", "off", "Color", "none", ... + "Location", "best", "AutoUpdate", "off" ) +cleanAxis( ax ); ytickangle( ax, 90 ); set( ax, 'TickDir', 'out' ); +ylabel( ax, 'R²' ) +xticks( ax, 1:Ns ); xticklabels( ax, bp_names ); +xlim( ax, [1,Ns] + [-1,1]/2 ); +ylim( ax, [0, 1] ) +set( f, 'UserData', {r2_mean_c, bpID, preVSpostID, mouseID, sessID} ) +title( ax, 'Reconstruction R² for overall, pre-, and post-stimulus' ) + +%% +p = arrayfun(@(x) signrank( squeeze( r2_mean_c(2,x,:) ), ... + squeeze( r2_mean_c(3,x,:) ) ), 1:Ns ); +fnOpts = {'UniformOutput', false}; +txOpts = {'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom'}; +astk = sum( p < [0.05, 0.01, 0.001]' ); +x = (1:Ns) + [0;1]/3; +y = [1;1] * max( r2_mean_c(2:3,:,:), [], [3,1] ) * 1.05; +line( ax, x, y, 'Color', 'k' ) +txt = [arrayfun( @(a) replace( join( repmat("\ast", 1, a) ), " ", "" ), astk, fnOpts{:} ); +arrayfun(@(h) sprintf( "$p=%.3f$", h) , p)]; +%txt = arrayfun(@(s) replace( join( txt(:,s) ), " ", ""), 1:Ns ); +text( ax, mean( x, 1 ), y(1,:)+0.035, txt(1,:), txOpts{:}, "FontSize", 10 ) +text( ax, mean( x, 1 ), y(1,:), txt(2,:), txOpts{:}, "FontSize", 8, ... + "Interpreter", "latex" ) +%% +saveFigure( f, fullfile( pool_fig_path, ... + "Reconstruction R² overall, pre and post" ), true, true ) \ No newline at end of file From 14ef5b16610585437b5574adb8fcb2bfb7560deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 20 Feb 2025 17:27:43 +0100 Subject: [PATCH 169/201] ctrl + i --- Jesus/DE_Jittering.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 270076e..4faeb06 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -49,9 +49,9 @@ % Total duration of the recording Nt = Ns/fs; % Useless clusters (labeled as noise or they have very low firing rate) - badsIdx = cellfun(@(x) x==3,sortedData(:,3)); + badsIdx = cellfun(@(x) x==3, sortedData(:,3) ); bads = find(badsIdx); - totSpkCount = cellfun(@numel,sortedData(:,2)); + totSpkCount = cellfun( @numel, sortedData(:,2) ); clusterSpikeRate = totSpkCount/Nt; silentUnits = clusterSpikeRate < 0.1; bads = union(bads,find(silentUnits)); From 4d59b8cca64f433daf52f98196af1ed4b74baa7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 20 Feb 2025 17:28:20 +0100 Subject: [PATCH 170/201] A bit of flexibility for pool regression --- Emilio/poolEphBeh_regression.m | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index c684144..7a91a35 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -42,7 +42,12 @@ catch end -iRN_mice = dir( fullfile( roller_path, "Batch*", "MC", "GADi*" ) ); +struct_search = "eOPN3"; % or "MC" +selCondition = "cont"; % or "freq" Continuous or frquency +verb = true; % verbose +iRN_mice = dir( fullfile( roller_path, "Batch*.MC", struct_search, "*" ) ); +iRN_mice = iRN_mice( [iRN_mice.isdir] & ... + ~arrayfun(@(x) any( ismember({'.','..'}, x.name ) ), iRN_mice )' ); animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); exclude_flags = contains( animalFolders, exclude_names ); %% Looping animals @@ -94,7 +99,8 @@ data_path = curDir; fprintf(1, ', Session %s\n', currSess ) try - [mdl, params, DX] = regressEphysVSBehaviour( data_path, params ); + [mdl, params, DX] = regressEphysVSBehaviour( data_path, params, ... + 'Condition', selCondition, 'Verbose', verb ); catch ME display(ME.message) continue @@ -159,7 +165,7 @@ end mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; -behFP = fullfile( roller_path, "MCiRNs_reconstruction_sm.mat" ); +behFP = fullfile( roller_path, struct_search + "iRNs_reconstruction_sm.mat" ); svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From c54fc753ffe88fab64ffae961e23e4358f7de11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 21 Feb 2025 18:22:32 +0100 Subject: [PATCH 171/201] Reconstructing BC-iRNs --- Emilio/poolEphBeh_regression.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 7a91a35..f54fc68 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -42,10 +42,11 @@ catch end -struct_search = "eOPN3"; % or "MC" -selCondition = "cont"; % or "freq" Continuous or frquency +struct_search = "BC"; % or "MC" "eOPN3" "ChR2" +selCondition = "freq"; % or "freq" "cont" Continuous or frquency +extra_id = "iRNs"; verb = true; % verbose -iRN_mice = dir( fullfile( roller_path, "Batch*.MC", struct_search, "*" ) ); +iRN_mice = dir( fullfile( roller_path, "Batch*", struct_search, "GADi*" ) ); iRN_mice = iRN_mice( [iRN_mice.isdir] & ... ~arrayfun(@(x) any( ismember({'.','..'}, x.name ) ), iRN_mice )' ); animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); @@ -165,7 +166,8 @@ end mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; -behFP = fullfile( roller_path, struct_search + "iRNs_reconstruction_sm.mat" ); +behFP = fullfile( roller_path, struct_search + extra_id + ... + "_reconstruction_sm.mat" ); svOpts = {'-mat'}; if exist(behFP, "file") svOpts = {'-append'}; From d60f76c267f368b024d183e19d0b1da2193c960e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 21 Feb 2025 18:50:33 +0100 Subject: [PATCH 172/201] Removing empty delay membership --- Jesus/DE_Jittering.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 4faeb06..32cd5e5 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -923,7 +923,7 @@ hstOpts = {'BinMethod', 'integers', 'BinLimits', [-0.5,4.5]}; behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); - + delayFlags( all(~delayFlags, 2), : ) = []; [behRes, behFig_path, behData, aInfo] = analyseBehaviour( behDir, ... "Condition", possNames(behChCond), ... "ConditionsNames", cellstr( consCondNames ), ... From df7aecafb0b568300f707e9b76309355f9cfb81c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 26 Feb 2025 20:50:19 +0100 Subject: [PATCH 173/201] Removed useless plots --- Jesus/DE_Jittering.m | 68 ++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 32cd5e5..47cb8c9 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -948,46 +948,46 @@ biFN = arrayfun(@(s) sprintf( biFigPttrn(s), pAreas(:,s) ), 1:numel(behMeasures) ); - trMvFlag = arrayfun(@(cr) behRes(1).Results(cr).MovStrucure.MovmentFlags, ... - 1:size(behRes(1).Results,2), fnOpts{:}); trMvFlag = cat(3, trMvFlag{:}); - BIscaleMat = sum(trMvFlag,3); - BIscale = arrayfun(@(cc) BIscaleMat(delayFlags(:,cc), cc), 1:Nccond, ... - fnOpts{:}); - [hg, hg_bin] = cellfun(@(c) histcounts(c, hstOpts{:}), ... - BIscale, fnOpts{:}); - hg = cat(1, hg{:}); hg_bin = cat(1, hg_bin{:}); + % trMvFlag = arrayfun(@(cr) behRes(1).Results(cr).MovStrucure.MovmentFlags, ... + % 1:size(behRes(1).Results,2), fnOpts{:}); trMvFlag = cat(3, trMvFlag{:}); + % BIscaleMat = sum(trMvFlag,3); + % BIscale = arrayfun(@(cc) BIscaleMat(delayFlags(:,cc), cc), 1:Nccond, ... + % fnOpts{:}); + % [hg, hg_bin] = cellfun(@(c) histcounts(c, hstOpts{:}), ... + % BIscale, fnOpts{:}); + % hg = cat(1, hg{:}); hg_bin = cat(1, hg_bin{:}); % [p_amp, h_amp] = ranksum(cat(1, zamp{1,:}), cat(1, zamp{2,:})); %% - clrMap = lines(Nccond); - countFig = figure( figOpts{:} ); ax(1) = subplot(10,1,1:8); - bar(ax(1), (0:4)', (hg./sum(hg,2))', 'EdgeColor', 'none'); hold on; - poaDist = cellfun(@(bi) fitdist(bi,"Poisson"), BIscale); - ylim(ax(1), [0,1]); set(ax(1), axOpts{:}); - legend(ax(1), consCondNames, 'AutoUpdate','off', lgOpts{:}) - lmbdaHeight = 0.95-(0.15/Nccond)*(0:Nccond-1); - arrayfun(@(pd) scatter(ax(1), poaDist(pd).lambda, lmbdaHeight(pd), '|',... - 'MarkerEdgeColor', clrMap(pd,:)), 1:Nccond) - arrayfun(@(pd) line(ax(1), paramci(poaDist(pd)), ... - lmbdaHeight([pd,pd]), 'Color', clrMap(pd,:), ... - 'Marker', '|'), 1:Nccond) - [p, chiVal] = arrayfun(@(ps) chi2test(hg(prmSubs(ps,:), :)), ... - 1:size(prmSubs,1)); - ax(2) = subplot(10,1,9:10); - signBeh = arrayfun(@(x) sprintf("%s vs %s p=%.3f", ... - consCondNames(prmSubs(x,:)), p(x)), 1:size(prmSubs,1)); - text(ax(2), 0, -0.3, sprintf('%s vs. %s P=%.3f\n', ... - [consCondNames(prmSubs), string(p(:))]')) - set(ax(2), 'Visible', 'off') - set(countFig, 'UserData', {signBeh, p}) - title(ax(1), strrep(expName, '_',' ')); xlabel(ax(1),'Moving body parts') - ylabel(ax(1),'Trial proportion') - countFigName = sprintf("Count distributions P%s", ... - sprintf(" %.3f", p(:))); + % clrMap = lines(Nccond); + % countFig = figure( figOpts{:} ); ax(1) = subplot(10,1,1:8); + % bar(ax(1), (0:4)', (hg./sum(hg,2))', 'EdgeColor', 'none'); hold on; + % poaDist = cellfun(@(bi) fitdist(bi,"Poisson"), BIscale); + % ylim(ax(1), [0,1]); set(ax(1), axOpts{:}); + % legend(ax(1), consCondNames, 'AutoUpdate','off', lgOpts{:}) + % lmbdaHeight = 0.95-(0.15/Nccond)*(0:Nccond-1); + % arrayfun(@(pd) scatter(ax(1), poaDist(pd).lambda, lmbdaHeight(pd), '|',... + % 'MarkerEdgeColor', clrMap(pd,:)), 1:Nccond) + % arrayfun(@(pd) line(ax(1), paramci(poaDist(pd)), ... + % lmbdaHeight([pd,pd]), 'Color', clrMap(pd,:), ... + % 'Marker', '|'), 1:Nccond) + % [p, chiVal] = arrayfun(@(ps) chi2test(hg(prmSubs(ps,:), :)), ... + % 1:size(prmSubs,1)); + % ax(2) = subplot(10,1,9:10); + % signBeh = arrayfun(@(x) sprintf("%s vs %s p=%.3f", ... + % consCondNames(prmSubs(x,:)), p(x)), 1:size(prmSubs,1)); + % text(ax(2), 0, -0.3, sprintf('%s vs. %s P=%.3f\n', ... + % [consCondNames(prmSubs), string(p(:))]')) + % set(ax(2), 'Visible', 'off') + % set(countFig, 'UserData', {signBeh, p}) + % title(ax(1), strrep(expName, '_',' ')); xlabel(ax(1),'Moving body parts') + % ylabel(ax(1),'Trial proportion') + % countFigName = sprintf("Count distributions P%s", ... + % sprintf(" %.3f", p(:))); %% arrayfun(@(f, fn) saveFigure(f, fullfile(behFig_path, fn), true, owFlag), ... behAreaFig(:), biFN(:) ); - saveFigure(countFig, fullfile(behFig_path, countFigName), true, owFlag ); + % saveFigure(countFig, fullfile(behFig_path, countFigName), true, owFlag ); end end \ No newline at end of file From 4e28781ecad141139e411cd5da19f27e981ca9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 26 Feb 2025 20:50:49 +0100 Subject: [PATCH 174/201] Fixing inconsistencies with arduino triggers --- Jesus/DE_Jittering.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 47cb8c9..49f027d 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -923,7 +923,9 @@ hstOpts = {'BinMethod', 'integers', 'BinLimits', [-0.5,4.5]}; behChCond = cellfun(@(x) contains(Conditions(chCond).name, x), ... {["Piezo", "Puff"];["Laser","Light"]}); - delayFlags( all(~delayFlags, 2), : ) = []; + delayFlags = arrayfun(@(x) any( Conditions(chCond).Triggers(:,1) == ... + Conditions(x).Triggers(:,1)', 2 ), consCondSubs, fnOpts{:} ); + delayFlags = cat(2, delayFlags{:}); [behRes, behFig_path, behData, aInfo] = analyseBehaviour( behDir, ... "Condition", possNames(behChCond), ... "ConditionsNames", cellstr( consCondNames ), ... From 2959ce65a9b85a8b2baaaf15be8175c8f180bcdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 26 Feb 2025 20:51:08 +0100 Subject: [PATCH 175/201] Plot laser ON conditions --- Emilio/compareR2_preVSpost_reconstruction.m | 91 +++++++++++++++++---- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/Emilio/compareR2_preVSpost_reconstruction.m b/Emilio/compareR2_preVSpost_reconstruction.m index 57a7193..4d71f2c 100644 --- a/Emilio/compareR2_preVSpost_reconstruction.m +++ b/Emilio/compareR2_preVSpost_reconstruction.m @@ -1,12 +1,18 @@ %% -mice_results = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs"; -pool_fig_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs\iRNs"; - -load( fullfile( mice_results, 'iRNs\MCiRNs_reconstruction_sm.mat') ) +expandName = @(x) fullfile( x.folder, x.name ); +% mice_results = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs"; +mice_results = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\BC-igRNs"; +% pool_fig_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs\iRNs"; +pool_fig_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\BC-igRNs"; +r2_fp = dir( fullfile( mice_results,'*_reconstruction_sm.mat') ); +load( expandName( r2_fp ), 'mice' ) +%% +cellcat = @(x,d) cat( d, x{:} ); bp_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... "Nonstim-whisker mean", "Nonstim-whisker fan arc", ... "Interwhisker arc", "Symmetry", "Nose", "Roller speed"]; +%% Nm = numel( mice ); % Numer of mice Nspm = arrayfun(@(x) numel( x.Sessions ), mice ); % Number of sessions per mouse Nexp = sum( Nspm ); @@ -29,20 +35,27 @@ [Nep, Ns] = size( r2_res_c, [1,2] ); %% -fnOpts = {'UniformOutput', false}; +% fnOpts = {'UniformOutput', false}; tocol = @(x) x(:); -r2_mean_c = cellcat( arrayfun(@(x) mean( r2_res_c(:,:,mouseID==x), 3 ), ... - 1:Nm, fnOpts{:} ), 3 ); -r2_mean_l = cellcat( arrayfun(@(x) mean( r2_res_l(:,:,mouseID==x), 3 ), ... - 1:Nm, fnOpts{:} ), 3 ); +% r2_mean_c = cellcat( arrayfun(@(x) mean( r2_res_c(:,:,mouseID==x), 3 ), ... +% 1:Nm, fnOpts{:} ), 3 ); +% r2_mean_l = cellcat( arrayfun(@(x) mean( r2_res_l(:,:,mouseID==x), 3 ), ... +% 1:Nm, fnOpts{:} ), 3 ); +r2_mean_c = r2_res_c; r2_mean_l = r2_res_l; f = figure("Color", "w"); t = createtiles( f, 1, 1); ax = nexttile( t ); -bpID = repmat( ones( Nep, 1 ) * (1:Ns), 1, 1, Nm); -preVSpostID = repmat( (1:Nep)' * ones( 1, Ns ), 1, 1, Nm ); -boxchart( ax, bpID(:), tocol( r2_mean_c ), 'GroupByColor', preVSpostID(:), ... - 'Notch', 'on' ) +% bpID = repmat( ones( Nep, 1 ) * (1:Ns), 1, 1, Nm); +% preVSpostID = repmat( (1:Nep)' * ones( 1, Ns ), 1, 1, Nm ); +bpID = repmat( ones( Nep-1, 1 ) * (1:Ns), 1, 1, Nexp ); +preVSpostID = repmat( (1:Nep-1)' * ones( 1, Ns ), 1, 1, Nexp ); +% boxchart( ax, bpID(:), tocol( r2_mean_c ), 'GroupByColor', preVSpostID(:), ... +% 'Notch', 'on' ) +boxchart( ax, bpID(:), tocol( r2_mean_c(2:3,:,:) ), ... + 'GroupByColor', preVSpostID(:), 'Notch', 'on' ) xline( ax, (1:Ns-1) + 1/2, '--', 'Color', 0.45*ones(1,3) ); -legend( {'Overall', 'Pre', 'Post'}, "Box", "off", "Color", "none", ... +% legend( {'Overall', 'Pre', 'Post'}, "Box", "off", "Color", "none", ... +% "Location", "best", "AutoUpdate", "off" ) +legend( {'Pre', 'Post'}, "Box", "off", "Color", "none", ... "Location", "best", "AutoUpdate", "off" ) cleanAxis( ax ); ytickangle( ax, 90 ); set( ax, 'TickDir', 'out' ); ylabel( ax, 'R²' ) @@ -58,7 +71,7 @@ fnOpts = {'UniformOutput', false}; txOpts = {'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom'}; astk = sum( p < [0.05, 0.01, 0.001]' ); -x = (1:Ns) + [0;1]/3; +x = (1:Ns) + [-1;1]/4; y = [1;1] * max( r2_mean_c(2:3,:,:), [], [3,1] ) * 1.05; line( ax, x, y, 'Color', 'k' ) txt = [arrayfun( @(a) replace( join( repmat("\ast", 1, a) ), " ", "" ), astk, fnOpts{:} ); @@ -69,4 +82,50 @@ "Interpreter", "latex" ) %% saveFigure( f, fullfile( pool_fig_path, ... - "Reconstruction R² overall, pre and post" ), true, true ) \ No newline at end of file + "Reconstruction R² overall, pre and post" ), true, true ) + +%% +% fnOpts = {'UniformOutput', false}; +tocol = @(x) x(:); +% r2_mean_c = cellcat( arrayfun(@(x) mean( r2_res_c(:,:,mouseID==x), 3 ), ... +% 1:Nm, fnOpts{:} ), 3 ); +% r2_mean_l = cellcat( arrayfun(@(x) mean( r2_res_l(:,:,mouseID==x), 3 ), ... +% 1:Nm, fnOpts{:} ), 3 ); +% r2_mean_c = r2_res_c; r2_mean_l = r2_res_l; +f = figure("Color", "w"); t = createtiles( f, 1, 1); +ax = nexttile( t ); +% bpID = repmat( ones( Nep, 1 ) * (1:Ns), 1, 1, Nm); +% preVSpostID = repmat( (1:Nep)' * ones( 1, Ns ), 1, 1, Nm ); +bpID = repmat( ones( Nep-1, 1 ) * (1:Ns), 1, 1, Nexp ); +preVSpostID = repmat( (1:Nep-1)' * ones( 1, Ns ), 1, 1, Nexp ); +% boxchart( ax, bpID(:), tocol( r2_mean_c ), 'GroupByColor', preVSpostID(:), ... +% 'Notch', 'on' ) +boxchart( ax, bpID(:), tocol( r2_mean_l(2:3,:,:) ), ... + 'GroupByColor', preVSpostID(:), 'Notch', 'on' ) +xline( ax, (1:Ns-1) + 1/2, '--', 'Color', 0.45*ones(1,3) ); +% legend( {'Overall', 'Pre', 'Post'}, "Box", "off", "Color", "none", ... +% "Location", "best", "AutoUpdate", "off" ) +legend( {'Pre', 'Post'}, "Box", "off", "Color", "none", ... + "Location", "best", "AutoUpdate", "off" ) +cleanAxis( ax ); ytickangle( ax, 90 ); set( ax, 'TickDir', 'out' ); +ylabel( ax, 'R²' ) +xticks( ax, 1:Ns ); xticklabels( ax, bp_names ); +xlim( ax, [1,Ns] + [-1,1]/2 ); +ylim( ax, [0, 1] ) +set( f, 'UserData', {r2_mean_l, bpID, preVSpostID, mouseID, sessID} ) +title( ax, 'Reconstruction R² for overall, pre-, and post-stimulus' ) +%% +p = arrayfun(@(x) signrank( squeeze( r2_mean_l(2,x,:) ), ... + squeeze( r2_mean_l(3,x,:) ) ), 1:Ns ); +fnOpts = {'UniformOutput', false}; +txOpts = {'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom'}; +astk = sum( p < [0.05, 0.01, 0.001]' ); +x = (1:Ns) + [-1;1]/4; +y = [1;1] * max( r2_mean_l(2:3,:,:), [], [3,1] ) * 1.05; +line( ax, x, y, 'Color', 'k' ) +txt = [arrayfun( @(a) replace( join( repmat("\ast", 1, a) ), " ", "" ), astk, fnOpts{:} ); +arrayfun(@(h) sprintf( "$p=%.3f$", h) , p)]; +%txt = arrayfun(@(s) replace( join( txt(:,s) ), " ", ""), 1:Ns ); +text( ax, mean( x, 1 ), y(1,:)+0.035, txt(1,:), txOpts{:}, "FontSize", 10 ) +text( ax, mean( x, 1 ), y(1,:), txt(2,:), txOpts{:}, "FontSize", 8, ... + "Interpreter", "latex" ) \ No newline at end of file From d348ef808bdcf45b896c3a44d16ee522d8b2abad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 5 Mar 2025 12:28:01 +0100 Subject: [PATCH 176/201] Silly bug in data saving --- Emilio/poolEphBeh_regression.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index f54fc68..f13efcc 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -143,7 +143,7 @@ rmse_laser = getRMSE( DX{4}, y_lpred, 1 ); - dataTable = table( {[r_sq;r_sq_pre;r_sq_post],[r_sq_l;r_sq_lpre;r_sq_post]}, ... + dataTable = table( {[r_sq;r_sq_pre;r_sq_post],[r_sq_l;r_sq_lpre;r_sq_lpost]}, ... {r_sq_trials}, {params.fit_error}, ... rmse_laser, 'VariableNames', {'R_2_p_L', 'R_squared_trials', ... 'RMSE_c', 'RMSE_l'} ); From 44b3505359bb884acc86b3fb36f9f5d5e9c0d03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 5 Mar 2025 12:38:44 +0100 Subject: [PATCH 177/201] MCiRNs reconstruction --- Emilio/poolEphBeh_regression.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index f13efcc..c0a574c 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -42,7 +42,7 @@ catch end -struct_search = "BC"; % or "MC" "eOPN3" "ChR2" +struct_search = "MC"; % or "MC" "eOPN3" "ChR2" "BC" selCondition = "freq"; % or "freq" "cont" Continuous or frquency extra_id = "iRNs"; verb = true; % verbose From bc6032bb95d21e68aa3a3feea3de45f4dd71d265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 5 Mar 2025 15:41:35 +0100 Subject: [PATCH 178/201] eOPN3 data --- Emilio/poolEphBeh_regression.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index c0a574c..8d389fc 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -42,11 +42,11 @@ catch end -struct_search = "MC"; % or "MC" "eOPN3" "ChR2" "BC" -selCondition = "freq"; % or "freq" "cont" Continuous or frquency -extra_id = "iRNs"; +struct_search = "eOPN3"; % or "MC" "eOPN3" "ChR2" "BC" +selCondition = "cont"; % or "freq" "cont" Continuous or frquency +extra_id = ""; % "iRNs" verb = true; % verbose -iRN_mice = dir( fullfile( roller_path, "Batch*", struct_search, "GADi*" ) ); +iRN_mice = dir( fullfile( roller_path, "Batch*", struct_search, "*" ) ); iRN_mice = iRN_mice( [iRN_mice.isdir] & ... ~arrayfun(@(x) any( ismember({'.','..'}, x.name ) ), iRN_mice )' ); animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); From 24969f1d3017bc4e1c48a2a124b83a62fc7929e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 5 Mar 2025 18:31:49 +0100 Subject: [PATCH 179/201] isscalar instead of numel()==1 --- Emilio/ephysVSai.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/ephysVSai.m b/Emilio/ephysVSai.m index 7f3335e..71f34fa 100644 --- a/Emilio/ephysVSai.m +++ b/Emilio/ephysVSai.m @@ -92,7 +92,7 @@ cf_flags = ctrlSub | ~cellfun( 'isempty', cf_flags ); brAll = cat( 1, brAll, behRes(cf_flags) ); - if ~isempty(rstPath) || numel( rstPath ) == 1 + if ~isempty(rstPath) || isscalar( rstPath ) rstCont = load( expandName( rstPath ), rstVars2load{:} ); else fprintf(1, 'Either empty or more than 1 file found!\n'); From 9b80757f26e876b0130bc6c17f78d3ce5387be1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 5 Mar 2025 18:31:52 +0100 Subject: [PATCH 180/201] Create poolEphBeh_recon_and_gof.m --- Emilio/poolEphBeh_recon_and_gof.m | 180 ++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 Emilio/poolEphBeh_recon_and_gof.m diff --git a/Emilio/poolEphBeh_recon_and_gof.m b/Emilio/poolEphBeh_recon_and_gof.m new file mode 100644 index 0000000..3c33dd3 --- /dev/null +++ b/Emilio/poolEphBeh_recon_and_gof.m @@ -0,0 +1,180 @@ +%#ok<*AGROW,*SAGROW> +%% Auxiliary variables and functions +fnOpts = {'UniformOutput', false}; +expandName = @(x) fullfile(x.folder, x.name); +animalPattern = '[a-zA-Z]+\d{1,}'; +rsOpts = {animalPattern, 'SearchType', 'expression'}; +ctOpts = {'IgnoreCase', true}; +lsOpts = {'L\d+.\d+', 'match'}; +ephFF = 'Ephys VW(-?\d+\.\d+)-(\d+\.\d+) RW20.00-200.00 SW(-?\d+\.\d+)-(-?\d+\.\d+)'; +tblOpts = {'VariableNames', {'Conditions', 'MI'}}; +% my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +% getMI = @(x,d) diff(x, 1, d)./sum(x, d); +% total_var_dist = @(dmat) integral( @(x) abs( pdf( dmat(1), x ) - pdf( dmat(2), x ) ), -5, 5 ); +getRMSE = @( r, x, d ) sqrt( mean( ( r - x ).^2, d, "omitmissing" ) ); +tocol = @(x) x(:); +m = 1e-3; +exclude_names = {'GADi13', 'GADi15', 'GADi53'}; + +if ~strcmp( computer, 'PCWIN64') + home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; + repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... + {'NeuroNetzAnalysis', 'AuxiliaryFuncs', 'Scripts'}, fnOpts{:} ); + cellfun(@(x) addpath( genpath( x ) ), repo_paths ) + roller_path = "/mnt/sds-hd/sd19b001/Emilio/SuperiorColliculusExperiments/Roller"; +else + roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; +end + +params = struct( 'relative_window', [-1,1]*800*m, 'delay_window', ... + [-1,1]*100*m, 'bin_size', 5*m, 'kfold', 20 ); +Nbins = diff(params.relative_window)/params.bin_size; +time_mdl = fit_poly( [1,Nbins], params.relative_window + ... + [1,-1]*(params.bin_size/2), 1 ); +tx = ( ( 1:Nbins)'.^[1,0] ) * time_mdl; +sponFlags = tx < 0; +laserFlags = my_xor(tx < [-0.1, 0.2]); +getTimeBoAT = @(s,f,p) reshape( s(f,:,:), size(s,2) * sum( f ), p.Ns ); + +struct_search = "BC"; % or "MC" "eOPN3" "ChR2" "BC" +selCondition = "freq"; % or "freq" "cont" Continuous or frquency +extra_id = "iRNs"; % "iRNs" "eRNs" "RNs" "" +mouse_line = "GADi"; % "GADi" "Rb" "vGlut" "" +verb = true; % verbose +iRN_mice = dir( fullfile( roller_path, "Batch*", struct_search, mouse_line+"*" ) ); +iRN_mice = iRN_mice( [iRN_mice.isdir] & ... + ~arrayfun(@(x) any( ismember({'.','..'}, x.name ) ), iRN_mice )' ); +animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); +exclude_flags = contains( animalFolders, exclude_names ); +%% Looping animals +oldMouse = ""; +mc = 0; mice = []; lp_mu = []; lPSTH = []; +sessType = 'single'; +for cad = tocol(animalFolders(~exclude_flags))' + [structPath, currMouse] = fileparts(cad); + [~, structName] = fileparts(structPath); + if string(oldMouse) ~= string(currMouse) + oldMouse = currMouse; + mice = [mice; struct('Name', currMouse, 'Sessions',[], ... + 'Structure', structName)]; + mc = mc + 1; + sc = 0; oldSess = ""; oldDepth = ""; + end + fprintf(1, 'Mouse %s ', currMouse) + sessDirs = getSubFolds(cad); + % Just date sessions + onlyDateSessFlag = arrayfun(@(x) string(regexp(x.name, '[0-9]{6}', ... + 'match')), sessDirs, fnOpts{:}); + sessDirs(cellfun(@isempty, onlyDateSessFlag)) = []; + for csd = sessDirs(:)' + curDir = expandName(csd); + sessDateDepth = regexp(csd.name, '(\d{6}).*_(\d{4})?', 'tokens', 'once'); + if ~isempty( sessDateDepth ) + currSess = sessDateDepth{1}; + if isempty( sessDateDepth{2} ) + depthSess = ''; + else + depthSess = sessDateDepth{2}; + end + else + currSess = regexp(csd.name, '(\d{6})', 'tokens', 'once'); + depthSess = ''; + if isempty(currSess) + fprintf( 1, "Unable to get session date and depth\n" ); + fprintf( 1, "Skipping: %s %s\n", currMouse, csd.name ) + continue + end + end + childFolders = getSubFolds(curDir); + sessOrgDirs = arrayfun(@(d) string(d.name), childFolders ); + sessOrgDirs( ~contains(sessOrgDirs, {'behaviour', 'ephys', ... + 'figures', 'opto'}, ctOpts{:}) ) = []; + if isempty(sessOrgDirs) + continue + end + data_path = curDir; + fprintf(1, ', Session %s\n', currSess ) + rfpStruct = dir( fullfile( data_path, "Regression " + ... + "CW-800.00-800.00ms DW-100.00-100.00 BZ5.00.mat" ) ); + if ~isempty(rfpStruct) + try + load( expandName( rfpStruct ), "mdlAll_ind", "DX", "params" ) + mdl = mdlAll_ind; + catch ME + display(ME.message) + continue + end + if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 || ... + any( cellfun(@isempty, DX) ) + continue + end + else + fprintf(1, 'No Regression file...\n') + continue + end + %% + mdl_mu = squeeze( mean( mdl, 2 ) ); + y_trials = reshape( DX{1}, params.Nb, params.Nr, params.Ns ); + y_pred = DX{2} * mdl_mu; + y_ptrials = reshape( y_pred, params.Nb, params.Nr, params.Ns ); + + r_sq_trials = goodnessFit2( y_trials, y_ptrials, 1 ); + r_sq = goodnessFit2( DX{1}, y_pred, 1 ); + + y_trials_pre = getTimeBoAT(y_trials, sponFlags, params); + y_ptrials_pre = getTimeBoAT(y_ptrials, sponFlags, params); + r_sq_pre = goodnessFit2(y_trials_pre, y_ptrials_pre, 1); + + y_trials_post = getTimeBoAT( y_trials, ~sponFlags, params ); + y_ptrials_post = getTimeBoAT( y_ptrials, ~sponFlags, params ); + r_sq_post = goodnessFit2(y_trials_post, y_ptrials_post, 1); + + y_lpred = DX{3} * mdl_mu; + y_lptrials = reshape( y_lpred, params.Nb, [], params.Ns ); + y_ltrials = reshape( DX{4}, size( y_lptrials ) ); + + r_sq_l = goodnessFit2( DX{4}, y_lpred, 1 ); + + y_trials_pre = getTimeBoAT(y_ltrials, laserFlags, params); + y_ptrials_pre = getTimeBoAT(y_lptrials, laserFlags, params); + r_sq_lpre = goodnessFit2(y_trials_pre, y_ptrials_pre, 1); + + y_trials_post = getTimeBoAT( y_ltrials, ~laserFlags, params ); + y_ptrials_post = getTimeBoAT( y_lptrials, ~laserFlags, params ); + r_sq_lpost = goodnessFit2(y_trials_post, y_ptrials_post, 1); + + rmse_laser = getRMSE( DX{4}, y_lpred, 1 ); + + dataTable = table( {[r_sq;r_sq_pre;r_sq_post],[r_sq_l;r_sq_lpre;r_sq_lpost]}, ... + {r_sq_trials}, {params.fit_error}, ... + rmse_laser, 'VariableNames', {'R_2_p_L', 'R_squared_trials', ... + 'RMSE_c', 'RMSE_l'} ); + if ( string(oldSess) ~= string(currSess) ) || ... + ( string(oldDepth) ~= string(depthSess) ) + oldSess = currSess; + oldDepth = depthSess; + auxStruct = struct('Date', currSess, ... + 'DataTable', dataTable, 'Type', sessType, ... + 'Depth', depthSess); + if ~isfield(mice, 'Sessions') + mice(mc).Sessions = auxStruct; + else + mice(mc).Sessions = [mice(mc).Sessions; auxStruct]; + end + sc = sc + 1; + end + close all + end +end +mice( arrayfun(@(x) isempty(x.Sessions), mice) ) = []; + +behFP = fullfile( roller_path, struct_search + extra_id + ... + "_gof.mat" ); +svOpts = {'-mat'}; +if exist(behFP, "file") + svOpts = {'-append'}; +end +save(behFP, "mice", svOpts{:}) +habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... + m.Sessions), mice, fnOpts{:}); +cat( 1, habFlag{:} ) From 6962bdc1a10bb6e5909d328142f9e01e94ece4d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Wed, 5 Mar 2025 18:32:08 +0100 Subject: [PATCH 181/201] Added few key parts of saving and ID --- Emilio/poolEphBeh_regression.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 8d389fc..67300e9 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -42,11 +42,12 @@ catch end -struct_search = "eOPN3"; % or "MC" "eOPN3" "ChR2" "BC" -selCondition = "cont"; % or "freq" "cont" Continuous or frquency -extra_id = ""; % "iRNs" +struct_search = "BC"; % or "MC" "eOPN3" "ChR2" "BC" +selCondition = "freq"; % or "freq" "cont" Continuous or frquency +extra_id = "iRNs"; % "iRNs" "eRNs" "RNs" "" +mouse_line = "GADi"; % "GADi" "Rb" "vGlut" "" verb = true; % verbose -iRN_mice = dir( fullfile( roller_path, "Batch*", struct_search, "*" ) ); +iRN_mice = dir( fullfile( roller_path, "Batch*", struct_search, mouse_line+"*" ) ); iRN_mice = iRN_mice( [iRN_mice.isdir] & ... ~arrayfun(@(x) any( ismember({'.','..'}, x.name ) ), iRN_mice )' ); animalFolders = arrayfun(@(f) string( expandName( f ) ), iRN_mice(:)); From 8fe699a1f97382e5db92cba5c8fda102d59fc584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 10 Mar 2025 18:18:19 +0100 Subject: [PATCH 182/201] Laser OFF and other improvements --- Emilio/compareR2_preVSpost_reconstruction.m | 60 ++++++++++++++++++--- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/Emilio/compareR2_preVSpost_reconstruction.m b/Emilio/compareR2_preVSpost_reconstruction.m index 4d71f2c..2222fc1 100644 --- a/Emilio/compareR2_preVSpost_reconstruction.m +++ b/Emilio/compareR2_preVSpost_reconstruction.m @@ -1,10 +1,11 @@ %% expandName = @(x) fullfile( x.folder, x.name ); +%% % mice_results = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs"; -mice_results = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\BC-igRNs"; +mice_results = fullfile("Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs\iRNs"); % pool_fig_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs\iRNs"; -pool_fig_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\BC-igRNs"; -r2_fp = dir( fullfile( mice_results,'*_reconstruction_sm.mat') ); +pool_fig_path = mice_results; +r2_fp = dir( fullfile( mice_results,'*_gof.mat') ); load( expandName( r2_fp ), 'mice' ) %% cellcat = @(x,d) cat( d, x{:} ); @@ -34,7 +35,7 @@ end [Nep, Ns] = size( r2_res_c, [1,2] ); -%% +%% Control pre- and post-stimulus % fnOpts = {'UniformOutput', false}; tocol = @(x) x(:); % r2_mean_c = cellcat( arrayfun(@(x) mean( r2_res_c(:,:,mouseID==x), 3 ), ... @@ -42,6 +43,7 @@ % r2_mean_l = cellcat( arrayfun(@(x) mean( r2_res_l(:,:,mouseID==x), 3 ), ... % 1:Nm, fnOpts{:} ), 3 ); r2_mean_c = r2_res_c; r2_mean_l = r2_res_l; +%% f = figure("Color", "w"); t = createtiles( f, 1, 1); ax = nexttile( t ); % bpID = repmat( ones( Nep, 1 ) * (1:Ns), 1, 1, Nm); @@ -65,7 +67,7 @@ set( f, 'UserData', {r2_mean_c, bpID, preVSpostID, mouseID, sessID} ) title( ax, 'Reconstruction R² for overall, pre-, and post-stimulus' ) -%% +%% Stats tests p = arrayfun(@(x) signrank( squeeze( r2_mean_c(2,x,:) ), ... squeeze( r2_mean_c(3,x,:) ) ), 1:Ns ); fnOpts = {'UniformOutput', false}; @@ -84,9 +86,7 @@ saveFigure( f, fullfile( pool_fig_path, ... "Reconstruction R² overall, pre and post" ), true, true ) -%% -% fnOpts = {'UniformOutput', false}; -tocol = @(x) x(:); +%% Laser ON out and in laser stimulation % r2_mean_c = cellcat( arrayfun(@(x) mean( r2_res_c(:,:,mouseID==x), 3 ), ... % 1:Nm, fnOpts{:} ), 3 ); % r2_mean_l = cellcat( arrayfun(@(x) mean( r2_res_l(:,:,mouseID==x), 3 ), ... @@ -127,5 +127,49 @@ arrayfun(@(h) sprintf( "$p=%.3f$", h) , p)]; %txt = arrayfun(@(s) replace( join( txt(:,s) ), " ", ""), 1:Ns ); text( ax, mean( x, 1 ), y(1,:)+0.035, txt(1,:), txOpts{:}, "FontSize", 10 ) +text( ax, mean( x, 1 ), y(1,:), txt(2,:), txOpts{:}, "FontSize", 8, ... + "Interpreter", "latex" ) + +%% Laser OFF vs Laser ON comparison +% r2_mean_c = cellcat( arrayfun(@(x) mean( r2_res_c(:,:,mouseID==x), 3 ), ... +% 1:Nm, fnOpts{:} ), 3 ); +% r2_mean_l = cellcat( arrayfun(@(x) mean( r2_res_l(:,:,mouseID==x), 3 ), ... +% 1:Nm, fnOpts{:} ), 3 ); +% r2_mean_c = r2_res_c; r2_mean_l = r2_res_l; +f = figure("Color", "w"); t = createtiles( f, 1, 1); +ax = nexttile( t ); +% bpID = repmat( ones( Nep, 1 ) * (1:Ns), 1, 1, Nm); +% preVSpostID = repmat( (1:Nep)' * ones( 1, Ns ), 1, 1, Nm ); +bpID = repmat( ones( Nep-1, 1 ) * (1:Ns), 1, 1, Nexp ); +preVSpostID = repmat( (1:Nep-1)' * ones( 1, Ns ), 1, 1, Nexp ); +% boxchart( ax, bpID(:), tocol( r2_mean_c ), 'GroupByColor', preVSpostID(:), ... +% 'Notch', 'on' ) +boxchart( ax, bpID(:), tocol( cat( 1, r2_mean_c(1,:,:), r2_mean_l(1,:,:) ) ), ... + 'GroupByColor', preVSpostID(:), 'Notch', 'on' ) +xline( ax, (1:Ns-1) + 1/2, '--', 'Color', 0.45*ones(1,3) ); +% legend( {'Overall', 'Pre', 'Post'}, "Box", "off", "Color", "none", ... +% "Location", "best", "AutoUpdate", "off" ) +legend( {'Laser OFF', 'Laser ON'}, "Box", "off", "Color", "none", ... + "Location", "best", "AutoUpdate", "off" ) +cleanAxis( ax ); ytickangle( ax, 90 ); set( ax, 'TickDir', 'out' ); +ylabel( ax, 'R²' ) +xticks( ax, 1:Ns ); xticklabels( ax, bp_names ); +xlim( ax, [1,Ns] + [-1,1]/2 ); +ylim( ax, [0, 1] ) +set( f, 'UserData', {r2_mean_c, r2_mean_l, bpID, preVSpostID, mouseID, sessID} ) +title( ax, 'Reconstruction R² for overall, pre-, and post-stimulus for BC→iRNs' ) +%% +p = arrayfun(@(x) signrank( squeeze( r2_mean_c(1,x,:) ), ... + squeeze( r2_mean_l(1,x,:) ) ), 1:Ns ); +fnOpts = {'UniformOutput', false}; +txOpts = {'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom'}; +astk = sum( p < [0.05, 0.01, 0.001]' ); +x = (1:Ns) + [-1;1]/4; +y = [1;1] * max( cat(1, r2_mean_l(1,:,:), r2_mean_c(1,:,:) ), [], [3,1] ) * 1.05; +line( ax, x, y, 'Color', 'k' ) +txt = [arrayfun( @(a) replace( join( repmat("\ast", 1, a) ), " ", "" ), astk, fnOpts{:} ); +arrayfun(@(h) sprintf( "$p=%.3f$", h) , p)]; +%txt = arrayfun(@(s) replace( join( txt(:,s) ), " ", ""), 1:Ns ); +text( ax, mean( x, 1 ), y(1,:)+0.035, txt(1,:), txOpts{:}, "FontSize", 10 ) text( ax, mean( x, 1 ), y(1,:), txt(2,:), txOpts{:}, "FontSize", 8, ... "Interpreter", "latex" ) \ No newline at end of file From 4a2b36da91d8e1802484e56e7507db86fc04893f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 10 Mar 2025 18:18:30 +0100 Subject: [PATCH 183/201] Runtime changes --- Emilio/poolEphBeh_recon_and_gof.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_recon_and_gof.m b/Emilio/poolEphBeh_recon_and_gof.m index 3c33dd3..58d8929 100644 --- a/Emilio/poolEphBeh_recon_and_gof.m +++ b/Emilio/poolEphBeh_recon_and_gof.m @@ -36,7 +36,7 @@ laserFlags = my_xor(tx < [-0.1, 0.2]); getTimeBoAT = @(s,f,p) reshape( s(f,:,:), size(s,2) * sum( f ), p.Ns ); -struct_search = "BC"; % or "MC" "eOPN3" "ChR2" "BC" +struct_search = "MC"; % or "MC" "eOPN3" "ChR2" "BC" selCondition = "freq"; % or "freq" "cont" Continuous or frquency extra_id = "iRNs"; % "iRNs" "eRNs" "RNs" "" mouse_line = "GADi"; % "GADi" "Rb" "vGlut" "" From 16b9dd308e44e05706b1ef31e6f1ae4ff1d85097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 10 Mar 2025 18:18:46 +0100 Subject: [PATCH 184/201] Validation of design matrices --- Emilio/poolEphBeh_recon_and_gof.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emilio/poolEphBeh_recon_and_gof.m b/Emilio/poolEphBeh_recon_and_gof.m index 58d8929..94026f4 100644 --- a/Emilio/poolEphBeh_recon_and_gof.m +++ b/Emilio/poolEphBeh_recon_and_gof.m @@ -105,7 +105,7 @@ continue end if isempty(DX) || (sum( isnan(mdl), "all" ) / numel(mdl) ) > 0.05 || ... - any( cellfun(@isempty, DX) ) + any( cellfun(@isempty, DX) ) || numel(DX)~= 4 continue end else From 6fd10fa653d8508a1236036c780e97367fee5a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 10 Mar 2025 18:19:05 +0100 Subject: [PATCH 185/201] Section divisions --- Emilio/poolEphBeh_regression.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Emilio/poolEphBeh_regression.m b/Emilio/poolEphBeh_regression.m index 67300e9..244a999 100644 --- a/Emilio/poolEphBeh_regression.m +++ b/Emilio/poolEphBeh_regression.m @@ -15,7 +15,7 @@ tocol = @(x) x(:); m = 1e-3; exclude_names = {'GADi13', 'GADi15', 'GADi53'}; - +%% if ~strcmp( computer, 'PCWIN64') home_path = '/gpfs/bwfor/home/hd/hd_hd/hd_bf154/'; repo_paths = cellfun(@(x) char( fullfile( home_path, x) ), ... @@ -25,7 +25,7 @@ else roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; end - +%% params = struct( 'relative_window', [-1,1]*800*m, 'delay_window', ... [-1,1]*100*m, 'bin_size', 5*m, 'kfold', 20 ); Nbins = diff(params.relative_window)/params.bin_size; @@ -34,14 +34,14 @@ tx = ( ( 1:Nbins)'.^[1,0] ) * time_mdl; sponFlags = tx < 0; getTimeBoAT = @(s,f,p) reshape( s(f,:,:), size(s,2) * sum( f ), p.Ns ); - +%% pc = parcluster('local'); try parpool( pc ); catch end - +%% struct_search = "BC"; % or "MC" "eOPN3" "ChR2" "BC" selCondition = "freq"; % or "freq" "cont" Continuous or frquency extra_id = "iRNs"; % "iRNs" "eRNs" "RNs" "" From 5a384a8e5c63efc909cf919b9be577843ed01780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 1 Apr 2025 17:10:59 +0200 Subject: [PATCH 186/201] More than 1 puffAll --- Jesus/DE_Jittering.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Jesus/DE_Jittering.m b/Jesus/DE_Jittering.m index 49f027d..d69d275 100644 --- a/Jesus/DE_Jittering.m +++ b/Jesus/DE_Jittering.m @@ -207,7 +207,8 @@ [chCond, iOk] = listdlg('ListString',condNames,'SelectionMode','single',... 'PromptString',... 'Choose the condition which has all whisker triggers: (one condition)',... - 'InitialValue', find(condGuess), 'ListSize', [350, numel(condNames)*16]); + 'InitialValue', find(condGuess,1,"first"), 'ListSize', ... + [350, numel(condNames)*16]); if ~iOk fprintf(1,'Cancelling...\n') return From 434cc65469862828c4ba080f14ba3b24f4daba82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 10 Apr 2025 20:42:50 +0200 Subject: [PATCH 187/201] Update compareR2_preVSpost_reconstruction.m --- Emilio/compareR2_preVSpost_reconstruction.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Emilio/compareR2_preVSpost_reconstruction.m b/Emilio/compareR2_preVSpost_reconstruction.m index 2222fc1..a1fde20 100644 --- a/Emilio/compareR2_preVSpost_reconstruction.m +++ b/Emilio/compareR2_preVSpost_reconstruction.m @@ -155,7 +155,7 @@ ylabel( ax, 'R²' ) xticks( ax, 1:Ns ); xticklabels( ax, bp_names ); xlim( ax, [1,Ns] + [-1,1]/2 ); -ylim( ax, [0, 1] ) +ylim( ax, [-1, 1] ) set( f, 'UserData', {r2_mean_c, r2_mean_l, bpID, preVSpostID, mouseID, sessID} ) title( ax, 'Reconstruction R² for overall, pre-, and post-stimulus for BC→iRNs' ) %% @@ -168,8 +168,8 @@ y = [1;1] * max( cat(1, r2_mean_l(1,:,:), r2_mean_c(1,:,:) ), [], [3,1] ) * 1.05; line( ax, x, y, 'Color', 'k' ) txt = [arrayfun( @(a) replace( join( repmat("\ast", 1, a) ), " ", "" ), astk, fnOpts{:} ); -arrayfun(@(h) sprintf( "$p=%.3f$", h) , p)]; +arrayfun(@(h) sprintf( "$p=%.2g$", h) , p)]; %txt = arrayfun(@(s) replace( join( txt(:,s) ), " ", ""), 1:Ns ); -text( ax, mean( x, 1 ), y(1,:)+0.035, txt(1,:), txOpts{:}, "FontSize", 10 ) +text( ax, mean( x, 1 ), y(1,:)*1.1, txt(1,:), txOpts{:}, "FontSize", 10 ) text( ax, mean( x, 1 ), y(1,:), txt(2,:), txOpts{:}, "FontSize", 8, ... "Interpreter", "latex" ) \ No newline at end of file From 78ca4caa38a70b371d44d5f67e95433ba41293c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 13 Jun 2025 09:05:16 +0200 Subject: [PATCH 188/201] Compute summMice from scratch --- Emilio/iegRNs_AmplitudeIndexPool.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Emilio/iegRNs_AmplitudeIndexPool.m b/Emilio/iegRNs_AmplitudeIndexPool.m index af89f66..37e8a6f 100644 --- a/Emilio/iegRNs_AmplitudeIndexPool.m +++ b/Emilio/iegRNs_AmplitudeIndexPool.m @@ -12,7 +12,7 @@ mt_subs = [11, 14, 17]; exp_type_subs_cell = {mc_subs, bc_subs, bs_subs, mt_subs}; -clearvars *_subs -except exp_type_subs_cell +% clearvars *_subs -except exp_type_subs_cell mice_bulk = arrayfun( @(x) load( expandPath( x ), "mice" ), ... bp_paths ); @@ -25,9 +25,9 @@ fnOpts = {'UniformOutput', false}; exp_subtype = {'iRNs', 'eRNs', 'RNs'}; % exp_subtype = {'terminal inhib'}; -% name_keys = {'GADi', {'GADe', 'vGlut'}, 'WTg'}; +name_keys = {'GADi', {'GADe', 'vGlut'}, 'WTg'}; % name_keys = {'GADi', 'vGlut', 'WTg'}; -name_keys = {'GADi', 'GADe', 'WTg'}; +% name_keys = {'GADi', 'GADe', 'WTg'}; % name_keys = {{'Rb', 'WT'}}; bodypart_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... "Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... @@ -42,7 +42,7 @@ cleanAxis = @(x) set( x, "Box", "off", "Color", "none" ); fig_path = fullfile( ... "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures" ); -load( fullfile( fig_path, "MC, BC, BS, MCterminals pool.mat" ), "summMice" ); +% load( fullfile( fig_path, "MC, BC, BS, MCterminals pool.mat" ), "summMice" ); expMice = summMice{1}(3); ovwtFlag = false; From 2c1bef2ce34135c26239490e928dceb195d27b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 13 Jun 2025 09:05:41 +0200 Subject: [PATCH 189/201] Removed the trial proportion and BP plots --- Emilio/iegRNs_AmplitudeIndexPool.m | 94 ++++++++++++++++-------------- 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/Emilio/iegRNs_AmplitudeIndexPool.m b/Emilio/iegRNs_AmplitudeIndexPool.m index 37e8a6f..6abc3ca 100644 --- a/Emilio/iegRNs_AmplitudeIndexPool.m +++ b/Emilio/iegRNs_AmplitudeIndexPool.m @@ -59,68 +59,72 @@ figs = gobjects( numel( exp_subtype ), 1 ); % exp_type = join( ['MC-', expMice.ExperimentalGroup] ); exp_type = expMice.ExperimentalGroup; +%% for cest = 1:numel(exp_subtype) cons_mice = exp_subtype_flags(:,cest) & ~exclude_mice; exp_subtype_flags(:,cest) = exp_subtype_flags(:,cest) & ~exclude_mice; if sum( cons_mice ) figs(cest) = figure( "Color", "w" ); - t = createtiles( figs(cest), 2, 1 ); ax = nexttile(t); + % t = createtiles( figs(cest), 2, 1 ); ax = nexttile(t); + t = createtiles( figs(cest), 1, 1 ); ax = nexttile(t); aux = squeeze( mean( expMice.AmplitudeIndex(:,:, ... cons_mice), 1, "omitmissing" ) )'; boxchart( ax, aux, bxOpts{:} ); ylabel( ax, 'Amplitude index' ); xticklabels( ax, xLabels ); - ylim(ax, [0,1]); cleanAxis(ax); ax.XAxis.Visible = "off"; + ylim(ax, [0,1]); cleanAxis(ax); %ax.XAxis.Visible = "off"; p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... "ErrorHandler", @(s,a) nan(1) ); mark_flag = p(:) < signTh; text( ax, 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... - arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) + arrayfun(@(x) sprintf("$$p=%.3g$$", x), p(:) ), txOpts{:} ) + xticklabels( xLabels ); - ax = nexttile(t); - aux = squeeze( mean( expMice.TrialProportions(:,:, ... - cons_mice), 1, "omitmissing" ) )'; - boxchart(ax, aux, bxOpts{:} ); - ylabel( ax, 'Trial proportions' ) - xticklabels( xLabels ); ylim([0,2]); cleanAxis( ax ); - p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... - "ErrorHandler", @(s,a) nan(1) ); - text(ax, 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... - arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) - title(t, sprintf( "Area/%s", exp_subtype{cest} ) ) + % ax = nexttile(t); + % aux = squeeze( mean( expMice.TrialProportions(:,:, ... + % cons_mice), 1, "omitmissing" ) )'; + % boxchart(ax, aux, bxOpts{:} ); + % ylabel( ax, 'Trial proportions' ) + % xticklabels( xLabels ); ylim([0,2]); cleanAxis( ax ); + % p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... + % "ErrorHandler", @(s,a) nan(1) ); + % text(ax, 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... + % arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) + title(t, sprintf( "%s Area/%s", exp_type, exp_subtype{cest} ) ) - for cbp = 1:numel(bodypart_names) - fig = figure("Color", "w"); t2 = createtiles( fig, 2, 1 ); - ax = nexttile(t2); - aux = squeeze( mean( expMice.PolygonUnfoldAmplIndx(:,:, ... - cbp, cons_mice), 2, "omitmissing" ) )'; - boxchart( ax, aux, bxOpts{:} ); - ylabel( ax, 'Amplitude index' ); xticklabels( ax, xLabels ); - ylim(ax, [0,1]); cleanAxis(ax); ax.XAxis.Visible = "off"; - p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... - "ErrorHandler", @(s,a) nan(1) ); - text( 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... - arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) + % for cbp = 1:numel(bodypart_names) + % % fig = figure("Color", "w"); t2 = createtiles( fig, 2, 1 ); + % fig = figure("Color", "w"); t2 = createtiles( fig, 1, 1 ); + % ax = nexttile(t2); + % aux = squeeze( mean( expMice.PolygonUnfoldAmplIndx(:,:, ... + % cbp, cons_mice), 2, "omitmissing" ) )'; + % boxchart( ax, aux, bxOpts{:} ); + % ylabel( ax, 'Amplitude index' ); xticklabels( ax, xLabels ); + % ylim(ax, [0,1]); cleanAxis(ax); ax.XAxis.Visible = "off"; + % p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... + % "ErrorHandler", @(s,a) nan(1) ); + % text( 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... + % arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) - ax = nexttile(t2); - aux = squeeze( mean( expMice.PolygonUnfoldTrialProp(:,:, ... - cbp, cons_mice), 2, "omitmissing" ) )'; - boxchart(ax, aux, bxOpts{:} ); - ylabel( ax, 'Trial proportions' ) - xticklabels( xLabels ); ylim([0,2]); cleanAxis( ax ); - p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... - "ErrorHandler", @(s,a) nan(1) ); - text( 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... - arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) - title(t2, sprintf( "%s/%s", bodypart_names(cbp), exp_subtype{cest} ) ) + % ax = nexttile(t2); + % aux = squeeze( mean( expMice.PolygonUnfoldTrialProp(:,:, ... + % cbp, cons_mice), 2, "omitmissing" ) )'; + % boxchart(ax, aux, bxOpts{:} ); + % ylabel( ax, 'Trial proportions' ) + % xticklabels( xLabels ); ylim([0,2]); cleanAxis( ax ); + % p = arrayfun(@(x) signrank( aux(:,1), aux(:,x) ), 2:size(aux,2), ... + % "ErrorHandler", @(s,a) nan(1) ); + % text( 2:size(aux,2), 1.15*max( aux(:,2:end), [], 1 ), ... + % arrayfun(@(x) sprintf("$$p=%.3f$$", x), p(:) ), txOpts{:} ) + % title(t2, sprintf( "%s/%s", bodypart_names(cbp), exp_subtype{cest} ) ) % saveFigure( fig, fullfile( fig_path, join( [bodypart_names(cbp), ... % exp_type, exp_subtype{cest}, "all mice pool" ] ) ), ... % true, ovwtFlag ) - saveFigure( fig, fullfile( fig_path, join( [bodypart_names(cbp), ... - exp_type, exp_subtype{cest}, sum( cons_mice ) ] ) ), ... - true, ovwtFlag ) - end + % saveFigure( fig, fullfile( fig_path, join( [bodypart_names(cbp), ... + % exp_type, exp_subtype{cest}, sum( cons_mice ) ] ) ), ... + % true, ovwtFlag ) + % end end end @@ -128,7 +132,7 @@ % join( ["Areas", exp_type, exp_subtype{f}, "all mice pool"] ) ), true, ovwtFlag ), ... % find( arrayfun(@(f) ~isa( f, 'matlab.graphics.GraphicsPlaceholder'), figs ) ) ); -arrayfun(@(f) saveFigure( figs(f), fullfile( fig_path, ... - join( ["Areas", exp_type, exp_subtype{f}, ... - sum( exp_subtype_flags(:,f) ) ] ) ), true, ovwtFlag ), ... - find( arrayfun(@(f) ~isa( f, 'matlab.graphics.GraphicsPlaceholder'), figs ) ) ); \ No newline at end of file +% arrayfun(@(f) saveFigure( figs(f), fullfile( fig_path, ... +% join( ["Areas", exp_type, exp_subtype{f}, ... +% sum( exp_subtype_flags(:,f) ) ] ) ), true, ovwtFlag ), ... +% find( arrayfun(@(f) ~isa( f, 'matlab.graphics.GraphicsPlaceholder'), figs ) ) ); \ No newline at end of file From 3845bcb7fa0fd7ef120df3bc09e56326d851a463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 13 Jun 2025 09:05:56 +0200 Subject: [PATCH 190/201] Fixed some plotting errors --- Emilio/popPolygon.m | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/Emilio/popPolygon.m b/Emilio/popPolygon.m index 69a3ef8..70355ef 100644 --- a/Emilio/popPolygon.m +++ b/Emilio/popPolygon.m @@ -1,15 +1,12 @@ % iRNs expMice = summMice{1}(3); -aux = expMice.PolygonUnfoldAmplIndx([1,5],:,:,cons_mice); +aux = expMice.PolygonUnfoldAmplIndx([1,5],:,:,cons_mice); % cons_mice comes from the iegRNs_AmplitudeIndexPool.m script % eOPN3 -expMice = summMice{4}(2); -aux = expMice.PolygonUnfoldAmplIndx([1,8],:,:,:); +% expMice = summMice{4}(2); +% aux = expMice.PolygonUnfoldAmplIndx([1,8],:,:,:); %% -createtiles = @(f,r,c) tiledlayout( f, r, c, ... - 'TileSpacing', 'Compact', 'Padding', 'tight'); - vaxOpts = cellstr( ["HorizontalAlignment", "center", ... "VerticalAlignment", "baseline", "Rotation"] ); med_AI_pbp = squeeze( median( aux, 2, "omitmissing" ) ); @@ -17,17 +14,16 @@ clrMap = [0.15*ones(1,3); 0, 0.51, 1]; Nb = 8; bodypart_names = ["Stim-whisker mean", "Stim-whisker fan arc", ... -"Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... -"Symmetry", "Nose", "Roller speed"]; + "Nonstim-whisker mean", "Nonstim-whisker fan arc", "Interwhisk arc", ... + "Symmetry", "Nose", "Roller speed"]; iqr_AI = quantile( med_AI_pbp, [1,3]/4, 3 ); -iqr_coords = iqr_AI .* reshape(z_axis,1,[],1); - -[f, z_axis, poly_coords] = createPolarPlotPolygons( med_AI_pbp ); +[f, z_axis, poly_coords] = createPolarPlotPolygons( med_AI_all' ); +iqr_coords = iqr_AI .* reshape(z_axis,1,[],1); [pchObj, ax] = plotPolygons( poly_coords, f, 'clrMap', clrMap ); -z_rot = exp( 1i*pi/32 ); +z_rot = exp( 1i*pi/32 ); % Dots by the polygon arrayfun(@(c,z) line( real( poly_coords(:,c) * z)', ... imag( poly_coords(:,c) * z )', 'LineStyle', 'none', ... @@ -35,22 +31,31 @@ 1:2, [z_rot, z_rot'] ) set( gca, 'Box', 'off', 'Color', 'none', "Visible", "off" ); % Lines for IQR -arrayfun(@(x,z) line( squeeze( real( iqr_coords(:,:,x) * z ) )', ... - squeeze( imag( iqr_coords(:,:,x) * z ) )', 'LineWidth', 2, ... +% arrayfun(@(x,z) line( squeeze( real( iqr_coords(:,:,x) * z ) )', ... +% squeeze( imag( iqr_coords(:,:,x) * z ) )', 'LineWidth', 2, ... +% 'Color', clrMap(x,:) ), 1:2, [z_rot, z_rot'] ) +arrayfun(@(x,z) line( squeeze( real( iqr_coords(x,:,:) * z ) )', ... + squeeze( imag( iqr_coords(x,:,:) * z ) )', 'LineWidth', 2, ... 'Color', clrMap(x,:) ), 1:2, [z_rot, z_rot'] ) -text(ax, 0.25:0.25:1, zeros(1,4), string( ( 1:4 )'/4 ), ... - "HorizontalAlignment", "left", "VerticalAlignment", "cap" ) +% text(ax, 0.25:0.25:1, zeros(1,4), string( ( 1:4 )'/4 ), ... +% "HorizontalAlignment", "left", "VerticalAlignment", "cap" ) title('Population Polygons for MC\rightarrowiRNs' ) legend( findobj( gca, 'Type', 'Patch' ), {'Laser OFF', 'Laser ON'}, ... "Location", "best", "Color", "none", "Box", "off" ) p = arrayfun(@(b) signrank( squeeze( med_AI_pbp(1,b,:) ), ... squeeze( med_AI_pbp(2,b,:) ) ), 1:8 ); -arrayfun(@(v, y) text( real( 1.25*poly_coords(1,v) ), ... - imag( 1.25*poly_coords(1,v) ), repmat( '\ast', 1, sum( p(v) < ... - [0.05, 0.01, 0.001] ) ), "HorizontalAlignment", "center", ... - "Rotation", y, "VerticalAlignment", "baseline"), 1:8, ... +% arrayfun(@(v, y) text( real( 1.25*poly_coords(1,v) ), ... +% imag( 1.25*poly_coords(1,v) ), repmat( '\ast', 1, sum( p(v) < ... +% [0.05, 0.01, 0.001] ) ), "HorizontalAlignment", "center", ... +% "Rotation", y, "VerticalAlignment", "baseline"), 1:8, ... +% (180*angle( transp(z_axis) )/pi) - 90 ); +arrayfun(@(v, y) text( real( 1.25 * max( poly_coords(v,:) ) ), ... + imag( 1.25 * max( poly_coords(v,:) ) ), sprintf("$p=%.3g$", p(v) ), ... + "HorizontalAlignment", "center", "Rotation", y, ... + "VerticalAlignment", "baseline", "Interpreter", "latex"), 1:8, ... (180*angle( transp(z_axis) )/pi) - 90 ); + arrayfun(@(v,b,y) text( real( z_axis(v) ), ... imag( z_axis(v) ), b, vaxOpts{:}, y ), 1:8, bodypart_names, ... (180*angle( transp(z_axis) )/pi) - 90 ) \ No newline at end of file From 3053fa4abe05888894bffb4647fcef3105d5cafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 13 Jun 2025 09:06:04 +0200 Subject: [PATCH 191/201] Runtime changes --- Emilio/compareR2_preVSpost_reconstruction.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emilio/compareR2_preVSpost_reconstruction.m b/Emilio/compareR2_preVSpost_reconstruction.m index a1fde20..a36fa21 100644 --- a/Emilio/compareR2_preVSpost_reconstruction.m +++ b/Emilio/compareR2_preVSpost_reconstruction.m @@ -1,8 +1,9 @@ %% expandName = @(x) fullfile( x.folder, x.name ); +roller_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller"; %% % mice_results = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs"; -mice_results = fullfile("Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs\iRNs"); +mice_results = fullfile(roller_path, "PoolFigures/MC-iegRNs/iRNs"); % pool_fig_path = "Z:\Emilio\SuperiorColliculusExperiments\Roller\PoolFigures\MC-iegRNs\iRNs"; pool_fig_path = mice_results; r2_fp = dir( fullfile( mice_results,'*_gof.mat') ); From 24c2f719842366b042cd4b3276eeff123dd3cf1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 25 Sep 2025 19:36:05 +0200 Subject: [PATCH 192/201] Updated names of the fields --- Emilio/poolEphMI.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Emilio/poolEphMI.m b/Emilio/poolEphMI.m index ff9a108..f4733e8 100644 --- a/Emilio/poolEphMI.m +++ b/Emilio/poolEphMI.m @@ -119,14 +119,14 @@ habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... m.Sessions), mice, fnOpts{:}); cat( 1, habFlag{:} ) -%{ + %% multiple jittDist = makedist('Normal', 'mu', 0, 'sigma', 1/9); habFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "multi", ... m.Sessions), mice, fnOpts{:}); habTable = arrayfun(@(m, f) {m.Sessions(f{:}).DataTable}, mice, habFlag, ... fnOpts{:}); -pBehIdx = cellfun(@(x) cellfun(@(y) cell2mat(y.BehaviourIndices), x, ... +pBehIdx = cellfun(@(x) cellfun(@(y) cell2mat(y.Trial_and_Amp_Indices{end}), x, ... fnOpts{:}), habTable, fnOpts{:}); Ncc = cellfun(@(x) cellfun(@(y) numel(y), x), pBehIdx, fnOpts{:}); rSz = cellfun(@(x) max(cellfun(@(y) numel(y), x)), pBehIdx); @@ -157,7 +157,7 @@ lgObj = legend(ax, mNames); set(lgObj, "Box", 'off', 'Color', 'none', 'Location', 'best', 'AutoUpdate', 'off') - +%{ %% single singFlag = arrayfun(@(m) arrayfun(@(s) string(s.Type) == "single", ... m.Sessions), mice, fnOpts{:}); From 086750811c4d9fca4d222e0beea0516ae77fe8fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 25 Sep 2025 19:36:26 +0200 Subject: [PATCH 193/201] Output baseline levels --- Emilio/AKK/getMaxAbsPerTrial.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Emilio/AKK/getMaxAbsPerTrial.m b/Emilio/AKK/getMaxAbsPerTrial.m index 732520a..08e1883 100644 --- a/Emilio/AKK/getMaxAbsPerTrial.m +++ b/Emilio/AKK/getMaxAbsPerTrial.m @@ -1,4 +1,5 @@ -function [mavpt, mxT] = getMaxAbsPerTrial(inStack, responseWindow, spontWindow, timeAxis) +function [mavpt, mxT, bl_lvl] = getMaxAbsPerTrial(inStack, ... + responseWindow, spontWindow, timeAxis) %GETMAXABSPERTRIAL gets as the name suggests, the maximum absolute %amplitude per trial in the given input stack % Detailed explanation goes here, later. @@ -24,8 +25,8 @@ spontaneousFlags = my_xor( timeAxis(:) >= spontWindow ); % mavpt = max(abs(inStack(responseFlags, :)-median(inStack,1))); -[mavpt, ps] = max( abs( inStack(responseFlags,:) - ... - median( inStack(spontaneousFlags,:), 1 ) ) ); +bl_lvl = median( inStack(spontaneousFlags,:), 1 ); +[mavpt, ps] = max( abs( inStack(responseFlags,:) - bl_lvl ) ); % mavpt = arrayfun(@(mp, tr) ... % inStack(find(responseFlags,1,'first')+mp-1, tr), ps(:), (1:Ntg)'); mxT = timeAxis(ps+find(responseFlags,1,"first")-1); From 219c4d8ef359d06b492ac0ae8a7601b434f7cf11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 25 Sep 2025 19:36:51 +0200 Subject: [PATCH 194/201] Auxiliary space for on-the-run scripts --- Emilio/aux_space.m | 129 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 Emilio/aux_space.m diff --git a/Emilio/aux_space.m b/Emilio/aux_space.m new file mode 100644 index 0000000..68d18e5 --- /dev/null +++ b/Emilio/aux_space.m @@ -0,0 +1,129 @@ +aux_mat = zeros( sum( any( ~isnan( PTX_mat(:,[2,3],:) ), 1 ), 'all' ), 2 ); +cm = 1; +for cm2 = 1:size( PTX_mat, 3 ) + dat_flag = any( ~isnan( PTX_mat(:,[2,3],cm2) ), 1 ); + if any( dat_flag ) + dat_flag2 = any( ~isnan( PTX_mat(:,[2,3],cm2) ), 2 ) ; + aux_mat(cm,:) = PTX_mat(dat_flag2,[true, dat_flag],cm2); + cm=cm+1; + end +end +%% +fowFlag = false; +batch_dir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch6_beh+Muscimol" ); +exp_dirs = dir( fullfile( batch_dir, "Musc", "*", "*" ) ); +exp_dirs( any( string( {exp_dirs.name} ) == ["."; ".."], 1 ) ) = []; +get_full_path = @(x) fullfile( x.folder, x.name); +m = 1e-3; +for cep = 1:numel(exp_dirs) + exp_path = get_full_path( exp_dirs(cep) ); + eph_path = dir( fullfile( exp_path, "ephys*" ) ); + eph_path( ~[eph_path.isdir] ) = []; + beh_path = fullfile( exp_path, "Behaviour" ); + + if ~isempty( eph_path ) + eph_path = get_full_path( eph_path ); + figure_path = fullfile( eph_path, "Figures" ); + af_path = dir( fullfile( eph_path , "*analysis.mat" ) ); + af_path = get_full_path( af_path ); + elseif exist( beh_path, "dir" ) + af_path = get_full_path( dir( fullfile( beh_path, "*analysis.mat") ) ); + figure_path = fullfile( beh_path, "Figures" ); + else + beh_path = exp_path; + af_path = get_full_path( dir( fullfile( beh_path, "*analysis.mat") ) ); + figure_path = fullfile( beh_path, "Figures" ); + end + + [~, af_name] = fileparts( af_path ); + expName = extractBefore(af_name, "analysis"); + load( af_path, "Conditions", "fs") + + fnOpts = {'UniformOutput', false}; + axOpts = {'Box','off','Color','none'}; + lgOpts = cat( 2, axOpts{1:2}, {'Location','best'} ); + + ldFlag = false; + try + load( get_full_path( dir( fullfile( beh_path, "RollerSpeed*.mat" ) ) ), "fr") + catch + ldFlag = true; + end + + ctrl_cond = contains( {Conditions.name}, "Control puff", "IgnoreCase", true ); + ptx_cond = contains( {Conditions.name}, 'musc', 'IgnoreCase', true ); + if sum(ptx_cond)==0 + fprintf(1, 'Did not find PTX condition!! Continuing!!') + fprintf(1, '%s', exp_path ) + continue + end + consCond = find( or(ctrl_cond, ptx_cond) ); + Nccond = length( consCond ); + prmSubs = nchoosek( 1:Nccond, 2 ); + + pairedStimFlags = arrayfun(@(c) any( ... + Conditions(1).Triggers(:,1) == ... + reshape( Conditions(c).Triggers(:,1), 1, [] ), 2 ), consCond, fnOpts{:} ); + pairedStimFlags = cat( 2, pairedStimFlags{:} ); + + consCondNames = string( { Conditions( consCond ).name } ); + + [behRes, behFig_path, behData, aInfo] = analyseBehaviour( beh_path, ... + "ConditionsNames", cellstr( consCondNames ), ... + "PairedFlags", pairedStimFlags, ... + "FigureDirectory", figure_path, ... + "ResponseWindow", [25, 350] * m, ... + "ViewingWindow", [-450, 500] * m, ... + "figOverWrite", fowFlag ); + + if ~exist( "fr", "var" ) && ldFlag + try + load( get_full_path( dir( fullfile( beh_path, "RollerSpeed*.mat" ) ) ), "fr") + catch + load( fullfile( beh_path, 'RollerFrameRate.mat' ), 'fr' ) + end + ldFlag = false; + end + + [pAreas, ~, behAreaFig] = createBehaviourIndex(behRes); + behMeasures = string({behAreaFig.Name}); + biFigPttrn = behMeasures+"%s"; + biFigPttrn = arrayfun(@(s) sprintf(s, sprintf(" %s (%%.3f)", ... + consCondNames ) ), biFigPttrn ); + + for it = 1:numel(behMeasures) + behRes = arrayfun(@(bs, ba) setfield( bs, ... + strrep( behMeasures(it), " ", "_" ), ba), behRes(:), pAreas(:,it) ); + end + + arrayfun(@(f) set( f, 'UserData', behRes ), behAreaFig ); + + biFN = arrayfun(@(s) sprintf( biFigPttrn(s), pAreas(:,s) ), 1:numel(behMeasures) ); + + arrayfun(@(f, fn) saveFigure(f, fullfile(behFig_path, fn), true, fowFlag), ... + behAreaFig(:), biFN(:) ); + + close all +end + +%% +% batch_dir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch13_beh" ); +% ss_fp = dir( fullfile( batch_dir, "PTX\WT*\*PTX\Behaviour\BehaviourResults*.mat" ) ); +batch_dir = fullfile( "Z:\Emilio\SuperiorColliculusExperiments\Roller\Batch12_ephys.e" ); +ss_fp = dir( fullfile( batch_dir, 'MC', 'vGlut*', '*PTX*', '*', 'BehaviourResults V-0.45 - 0.50 s R25.00 - 350.00 ms.mat' ) ); +Nf = numel( ss_fp ); +bl_changes = zeros( Nf, 8 ); +my_zscore = @(x, m, s) ( x - m ) ./ ( s .* (s~=0) + 1 .* (s==0) ); +for cf = 1:Nf + load( get_full_path( ss_fp(cf) ), "behRes" ) + c_idx = contains( {behRes.ConditionName}, 'control puff', 'IgnoreCase', true ); + p_idx = contains( {behRes.ConditionName}, 'ptx', 'IgnoreCase', true ); + c = {behRes(c_idx).Results.Baseline}; + c = cat( 1, c{:} ); + t = {behRes(p_idx).Results.Baseline}; + t = cat( 1, t{:} ); + [cz, centre, scale] = zscore( c , 0, 2 ); + bl_changes(cf,:) = median( my_zscore( t, centre, scale ), 2 ) - ... + median( cz, 2 ); +end +bs_n = string( {behRes(1).Results.BehSigName} ); From 94474f99f9828483db7bcad910b562226e44a2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 7 Nov 2025 18:05:58 +0100 Subject: [PATCH 195/201] Organising script for inference --- Emilio/jitt_reorganise_counts.m | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Emilio/jitt_reorganise_counts.m diff --git a/Emilio/jitt_reorganise_counts.m b/Emilio/jitt_reorganise_counts.m new file mode 100644 index 0000000..19aed14 --- /dev/null +++ b/Emilio/jitt_reorganise_counts.m @@ -0,0 +1,13 @@ +cfg_struct = configStructure; +cfg_struct.Viewing_window_s = [-0.3,0.2]; +[PSTHpupt, psthTx, n_trials] = getPSTH_perU_perT( ... + relativeSpkTmsStruct, cfg_struct); +n_conditions = numel(PSTHpupt); +n_elements = cellfun(@(x) numel(x), PSTHpupt); +condition_names = {'laser1ms','laser10ms','laser50ms',... + 'laser100ms','laser200ms','whisker'}; +for ccond = 1:n_conditions + [n_bins, n_neurons] = size(PSTHpupt{ccond},[2,3]); + + +end \ No newline at end of file From 4e2f69e3fd0a173e2eac38757d2eeda543dcd41c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 15 Jan 2026 11:41:57 +0100 Subject: [PATCH 196/201] Create MUA_LFP_estimation.m Estimation of 'synchronised vs desynchronised' anaesthesia-induced states. --- Emilio/MUA_LFP_estimation.m | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Emilio/MUA_LFP_estimation.m diff --git a/Emilio/MUA_LFP_estimation.m b/Emilio/MUA_LFP_estimation.m new file mode 100644 index 0000000..815aaf7 --- /dev/null +++ b/Emilio/MUA_LFP_estimation.m @@ -0,0 +1,93 @@ +exp_paths = ["Z:\PainData\Corrected_Channel_Map\L6\Cortex\20.8.21\KS2", ... +"Z:\PainData\Corrected_Channel_Map\L6\Cortex\26.8.21", ... +"Z:\PainData\Corrected_Channel_Map\Dual\L6_VPL\S1\Nblocks0\th10_2\AUC0pt7\Lambda10", ... +"Z:\PainData\Corrected_Channel_Map\L6\Cortex\m8", ... +"Z:\PainData\Corrected_Channel_Map\L6\Cortex\27.8.21"]; +anaesthesia_states = cell(size(exp_paths)); +%% +for ce = 1:numel(exp_paths) + data_dir = exp_paths(ce); + spike_file = dir(fullfile(data_dir,"*All_all_channels_clean.mat")); + if numel(spike_file)~=1 + spike_file = dir(fullfile(data_dir, "*all_channels_clean.mat")); + end + load(fullfile(spike_file.folder, spike_file.name)); + + unit_flag = sum([sortedData{:,3}] == [1;2]) > 0; + % unit_flag = [sortedData{:,3}] == 1; + spike_times = sortedData(unit_flag,2); + all_spikes = cat(1, spike_times{:}); + + bin_files = dir(fullfile(data_dir,'*.bin')); + if numel(bin_files)>=1 + bin_files = bin_files([bin_files.bytes]==max([bin_files.bytes])); + exp_duration = (bin_files.bytes/(64*2))/fs; + else + exp_duration = max(all_spikes)*1.001; + end + fr_per_unit = cellfun(@(x) numel(x)/exp_duration, spike_times); + %% + bin_size = 0.1; + bins = (bin_size/2):bin_size:exp_duration; + centres = mean([bins(1:end-1);bins(2:end)]); + + muah = histcounts(all_spikes, bins); + [b1,a1] = butter(3,[0.8,1.8]*2*bin_size,'bandpass'); + [blow, alow] = butter(2,[0.0005, 0.01]*2*bin_size,'bandpass'); + bouts = filtfilt(b1, a1, muah); + pad_size = ceil(1000/bin_size); + extra_bout = padarray(bouts(:), pad_size,"symmetric","pre"); + brain_state = filtfilt(blow, alow, abs(extra_bout)); + brain_state(1:pad_size) = []; + anaesthesia_states{ce} = brain_state; + %% + f = figure('PaperSize', [21, 14.8], 'Units', 'centimeters', ... + 'Position', [2 2 21 14.8]); + t = createtiles(f,1,5); + axs(1) = nexttile(t,1,[1,4]); + plot(axs(1),centres, muah, 'Color', (2/3)*ones(1,3), ... + 'DisplayName', 'MUA histogram'); + ylabel(axs(1),'MUA counts') + yyaxis(axs(1), "right"); + plot(axs(1), centres, zscore(brain_state), 'k','LineWidth', 2, ... + 'DisplayName', 'Anaesthesia state'); + ylabel(axs(1), 'Anaesthesia state') + legend(axs(1), 'Box', 'off', 'Color', 'none', 'Location', 'best', ... + 'AutoUpdate', 'off') + yline(axs(1), 0.85, 'k--', 'LineWidth', 1) + xlabel(axs(1), 'Time [s]'); axs(1).YAxis(2).Color=0.15*ones(1,3); + xlim(axs(1),[0,exp_duration]) + + axs(2) = nexttile(t); + jit_width = 0.33; + sc = scatter(axs(2), rand(numel(spike_times),1) * jit_width + 1-(jit_width/2), ... + fr_per_unit, 'k.', 'MarkerEdgeAlpha',0.75, 'displayname', 'Unit fr'); + hold(axs(2),"on") + boxchart(axs(2),ones(size(fr_per_unit)),fr_per_unit,"Notch","on", ... + "BoxEdgeColor","k","BoxFaceColor","none","MarkerStyle","none") + ln = plot(axs(2),[1,1]+[-1, 1]*jit_width, mean(fr_per_unit)*[1,1], "b", ... + "LineWidth", 1.5, "DisplayName", ... + sprintf("Mean %.2g Hz", mean(fr_per_unit))); + ylabel(axs(2), 'Firing rate [Hz]') + legend(axs(2), [sc,ln],'Box', 'off', 'Color', 'none', ... + 'Location', 'best', 'AutoUpdate', 'off') + set(get(axs(2),"XAxis"),"Visible", "off") + set(axs,"TickDir","out") + cleanAxis(axs); + title(t,data_dir,"interpreter","none") + %% + saveFigure(f, fullfile(data_dir,'Anaesthesia state estimation and fr'), true, true) + close(f) + clearvars -except exp_paths ce anaesthesia_states +end + +%% +nas = cellfun(@(x) zscore(x), anaesthesia_states, 'UniformOutput', false); +ths = -3.5:0.01:3.5; +props = zeros(numel(ths), numel(nas)); +ii = 1; +for cth = ths + prop = cellfun(@(x) sum(x>cth)/numel(x), nas); + props(ii,:) = prop; + ii = ii + 1; +end \ No newline at end of file From 2b1fb85d0d5171b647edf2810a147e6ab3b2e6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Thu, 15 Jan 2026 13:08:09 +0100 Subject: [PATCH 197/201] Updated threshold and few aesthetics --- Emilio/MUA_LFP_estimation.m | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/Emilio/MUA_LFP_estimation.m b/Emilio/MUA_LFP_estimation.m index 815aaf7..a421e5d 100644 --- a/Emilio/MUA_LFP_estimation.m +++ b/Emilio/MUA_LFP_estimation.m @@ -1,9 +1,12 @@ -exp_paths = ["Z:\PainData\Corrected_Channel_Map\L6\Cortex\20.8.21\KS2", ... -"Z:\PainData\Corrected_Channel_Map\L6\Cortex\26.8.21", ... -"Z:\PainData\Corrected_Channel_Map\Dual\L6_VPL\S1\Nblocks0\th10_2\AUC0pt7\Lambda10", ... -"Z:\PainData\Corrected_Channel_Map\L6\Cortex\m8", ... -"Z:\PainData\Corrected_Channel_Map\L6\Cortex\27.8.21"]; +base_path = "Z:\PainData\Corrected_Channel_Map\"; +exp_paths = base_path + ["L6\Cortex\20.8.21\KS2", ... + "L6\Cortex\26.8.21", ... + "Dual\L6_VPL\S1\Nblocks0\th10_2\AUC0pt7\Lambda10", ... + "L6\Cortex\m8", ... + "L6\Cortex\27.8.21"]; anaesthesia_states = cell(size(exp_paths)); +fullpath = @(f) fullfile(f.folder,f.name); +load_data = @(f) load(fullpath(f)); %% for ce = 1:numel(exp_paths) data_dir = exp_paths(ce); @@ -11,8 +14,10 @@ if numel(spike_file)~=1 spike_file = dir(fullfile(data_dir, "*all_channels_clean.mat")); end - load(fullfile(spike_file.folder, spike_file.name)); - + load(fullpath(spike_file)); + + cond_file = dir(fullfile(data_dir,'*analysis.mat')); + load(fullpath(cond_file)) unit_flag = sum([sortedData{:,3}] == [1;2]) > 0; % unit_flag = [sortedData{:,3}] == 1; spike_times = sortedData(unit_flag,2); @@ -54,14 +59,15 @@ ylabel(axs(1), 'Anaesthesia state') legend(axs(1), 'Box', 'off', 'Color', 'none', 'Location', 'best', ... 'AutoUpdate', 'off') - yline(axs(1), 0.85, 'k--', 'LineWidth', 1) + yline(axs(1), 0.864, 'k--', 'LineWidth', 1) xlabel(axs(1), 'Time [s]'); axs(1).YAxis(2).Color=0.15*ones(1,3); xlim(axs(1),[0,exp_duration]) axs(2) = nexttile(t); jit_width = 0.33; - sc = scatter(axs(2), rand(numel(spike_times),1) * jit_width + 1-(jit_width/2), ... - fr_per_unit, 'k.', 'MarkerEdgeAlpha',0.75, 'displayname', 'Unit fr'); + sc = scatter(axs(2), rand(numel(spike_times),1) * jit_width + ... + 1-(jit_width/2), fr_per_unit, 'k.', 'MarkerEdgeAlpha', 0.75, ... + 'displayname', 'Unit fr'); hold(axs(2),"on") boxchart(axs(2),ones(size(fr_per_unit)),fr_per_unit,"Notch","on", ... "BoxEdgeColor","k","BoxFaceColor","none","MarkerStyle","none") @@ -76,7 +82,8 @@ cleanAxis(axs); title(t,data_dir,"interpreter","none") %% - saveFigure(f, fullfile(data_dir,'Anaesthesia state estimation and fr'), true, true) + saveFigure(f, fullfile(data_dir,'Anaesthesia state estimation and fr'), ... + true, true) close(f) clearvars -except exp_paths ce anaesthesia_states end @@ -90,4 +97,7 @@ prop = cellfun(@(x) sum(x>cth)/numel(x), nas); props(ii,:) = prop; ii = ii + 1; -end \ No newline at end of file +end + +opt_th = props>((1/6)*0.99) & props <((1/6)*1.01); +th = mean(ths(any(opt_th,2))); \ No newline at end of file From 8b27805cc831f0a69e152b80c5520c02dd57751a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 16 Jan 2026 17:10:52 +0100 Subject: [PATCH 198/201] Finished version. Saved a boolean vector per condition per experiment and the boolean signal throughout the experiment duration --- Emilio/MUA_LFP_estimation.m | 45 ++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/Emilio/MUA_LFP_estimation.m b/Emilio/MUA_LFP_estimation.m index a421e5d..dcde193 100644 --- a/Emilio/MUA_LFP_estimation.m +++ b/Emilio/MUA_LFP_estimation.m @@ -11,41 +11,70 @@ for ce = 1:numel(exp_paths) data_dir = exp_paths(ce); spike_file = dir(fullfile(data_dir,"*All_all_channels_clean.mat")); - if numel(spike_file)~=1 + if numel(spike_file)~=1 spike_file = dir(fullfile(data_dir, "*all_channels_clean.mat")); end load(fullpath(spike_file)); - + cond_file = dir(fullfile(data_dir,'*analysis.mat')); load(fullpath(cond_file)) + Ns = numel(Triggers.Laser); + exp_duration = Ns/fs; unit_flag = sum([sortedData{:,3}] == [1;2]) > 0; - % unit_flag = [sortedData{:,3}] == 1; spike_times = sortedData(unit_flag,2); all_spikes = cat(1, spike_times{:}); bin_files = dir(fullfile(data_dir,'*.bin')); + %{ if numel(bin_files)>=1 bin_files = bin_files([bin_files.bytes]==max([bin_files.bytes])); exp_duration = (bin_files.bytes/(64*2))/fs; else exp_duration = max(all_spikes)*1.001; end + %} fr_per_unit = cellfun(@(x) numel(x)/exp_duration, spike_times); %% + th = 0.864; bin_size = 0.1; - bins = (bin_size/2):bin_size:exp_duration; + bins = 0:bin_size:exp_duration; centres = mean([bins(1:end-1);bins(2:end)]); muah = histcounts(all_spikes, bins); [b1,a1] = butter(3,[0.8,1.8]*2*bin_size,'bandpass'); [blow, alow] = butter(2,[0.0005, 0.01]*2*bin_size,'bandpass'); bouts = filtfilt(b1, a1, muah); - pad_size = ceil(1000/bin_size); - extra_bout = padarray(bouts(:), pad_size,"symmetric","pre"); + pad_size = ceil(1000/bin_size); % 1000 seconds + extra_bout = padarray(bouts(:), pad_size, "symmetric", "pre"); brain_state = filtfilt(blow, alow, abs(extra_bout)); brain_state(1:pad_size) = []; anaesthesia_states{ce} = brain_state; %% + sync_flag = zscore(brain_state)>th; + anaObj = StepWaveform(sync_flag,1/bin_size); + anaObj.MinIEI = 1; + oo_ana_triggers = anaObj.Triggers*bin_size; + tx = ((1:Ns)-0.5)/fs; + ana_signal = false(1,Ns); + for cr = 1:size(oo_ana_triggers,1) + ana_signal = ana_signal | ... + (tx>=oo_ana_triggers(cr,1) & tx<=oo_ana_triggers(cr,2)); + end + Triggers.Anaesthesia = ana_signal; + cons_cond = contains({Conditions.name}, 'block', 'IgnoreCase', true); + sync_flag = cell(sum(cons_cond),1); + ii = 1; + for ccond = find(cons_cond) + trig_times = Conditions(ccond).Triggers/fs; + sync_state = any(trig_times(:,1) >= oo_ana_triggers(:,1)' & ... + trig_times(:,1) < oo_ana_triggers(:,2)', 2); + sync_flag{ii} = sync_state; + ii = ii + 1; + end + save(fullpath(cond_file), 'sync_flag', 'Triggers', '-append') + % Conditions_state(arrayfun(@(x) numel(x.Triggers)==0, ... + % Conditions_state)) = []; + %% f = figure('PaperSize', [21, 14.8], 'Units', 'centimeters', ... 'Position', [2 2 21 14.8]); t = createtiles(f,1,5); @@ -82,10 +111,10 @@ cleanAxis(axs); title(t,data_dir,"interpreter","none") %% - saveFigure(f, fullfile(data_dir,'Anaesthesia state estimation and fr'), ... + saveFigure(f, fullfile(data_dir,'Anaesthesia state and fr'), ... true, true) close(f) - clearvars -except exp_paths ce anaesthesia_states + clearvars -except exp_paths ce anaesthesia_states fullpath load_data end %% From 58badeb6240ec6f6e3930d5bfda345e99b07bfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Tue, 20 Jan 2026 17:50:16 +0100 Subject: [PATCH 199/201] Moved threshold to 0 Splitting the states 50/50 into synchronised and desynchronised states. --- Emilio/MUA_LFP_estimation.m | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Emilio/MUA_LFP_estimation.m b/Emilio/MUA_LFP_estimation.m index dcde193..04772bc 100644 --- a/Emilio/MUA_LFP_estimation.m +++ b/Emilio/MUA_LFP_estimation.m @@ -35,7 +35,7 @@ %} fr_per_unit = cellfun(@(x) numel(x)/exp_duration, spike_times); %% - th = 0.864; + th = 0; bin_size = 0.1; bins = 0:bin_size:exp_duration; centres = mean([bins(1:end-1);bins(2:end)]); @@ -50,6 +50,7 @@ brain_state(1:pad_size) = []; anaesthesia_states{ce} = brain_state; %% + sync_flag = zscore(brain_state)>th; anaObj = StepWaveform(sync_flag,1/bin_size); anaObj.MinIEI = 1; @@ -72,23 +73,28 @@ ii = ii + 1; end save(fullpath(cond_file), 'sync_flag', 'Triggers', '-append') - % Conditions_state(arrayfun(@(x) numel(x.Triggers)==0, ... - % Conditions_state)) = []; %% f = figure('PaperSize', [21, 14.8], 'Units', 'centimeters', ... 'Position', [2 2 21 14.8]); t = createtiles(f,1,5); axs(1) = nexttile(t,1,[1,4]); - plot(axs(1),centres, muah, 'Color', (2/3)*ones(1,3), ... + plot(axs(1), centres, muah, 'Color', (2/3)*ones(1,3), ... 'DisplayName', 'MUA histogram'); ylabel(axs(1),'MUA counts') yyaxis(axs(1), "right"); plot(axs(1), centres, zscore(brain_state), 'k','LineWidth', 2, ... - 'DisplayName', 'Anaesthesia state'); - ylabel(axs(1), 'Anaesthesia state') + 'DisplayName', 'LFP estimation'); + ylabel(axs(1), '1\ Hz envelope', 'Interpreter', 'latex') + y = axs(1).YLim; + y2 = repmat(y(:), [1,size(oo_ana_triggers,1)]); + y2 = padarray(y2,2,"symmetric","post"); + x = padarray(oo_ana_triggers,[0,1],"symmetric","both")'; + patch(axs(1),x,y2,ones(size(x)), 'EdgeColor', 'none', ... + 'FaceColor', 'b', 'FaceAlpha', 0.15, ... + 'DisplayName', 'Synchronised state') legend(axs(1), 'Box', 'off', 'Color', 'none', 'Location', 'best', ... 'AutoUpdate', 'off') - yline(axs(1), 0.864, 'k--', 'LineWidth', 1) + yline(axs(1), th, 'k--', 'LineWidth', 1) xlabel(axs(1), 'Time [s]'); axs(1).YAxis(2).Color=0.15*ones(1,3); xlim(axs(1),[0,exp_duration]) @@ -111,13 +117,14 @@ cleanAxis(axs); title(t,data_dir,"interpreter","none") %% - saveFigure(f, fullfile(data_dir,'Anaesthesia state and fr'), ... - true, true) + saveFigure(f, fullfile(data_dir,'LFP estimation and fr'), ... + true, false) close(f) clearvars -except exp_paths ce anaesthesia_states fullpath load_data end %% +prop_th = 1/2; nas = cellfun(@(x) zscore(x), anaesthesia_states, 'UniformOutput', false); ths = -3.5:0.01:3.5; props = zeros(numel(ths), numel(nas)); @@ -128,5 +135,5 @@ ii = ii + 1; end -opt_th = props>((1/6)*0.99) & props <((1/6)*1.01); +opt_th = props>(prop_th*0.99) & props <(prop_th*1.01); th = mean(ths(any(opt_th,2))); \ No newline at end of file From 22db20b42db90cb1c28b41208e268d1293496db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Fri, 23 Jan 2026 16:00:36 +0100 Subject: [PATCH 200/201] Create homogenise_images_4_sharcq.m --- Emilio/homogenise_images_4_sharcq.m | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Emilio/homogenise_images_4_sharcq.m diff --git a/Emilio/homogenise_images_4_sharcq.m b/Emilio/homogenise_images_4_sharcq.m new file mode 100644 index 0000000..ce5bd2f --- /dev/null +++ b/Emilio/homogenise_images_4_sharcq.m @@ -0,0 +1,38 @@ + +fullpath = @(x) fullfile(x.folder, x.name); +get_img_size = @(x) [x.getTag("ImageWidth"), x.getTag("ImageLength")]; +fnOpts = {'UniformOutput', false}; +ideal_prop = 57/40; + + +img_dir = "Z:\Leonie\AC\M65\M65 ThSC"; +original_resolution = 2.302; +desired_resolution = 10; +homogenised_img_folder = fullfile(img_dir, 'Homogenised and downsampled'); +if ~exist(homogenised_img_folder,"dir") + mkdir(homogenised_img_folder) +end +scaling_factor = original_resolution/desired_resolution; + +img_paths = dir(fullfile(img_dir, "*Merged_overlay.tif")); +roi_paths = dir(fullfile(img_dir, "*Merged_overlay ROIs.csv")); +t_objs = arrayfun(@(x) Tiff(fullpath(x), 'r'), img_paths); +img_size = arrayfun(@(x) get_img_size(x), t_objs, fnOpts{:}); +arrayfun(@(x) x.close, t_objs); +img_size = cat(1, img_size{:}); +img_prop = img_size(:,1)./img_size(:,2); +final_sz = ceil(max(img_size(:,1)) * [1, (1/ideal_prop)]); +for ci = 1:numel(img_paths) + shift_px = [floor((final_sz([2,1]) - img_size(ci,[2,1]))/2)]; + img = imread(fullpath(img_paths(ci))); + img2 = padarray(img, [shift_px, 0], 0, 'both'); + img2 = imresize(img2, scaling_factor); + roi_table = readtable(fullpath(roi_paths(ci)), ... + 'Delimiter',',','VariableNamingRule','preserve'); + roi_table{:,{'X','Y'}} = round((roi_table{:,{'X','Y'}} + ... + shift_px([2,1]))*scaling_factor); + imwrite(img2,fullfile(homogenised_img_folder, ... + img_paths(ci).name),'tif', 'WriteMode', 'overwrite') + writetable(roi_table,fullfile(homogenised_img_folder, ... + roi_paths(ci).name),'WriteVariableNames',true) +end \ No newline at end of file From 2f72cfa34539d22e11bb08247fbc6688ff3e321e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Isa=C3=ADas-Camacho?= Date: Mon, 9 Feb 2026 17:45:05 +0100 Subject: [PATCH 201/201] Mouse 68 --- Emilio/homogenise_images_4_sharcq.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Emilio/homogenise_images_4_sharcq.m b/Emilio/homogenise_images_4_sharcq.m index ce5bd2f..565a978 100644 --- a/Emilio/homogenise_images_4_sharcq.m +++ b/Emilio/homogenise_images_4_sharcq.m @@ -5,8 +5,8 @@ ideal_prop = 57/40; -img_dir = "Z:\Leonie\AC\M65\M65 ThSC"; -original_resolution = 2.302; +img_dir = fullfile("Z:\Leonie\AC\M68\M68 fit"); +original_resolution = 1.15; desired_resolution = 10; homogenised_img_folder = fullfile(img_dir, 'Homogenised and downsampled'); if ~exist(homogenised_img_folder,"dir") @@ -15,7 +15,7 @@ scaling_factor = original_resolution/desired_resolution; img_paths = dir(fullfile(img_dir, "*Merged_overlay.tif")); -roi_paths = dir(fullfile(img_dir, "*Merged_overlay ROIs.csv")); +roi_paths = dir(fullfile(img_dir, "*Merged_overlay.csv")); t_objs = arrayfun(@(x) Tiff(fullpath(x), 'r'), img_paths); img_size = arrayfun(@(x) get_img_size(x), t_objs, fnOpts{:}); arrayfun(@(x) x.close, t_objs); @@ -27,6 +27,7 @@ img = imread(fullpath(img_paths(ci))); img2 = padarray(img, [shift_px, 0], 0, 'both'); img2 = imresize(img2, scaling_factor); + img2 = img2(1:800,1:1140,:); roi_table = readtable(fullpath(roi_paths(ci)), ... 'Delimiter',',','VariableNamingRule','preserve'); roi_table{:,{'X','Y'}} = round((roi_table{:,{'X','Y'}} + ...