Skip to content

Commit

Permalink
Merge pull request #41 from SCIInstitute/scripting
Browse files Browse the repository at this point in the history
Scripting
  • Loading branch information
jessdtate authored Jul 23, 2019
2 parents 9eead63 + 63d6b8e commit a3b32f9
Show file tree
Hide file tree
Showing 29 changed files with 2,384 additions and 1,603 deletions.
103 changes: 57 additions & 46 deletions SOURCE/Fiducializing/autoProcessSignal.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@


function success = autoProcessSignal()
% do all the autoprocessing. Use the fiducials in the fiducialed beat to find all other beats of
% that run and fiducialise those beats, too. Handle & save the autoprocessed beats just like the
% beat done by the user.
% do all the autoprocessing. Use the fiducials in the fiducialed beat to find
% all other beats of that run and fiducialise those beats, too. Handle & save
% the autoprocessed beats just like the beat done by the user.

%set up globals
clear global AUTOPROCESSING % just in case, so previous stuff doesnt mess anything up
global TS SCRIPTDATA AUTOPROCESSING

unslicedDataIndex = SCRIPTDATA.unslicedDataIndex;
templateFids = TS{SCRIPTDATA.CURRENTTS}.fids;
templateBeatEnvelope = [TS{SCRIPTDATA.CURRENTTS}.selframes(1), TS{SCRIPTDATA.CURRENTTS}.selframes(2)];
templateBeatEnvelope = [TS{SCRIPTDATA.CURRENTTS}.selframes(1), ...
TS{SCRIPTDATA.CURRENTTS}.selframes(2)];
badLeads = (find(TS{SCRIPTDATA.unslicedDataIndex}.leadinfo > 0))';


Expand All @@ -55,7 +56,8 @@
settings.RunNumber = SCRIPTDATA.ACQNUM;


[AUTOPROCESSING.beats, AUTOPROCESSING.allFids, info, success] = getBeatsAndFids(TS{unslicedDataIndex}.potvals, templateBeatEnvelope, templateFids, badLeads, settings);
[AUTOPROCESSING.beats, AUTOPROCESSING.allFids, info, success] = getBeatsAndFids(...
TS{unslicedDataIndex}.potvals, templateBeatEnvelope, templateFids, badLeads, settings);
if ~success, return, end

AUTOPROCESSING.leadsToAutofiducialize = info.leadsToAutofiducialize;
Expand All @@ -76,15 +78,18 @@
success = 1;
return;
end
save(SCRIPTDATA.SCRIPTFILE,'SCRIPTDATA') % save settings.. in case user made a change in autofiducializing window
% save settings.. in case user made a change in autofiducializing window
save(SCRIPTDATA.SCRIPTFILE,'SCRIPTDATA')
end

%%%%% main loop: process each beat.
global times % to do: remove this? this global is only there to measure time efficiency..
% to do: remove this? this global is only there to measure time efficiency..
global times
times=struct();
times(1).count=1;

for beatNumber=2:length(AUTOPROCESSING.beats) % skip the first beat, as this is the user fiducialized one
% skip the first beat, as this is the user fiducialized one
for beatNumber=2:length(AUTOPROCESSING.beats)
b=tic;
success = processBeat(beatNumber);
t2=toc(b);
Expand All @@ -103,31 +108,14 @@
























%%%%%%%%%%% functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function getFaultyBeats
% determine the beats, where autoprocessing didn't quite work ( eg those with very high variance)
% determine the beats, where autoprocessing didn't quite work
% ( eg those with very high variance)
% fill AUTOPROCESSING.faultyBeatInfo and AUTOPROCESSING.faultyBeatIndeces with info

global AUTOPROCESSING SCRIPTDATA
Expand All @@ -141,8 +129,11 @@
%%%% set up variables
treshold_variance = SCRIPTDATA.TRESHOLD_VAR;
faultyBeatIndeces =[]; % the indeces in .Beats of faulty beats
faultyBeatInfo = {}; % which fiducials (which types) in the beat are bad? e.g faultyBeatInfo = { [2 4], [5 6 7],.. }
faultyBeatValues = {}; % correspondes with faultyBeatInfo, but contains the value instead of type
% which fiducials (which types) in the beat are bad?
% e.g faultyBeatInfo = { [2 4], [5 6 7],.. }
faultyBeatInfo = {};
% correspondes with faultyBeatInfo, but contains the value instead of type
faultyBeatValues = {};
numBeats = length(AUTOPROCESSING.beats);

if ~isempty(AUTOPROCESSING.allFids)
Expand All @@ -163,7 +154,8 @@
faultyBeatInfo{end+1} = faultyFids;

%%%% get the faultyValues of that faulty beat
faultyIndeces = faultyIndeces + numFids; % now faultyIndeces are indeces of global bad fiducials
% now faultyIndeces are indeces of global bad fiducials
faultyIndeces = faultyIndeces + numFids;
faultyValues = [AUTOPROCESSING.allFids{beatNumber}(faultyIndeces).value];
faultyBeatValues{end+1}=faultyValues;
end
Expand Down Expand Up @@ -191,7 +183,8 @@
%%%% slice "complete ts" into beat (in TS{newBeatIdx} )
a=tic;
newBeatIdx=tsNew(1);
beatframes=AUTOPROCESSING.beats{beatNumber}(1):AUTOPROCESSING.beats{beatNumber}(2); % all time frames of the beat
% all time frames of the beat
beatframes=AUTOPROCESSING.beats{beatNumber}(1):AUTOPROCESSING.beats{beatNumber}(2);

TS{newBeatIdx}=TS{SCRIPTDATA.unslicedDataIndex};
TS{newBeatIdx}.potvals=TS{newBeatIdx}.potvals(:,beatframes);
Expand All @@ -218,7 +211,8 @@
for fidIdx=1:length(fids)
fids(fidIdx).value=fids(fidIdx).value - reference + 1; % fids now in relative frame
end
if isfield(fids,'variance'), fids=rmfield(fids,'variance'); end %variance not wanted in the output
%variance not wanted in the output
if isfield(fids,'variance'), fids=rmfield(fids,'variance'); end
TS{newBeatIdx}.fids=fids;
t=toc(a);
times(times(1).count).b_MakeFidsLocalAndRemvoeVariance=t;
Expand Down Expand Up @@ -276,14 +270,16 @@
%%%% split TS{newIdx} into numGroups smaller ts in grIndices
splitgroup = [];
for p=1:length(SCRIPTDATA.GROUPNAME{SCRIPTDATA.CURRENTRUNGROUP})
if SCRIPTDATA.GROUPDONOTPROCESS{SCRIPTDATA.CURRENTRUNGROUP}{p} == 0, splitgroup = [splitgroup p]; end
if SCRIPTDATA.GROUPDONOTPROCESS{SCRIPTDATA.CURRENTRUNGROUP}{p} == 0, ...
splitgroup = [splitgroup p]; end
end
% splitgroup is now eg [1 3] if there are 3 groups but the 2 should
% not be processed
channels=SCRIPTDATA.GROUPLEADS{SCRIPTDATA.CURRENTRUNGROUP}(splitgroup);
grIndices = tsSplitTS(newBeatIdx, channels);
% update the filenames (add '-groupextension' to filename)
tsDeal(grIndices,'filename',ioUpdateFilename('.mat',filename,SCRIPTDATA.GROUPEXTENSION{SCRIPTDATA.CURRENTRUNGROUP}(splitgroup)));
tsDeal(grIndices,'filename',ioUpdateFilename('.mat',filename,SCRIPTDATA.GROUPEXTENSION{...
SCRIPTDATA.CURRENTRUNGROUP}(splitgroup)));
tsClear(newBeatIdx);

t=toc(a);
Expand All @@ -296,6 +292,7 @@
ts=TS{grIdx};
fullFilename=fullfile(SCRIPTDATA.MATODIR, ts.filename);
fprintf('Saving file: %s\n',ts.filename)
SCRIPTDATA.OUTFILENAME{end+1} = ts.filename;
save(fullFilename,'ts','-v6')
end
t=toc(a);
Expand All @@ -309,21 +306,24 @@
if SCRIPTDATA.DO_INTEGRALMAPS == 1
a=tic;
if SCRIPTDATA.DO_DETECT == 0
msg=sprintf('Need fiducials (at least QRS wave or T wave) to do integral maps for %s. Aborting..', filename);
msg=sprintf(['Need fiducials (at least QRS wave or T wave) to do integral ' ...
'maps for %s. Aborting..'], filename);
errordlg(msg)
success = 0;
return
end
mapindices = fidsIntAll(grIndices);
if length(splitgroup)~=length(mapindices)
msg=sprintf('Fiducials (QRS wave or T wave) necessary to do integral maps. However, for %s there are no fiducials for all groups. Aborting...',filename);
msg=sprintf(['Fiducials (QRS wave or T wave) necessary to do integral maps. '...
'However, for %s there are no fiducials for all groups. Aborting...'],filename);
errordlg(msg)
success = 0;
return
end


fnames=ioUpdateFilename('.mat',filename,SCRIPTDATA.GROUPEXTENSION{SCRIPTDATA.CURRENTRUNGROUP}(splitgroup),'-itg');
fnames=ioUpdateFilename('.mat',filename,SCRIPTDATA.GROUPEXTENSION{...
SCRIPTDATA.CURRENTRUNGROUP}(splitgroup),'-itg');

tsDeal(mapindices,'filename',fnames);
tsSet(mapindices,'newfileext','');
Expand All @@ -333,6 +333,7 @@
ts=TS{mapIdx};
fullFilename=fullfile(SCRIPTDATA.MATODIR, ts.filename);
fprintf('Saving file: %s\n',ts.filename)
SCRIPTDATA.ITGFILENAME{end+1} = ts.filename;
save(fullFilename,'ts','-v6')
end
tsClear(mapindices);
Expand All @@ -349,22 +350,25 @@
a=tic;

if SCRIPTDATA.DO_DETECT == 0 % 'Detect fiducials must be selected'
errordlg('Fiducials needed to do Activationsmaps! Select the ''Do Fiducials'' button to do Activationmaps. Aborting...')
errordlg(['Fiducials needed to do Activationsmaps! Select the ''Do Fiducials'' '...
'button to do Activationmaps. Aborting...'])
return
end

%%%% make new ts at TS(mapindices). That new ts is like the old
%%%% one, but has ts.potvals=[act rec act-rec]
[mapindices, success] = sigActRecMap(grIndices);
if ~success,return, end
tsDeal(mapindices,'filename',ioUpdateFilename('.mat',filename,SCRIPTDATA.GROUPEXTENSION{SCRIPTDATA.CURRENTRUNGROUP}(splitgroup),'-ari'));
tsDeal(mapindices,'filename',ioUpdateFilename('.mat',filename,SCRIPTDATA.GROUPEXTENSION{...
SCRIPTDATA.CURRENTRUNGROUP}(splitgroup),'-ari'));
tsSet(mapindices,'newfileext','');

%%%% save the 'new act/rec' ts as eg 'Run0009-gr1-ari.mat and clearTS{mapindex}
for mapIdx=mapindices
ts=TS{mapIdx};
fullFilename=fullfile(SCRIPTDATA.MATODIR, ts.filename);
fprintf('Saving file: %s\n',ts.filename)
SCRIPTDATA.ARIFILENAME{end+1} = ts.filename;
save(fullFilename,'ts','-v6')
end
tsClear(mapindices);
Expand Down Expand Up @@ -396,7 +400,8 @@
qstart_indeces=find([TS{newBeatIdx}.fids.type]==2);
qend_indeces=find([TS{newBeatIdx}.fids.type]==4);
if isempty(qstart_indeces) || isempty(qend_indeces)
msg = sprintf('There is no qrs-wave for the file %s. Therefore, activation detection cannot be done for this file. Aborting...',TS{newBeatIdx}.filename);
msg = sprintf(['There is no qrs-wave for the file %s. Therefore, activation '...
'detection cannot be done for this file. Aborting...'],TS{newBeatIdx}.filename);
errordlg(msg)
success = 0;
return
Expand Down Expand Up @@ -433,7 +438,8 @@
if ~success, return, end

if any((qe-qs) < 15)
msg = sprintf('The QRS-wave in beat %d is to small! This often causes the activation detetection to fail',newBeatIdx);
msg = sprintf(['The QRS-wave in beat %d is to small! This often causes the '...
'activation detetection to fail'],newBeatIdx);
errordlg(msg)
success = 0 ;
return
Expand All @@ -442,8 +448,10 @@
try
for leadNumber=1:numchannels
%for each lead in each group = for all leads..
%[act(leadNumber)] = (actFktHandle(TS{newBeatIdx}.potvals(leadNumber,qs(leadNumber):qe(leadNumber)),win,deg)-1)/SCRIPTDATA.SAMPLEFREQ + qs(leadNumber);
[act(leadNumber)] = (actFktHandle(TS{newBeatIdx}.potvals(leadNumber,qs(leadNumber):qe(leadNumber)),win,deg)-1) + qs(leadNumber);
%[act(leadNumber)] = (actFktHandle(TS{newBeatIdx}.potvals(leadNumber,...
%qs(leadNumber):qe(leadNumber)),win,deg)-1)/SCRIPTDATA.SAMPLEFREQ + qs(leadNumber);
[act(leadNumber)] = (actFktHandle(TS{newBeatIdx}.potvals(leadNumber,...
qs(leadNumber):qe(leadNumber)),win,deg)-1) + qs(leadNumber);
end
catch
errordlg('The selected function used to find the activations caused an error. Aborting...')
Expand Down Expand Up @@ -477,7 +485,8 @@
tStartIndeces=find([TS{newBeatIdx}.fids.type]==5);
tEndIndeces=find([TS{newBeatIdx}.fids.type]==7);
if isempty(tStartIndeces) || isempty(tEndIndeces)
msg = sprintf('There is no t-wave for the file %s. Therefore, recovery detection cannot be done for this file. Aborting...',TS{newBeatIdx}.filename);
msg = sprintf(['There is no t-wave for the file %s. Therefore, recovery '...
'detection cannot be done for this file. Aborting...'],TS{newBeatIdx}.filename);
errordlg(msg)
success = 0;
return
Expand Down Expand Up @@ -512,8 +521,10 @@
if ~success, return, end
try
for leadNumber=1:numchannels
%rec(leadNumber) = recFktHandle(TS{newBeatIdx}.potvals(leadNumber,ts(leadNumber):te(leadNumber)),win,deg)/SCRIPTDATA.SAMPLEFREQ + ts(leadNumber);
rec(leadNumber) = recFktHandle(TS{newBeatIdx}.potvals(leadNumber,ts(leadNumber):te(leadNumber)),win,deg) + ts(leadNumber);
%rec(leadNumber) = recFktHandle(TS{newBeatIdx}.potvals(leadNumber,...
%ts(leadNumber):te(leadNumber)),win,deg)/SCRIPTDATA.SAMPLEFREQ + ts(leadNumber);
rec(leadNumber) = recFktHandle(TS{newBeatIdx}.potvals(leadNumber,...
ts(leadNumber):te(leadNumber)),win,deg) + ts(leadNumber);

end
catch
Expand Down
58 changes: 58 additions & 0 deletions SOURCE/Functions/app/CloseFcn.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
% MIT License
%
% Copyright (c) 2017 The Scientific Computing and Imaging Institute
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
% SOFTWARE.




function CloseFcn(~)
%callback function for the 'close' buttons.
global SCRIPTDATA PROCESSINGDATA FIDSDISPLAY SLICEDISPLAY TS

%%%% save setting
try
if ~isempty(SCRIPTDATA.SCRIPTFILE)
saveSettings
disp('Saved SETTINGS before closing PFEIFER')
else
disp('PFEIFER closed without saving SETTINGS')
end
catch
%do nothing
end

%%%% delete all gui figures
delete(findobj(allchild(0),'tag','PROCESSINGSCRIPTMENU'));
delete(findobj(allchild(0),'tag','PROCESSINGSCRIPTSETTINGS'));
delete(findobj(allchild(0),'tag','SLICEDISPLAY'));
delete(findobj(allchild(0),'tag','FIDSDISPLAY'));

%%%% delete all waitbars
waitObjs = findall(0,'type','figure','tag','waitbar');
delete(waitObjs);

%%%% delete all error dialog windows
errordlgObjs = findall(0,'type','figure','tag','Msgbox_Error Dialog');
delete(errordlgObjs);

%%%% clear globals
clear global FIDSDISPLAY SLICEDISPLAY TS
end
Loading

0 comments on commit a3b32f9

Please sign in to comment.