Cerebral Haemodynamic Autoregulatory Information System GUI 1.0.0

File: <base>/CHARIS_GUI_CODE/CHARISGUIicpEventFinder.m (5,916 bytes)
function [obj] = CHARISGUIicpEventFinder(patientID,rawICP,rawTime,thresholdPressure,minEventTime,minPreEventTime)

%THIS VERSION OF icpEventFinder IS TO BE USED SOLELY FOR THE CHARIS GUI


%{

    make sure icp data is in mmHg before input
    rawTime must be in seconds
    thresholdPressure must be in mmHg
    minEventTime and minPreEventTime must be in minutes
    eventPreTime and eventTimeLengths are in minutes
    outTime is in seconds

%}

if(length(rawICP)==length(rawTime))
    %average every minute.  assumes 50hz
    [meanM,varM,x,~] = statEveryK(rawICP,50*60);
    
    %adjust the mean
    lowVarMeanX = find(varM<50);
    lowVarMean = meanM(lowVarMeanX);
    adjustedMean = interp1(lowVarMeanX,lowVarMean,1:length(meanM));
    
    %Find possible event start locations
    eventThresholdPressure = thresholdPressure;
    highX = find(adjustedMean>=eventThresholdPressure);
    DhighX = diff(highX);
    highXstarters = [0,find(DhighX > 1)]+1;
    highXstartersCount = zeros(1,length(highXstarters));
    for starter = 1:length(highXstarters)-1
        highXstartersCount(starter) = length(find(DhighX(highXstarters(starter):highXstarters(starter+1)-1)==1));
    end
    highXstartersCount(end) = length(find(DhighX(highXstarters(end):end)==1));
    highXlocations = highX(highXstarters);
    
    %Choose the possible events that last for n minutes or more
    nMinutes = minEventTime;
    eventLocations = highXlocations(find(highXstartersCount>=nMinutes));
    eventTimeLengths = highXstartersCount(find(highXstartersCount>=nMinutes));
    
    %Choose the events that proceed a segment of regular icp
    regTimeThresh = minPreEventTime;
    regLowThresh = 0;
    eventRegTimeLengths = zeros(1,length(eventLocations));
    tempSeg = adjustedMean(1:eventLocations(1));
    eventRegTimeLengths(1) = backBandCounter(tempSeg(1:end-1),regLowThresh,eventThresholdPressure);
    for event = 2:length(eventLocations)
        tempSeg = adjustedMean(eventLocations(event-1):eventLocations(event));
        eventRegTimeLengths(event) = backBandCounter(tempSeg(1:end-1),regLowThresh,eventThresholdPressure);
    end
    eventsWithReg = find(eventRegTimeLengths>=regTimeThresh);
    eventLocations = eventLocations(eventsWithReg);
    eventTimeLengths = eventTimeLengths(eventsWithReg);
    
    outIndex = x(eventLocations);
    outTime = rawTime(x(eventLocations));
    eventPreTime = eventRegTimeLengths(eventsWithReg);
    
    %Go through each event
    goodEvents = ones(length(eventLocations),1);
    set(0,'DefaultFigureWindowStyle','docked');
    figure;
    
    for event = 1:length(eventLocations)
        clc;
        domain = x(eventLocations(event)):x(eventLocations(event)+eventTimeLengths(event));
        plot(rawTime(domain),rawICP(domain));
        hold on;
        plot(rawTime(x),adjustedMean,'g');
        axis([rawTime(x(eventLocations(event)-eventPreTime(event))) rawTime(x(eventLocations(event)+eventTimeLengths(event))) 0 50])
        xlabel('Time in seconds');
        ylabel('mmHg');
        title(sprintf('Please confirm if this is an event. (Enter 1 for yes, 2 for no) \n'));
        zoom xon;
        pan xon;
        hold off;%hold here
        prompt = 'Does this event make sense? Enter 1 for yes, 2 for no:';
        answer = input(prompt);
        if(answer == 2)
            goodEvents(event)=0;
        end
    end
    close
    outIndex = outIndex(find(goodEvents==1));
    outTime = outTime(find(goodEvents==1));
    eventPreTime = eventPreTime(find(goodEvents==1));
    eventTimeLengths = eventTimeLengths(find(goodEvents==1));
    
    
    %create eventResult object
    crThreshold = sprintf('%d mmHg Threshold',thresholdPressure);
    crPreTime = sprintf('%d minutes pre-time',minPreEventTime);
    crPostTime = sprintf('%d minutes post-time',minEventTime);
    criteria = struct('threshold',crThreshold,'preTime',crPreTime,'postTime',crPostTime);
    atPreTimes = eventPreTime;
    atPostTimes = eventTimeLengths;
    eventAttributes = struct('postTimes',atPostTimes,'preTimes',atPreTimes);
    obj = icpEventResult(patientID,criteria,outTime,eventAttributes);
    
    
else
    fprintf('The ICP and time data are of different lengths.\n');
end
end

function [meanM,varM,indexStatStart,indexStatMid] = statEveryK(matrix,k)

[R,C] = size(matrix);
numSeg = floor(R./k);
if(numSeg<1)
    numSeg = 1;
end
meanM = zeros(numSeg+1,C);
varM = zeros(numSeg+1,C);
x = 1:numSeg+1;
for c = 1:C
    for s = 1:numSeg
        fprintf('   Segment %d of %d \n',s,numSeg);
        x(s) = (s.*k)-k+1;
        tempData = matrix((s.*k)-k+1:s.*k,c);
        meanM(s,c) = mean(tempData(find(~isnan(tempData))));
        varM(s,c) = var(tempData(find(~isnan(tempData))));
    end
    if((numSeg)+1<=R)
        x(numSeg+1) = numSeg.*k;
        tempData = matrix((numSeg.*k)+1:end,c);
        meanM(numSeg+1,c) = mean(tempData(find(~isnan(tempData))));
        varM(numSeg+1,c) = var(tempData(find(~isnan(tempData))));
    end
end
indexStatStart = x;
indexStatMid = x+(round(k/2));
end

function [ count ] = backBandCounter(vector,low,high)

%Counts the number of values that fall within the band from last to first.
%Count stops when a value falls outside the band.
flippedVector = flip(vector);
count = 0;
for k = 1:length(vector);
    if(flippedVector(k)>= low && flippedVector(k)<=high)
        count = count + 1;
    else
        break;
    end
end
end

function [location]=closestPoint(Vector,GivenPoint)

% Check unique Vector 
if length(unique(Vector))==length(Vector);
    

distance=nan(length(Vector),1);

% Get distances
for i=1:length(Vector)
    
    distance(i,1)=abs(Vector(i)-GivenPoint);
end
[~,location]=min(distance);

else
    fprintf('ERROR: Values are not Unique')
    location=[];
    
end
end