% Code by Phil Bedggood and Flora Hui % Questions to pabedg@unimelb.edu.au or huif@unimelb.edu.au % Citation: Hui F, et al (2014). "Quantitative spatial and temporal analysis of % fluorescein angiography dynamics in the eye". PLoS ONE xxx. % % Main input: A grayscale fluorescein angiogram TIFF stack (example "Sample.tif" included) % Main output: A registered version of this TIFF stack % Workflow: registerTiffStack -> PCAsmooth -> readTraceMask -> fitRegisteredTif if plotIndividual if plotPCA load([theTifName(1:end-8) '_PCA.mat'],'intensityTraceMatrix'); else load([theTifName(1:end-8) '.mat'],'intensityTraceMatrix'); end end thisTrace = intensityTraceMatrix(pp,:); % Apply a median filter to thisTrace when not using PCA if ~makePCAImages thisTrace = medfilt1(thisTrace); end thisMax = max(thisTrace); %% Find the first time at which there was a peak, and the last time at which there was a peak peakLocation_1st = find(thisTrace == thisMax,1); peakLocation_2nd = find(thisTrace(end:-1:1) == thisMax,1); peakLocation_2nd = numFrames - peakLocation_2nd + 1; peakLocation_1st_orig = peakLocation_1st; if thisMax == 255 % To mitigate saturation issues, average the two peak locations peakLocation_1st = round(mean([peakLocation_1st peakLocation_2nd])); peakLocation_2nd = peakLocation_1st; end % Determine the half rise time, half fall time and offset: firstFrameToConsider = 1; firstIndices = firstFrameToConsider : peakLocation_1st; theXData_1st = all_x(firstIndices); secondIndices = peakLocation_2nd : numFrames; theXData_2nd = all_x(secondIndices); halfMax_1st = (thisMax - thisTrace(1))/2 + thisTrace(1); halfMax_2nd = (thisMax - thisTrace(end))/2 + thisTrace(end); firstTrace = thisTrace(firstIndices); secondTrace = thisTrace(secondIndices); risingHalfPeakLocation = find(abs(firstTrace - halfMax_1st) == min(abs(firstTrace - halfMax_1st)) ,1); risingHalfPeakTime = theXData_1st(risingHalfPeakLocation); fallingHalfPeakLocation = find(abs(secondTrace - halfMax_2nd) == min(abs(secondTrace - halfMax_2nd)) ,1); fallingHalfPeakTime = theXData_2nd(fallingHalfPeakLocation); % Use an average of the last 2 seconds of data to work out the offset lastSecondFrames = round(numFrames/all_x(1,end)); baseline = sum(thisTrace(1,(1:(2*lastSecondFrames))))/(2*(lastSecondFrames)); % Baseline correction by first two seconds correctedTrace = thisTrace - baseline; lastSecond = sum(correctedTrace(1,(end-(2*(lastSecondFrames)-1):end)))/(2*(lastSecondFrames)); offset = (lastSecond/max(correctedTrace)); % Calculate the offset relative to peak if offset < 0 % gets rid of negative values offset = 0; end coefficientStore(pp,:) = [risingHalfPeakTime fallingHalfPeakTime offset]; % Store the coefficients for this pixel