How do I extract the firing threshold value from an action potential phase plot?

15 Ansichten (letzte 30 Tage)
Hi,
I am managing to produce a phase plot and I can zoom into it to see a closely approximated value for the firing threshold (first kink with a blue arrow pointing to in the attached figure). How do I extract this value without using ginput?
My code to produce the figure and extract the value using ginput:
% Roksana's script to plot .smr average AP phase plot
% 20210127
% For troubleshooting analysis - cleans the workspace
clear
close all
%Import data
load('C:\xyz.mat')
%Define channel to plot
data = xyz;
vm = data.values;
%scale x-axis by interval
t = linspace(0,length(vm)*data.interval,length(vm));
%derive membrane potential
dA = diff(data.values);
%omit last value so vectors are of equal length
data.values(end)=[];
%plot derivative dV/dt over Vm
figure;
plot(data.values,dA);
xlabel('Membrane Potential (Vm)');
ylabel('dV/dt');
title('Phase Plot');
%find firing threshold
zoom on;
pause()
zoom off;
[x, ~] = ginput
zoom out;
  2 Kommentare
Roksana Khalid
Roksana Khalid am 2 Feb. 2021
Yes, same topic and data.
The membrane potential value (x-axis) I get from here corresponds to the y-values I want to set on the plot in the other question.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Mathieu NOE
Mathieu NOE am 2 Feb. 2021
hello again....
so my second submission for you today !
attached also 2 subfunction for crossing points computation and a better derivative method
i used a bit of smoothing befor the derivation to improve the quality of the data , especially in the "corners".
it's more or less a second alternative to the technique employed in the other post (BTW you could here also compute width and area if needed)
%Import data
load('xyz.mat')
%Define channel to plot
% data = xyz;
% vm = data.values;
% S2C1_17082020_WM_apomorphine_20uM_Ch1 =
%
% struct with fields:
%
% title: 'voltage'
% comment: 'No comment'
% interval: 4.0000e-05
% scale: 0.0153
% offset: 0
% units: 'mV'
% start: 0
% length: 1122
% values: [1122×1 double]
vm = S2C1_17082020_WM_apomorphine_20uM_Ch1.values;
samples = length(vm);
dt = S2C1_17082020_WM_apomorphine_20uM_Ch1.interval;
t_final = samples*dt;
%scale x-axis by interval
t = linspace(0, t_final,samples);
% smoothin a bit the data
vm_smoo = sgolayfilt(vm,1,15);
figure(1);
plot(t,vm,'b',t,vm_smoo,'r');
ylabel('V (mV)');
xlabel('Time (s)');
legend('raw','sgolay filtered');
title('Membrane potential')
% compute first derivative on raw and smoothed data
[dvm, ddvm] = firstsecondderivatives(t,vm);
[dvm_smoo, ddvm_smoo] = firstsecondderivatives(t,vm_smoo);
% 1st knee point has slope approx 1/1.5 of max slope (positive threshold, positive slope)
% 2nd knee point has slope approx 1/10th of max slope (negative threshold, positive slope)
a_pos1 = 1.5;
pos_slope_max = max(dvm_smoo(dvm_smoo>0));
pos_slope_trigger = pos_slope_max/a_pos1;
a_pos2 = 10;
neg_slope_max = min(dvm_smoo(dvm_smoo<0));
neg_slope_trigger = neg_slope_max/a_pos2;
% use crossing_V7 function to find and interpolate crossing points
[ind_pos1,t0_pos1,s0_pos1,~,~,~] = crossing_V7(dvm_smoo,t,pos_slope_trigger,'linear');
[ind_pos2,t0_pos2,s0_pos2,~,~,~] = crossing_V7(dvm_smoo,t,neg_slope_trigger,'linear');
% select first one (can be multiple if measurement noise - shoudn't be especially after filtering)
t0_pos1 = t0_pos1(1);
t0_pos2 = t0_pos2(1);
vm_knee1 = interp1(t,vm,t0_pos1,'linear');
vm_knee2 = interp1(t,vm,t0_pos2,'linear');
dvm_knee1 = interp1(t,dvm,t0_pos1,'linear');
dvm_knee2 = interp1(t,dvm,t0_pos2,'linear');
figure(2);
plot(t,vm,'b',t0_pos1,vm_knee1,'+r',t0_pos2,vm_knee2,'+g')
ylabel('V (mV)')
xlabel('Time (s)')
title('Membrane potential')
figure(3);
plot(vm,dvm,'b',vm_knee1,dvm_knee1,'+r',vm_knee2,dvm_knee2,'+g')
xlabel('Voltage (mV)')
ylabel('dV/dt (mV/s)')
title('Membrane potential')
  3 Kommentare
Mathieu NOE
Mathieu NOE am 3 Feb. 2021
hello again
see first my answer in the other post
fine tunong my slope threshold to 7e3 mV/s led to find the exact point your showing
hope this helps
%Import data
load('xyz.mat')
% load('AP2.mat')
vm = S2C1_17082020_WM_apomorphine_20uM_Ch1.values;
samples = length(vm);
dt = S2C1_17082020_WM_apomorphine_20uM_Ch1.interval;
t_final = samples*dt;
%scale x-axis by interval
t = linspace(0, t_final,samples);
% compute first derivative on data
[dvm, ddvm] = firstsecondderivatives(t,vm);
figure(1);
subplot(2,1,1),plot(t,vm,'b');
ylabel('V (mV)');
subplot(2,1,2),plot(t,dvm,'b');
ylabel('dV/dt (mV/s)');
xlabel('Time (s)');
title('Membrane potential')
% 1st knee point has slope approx 1/N th of max slope (positive threshold, positive slope)
% 2nd knee point has slope approx 1/N th of max slope (negative threshold, positive slope)
% a_pos1 = 150;
% pos_slope_max = max(dvm(dvm>=0));
% pos_slope_trigger = pos_slope_max/a_pos1; % 4e3
pos_slope_trigger = 7e3;
% a_pos2 = 25;
% neg_slope_max = min(dvm(dvm<=0));
% neg_slope_trigger = neg_slope_max/a_pos2; % -4e3
neg_slope_trigger = -7e3;
indpos = find(dvm>=pos_slope_trigger)
t0_pos1 = t(indpos(1));
indneg = find(dvm<=neg_slope_trigger)
t0_pos2 = t(indneg(end));
vm_knee1 = interp1(t,vm,t0_pos1,'linear');
vm_knee2 = interp1(t,vm,t0_pos2,'linear');
dvm_knee1 = interp1(t,dvm,t0_pos1,'linear');
dvm_knee2 = interp1(t,dvm,t0_pos2,'linear');
figure(2);
plot(t,vm,'b',t0_pos1,vm_knee1,'+r',t0_pos2,vm_knee2,'+g')
ylabel('V (mV)')
xlabel('Time (s)')
title('Membrane potential')
figure(3);
plot(vm,dvm,'b',vm_knee1,dvm_knee1,'+r',vm_knee2,dvm_knee2,'+g')
xlabel('Voltage (mV)')
ylabel('dV/dt (mV/s)')
title('Membrane potential')

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Image Processing Toolbox finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by