function expFiles = autoDenoise(expFiles, speedCutoff, maxNoisyFrames)
    colors = defaultMatlabColors;
    for i=1:length(expFiles)
        load(expFiles{i});
        
        % Scale threshold for noisy frames such that longer experiments
        % aren't more heavily scrutinized than short ones
        maxNoisyFrames = ceil(expmt.parameters.duration/24)*maxNoisyFrames;
        
        spFile = split(expFiles{i},'\');
        expFile = spFile{length(spFile)};
        spFile{length(spFile)} = '';
        expDir = join(spFile(1:length(spFile)),'\');
        expDir = expDir{1};

        % Pull experiment start date and time from file name using CNE functions
        expDate = returnExpDate(string(expFile));

        % Get ID of box in which experiment was run
        disp(expFile);

        % Automatically determine filename for survival Excel sheet
        survivalFile = strcat(expDir,expDate,"-survival_data.xlsx");
        % Load Excel sheet
        survival = readtable(survivalFile);
        roiStats = strings(1,expmt.nTracks);
        
        xlswrite(survivalFile,{'AutoX_lower_bound'},1,"T1");
        xlswrite(survivalFile,{'AutoX_upper_bound'},1,"U1");       
        
        % Set to 1 once at least 1 ROI requires denoising, otherwise no
        % need to save new file!
        denoiseReq = 0;
        
        %for roi = [59,61,63]
        for roi = 1:expmt.nTracks

            roiStats(roi) = classifyROI(survival,roi);
            maxXWidth = 20; % by default, don't let an ROI have a width greater than 20 as define by fly movement
            
            lowBound = min(expmt.Centroid.data(:,2,roi));
            upBound = max(expmt.Centroid.data(:,2,roi));
            
            if ~strcmp(roiStats(roi),'NI')
                % Look for noise, as indicated by impossible speed bt
                % frames
                tooFast = expmt.Speed.data(:,roi) > speedCutoff;
                checkSpeed = cumsum(tooFast);

                if checkSpeed(length(checkSpeed)) > maxNoisyFrames
                    denoiseReq = 1;

                    % Store x and y centroid positions in temporary
                    % variables
                    x = expmt.Centroid.data(:,1,roi);
                    y = expmt.Centroid.data(:,2,roi);
                    
                    figure;

                    subplot(3,1,1);
                    hold on;
                    plot(scaleHt(y),'Color',colors(2,:));
                    %plot(tooFast,'Color',colors(3,:));
                    title(strcat("ROI: ",num2str(roi)));
                    xlabel('Frame');
                    ylabel('Y position');
                    xlim([0 length(y)]);

                    subplot(3,1,2);
                    plot(x,'Color',colors(3,:));
                    xlabel('Frame');
                    ylabel('X position');
                    xlim([0 length(y)]);

                    % There are two ways you can define a center of an
                    % ROI...
                    % ...based on ROI bounds
                    leftEdge = expmt.ROI.bounds(roi,1);
                    rightEdge = expmt.ROI.bounds(roi,1) + expmt.ROI.bounds(roi,3);  
                    roiCenter = mean([leftEdge,rightEdge]);
                    
                    % ...or based on fly movement
                    % 2020-07-12 - changed this from nanmean(x) to middle
                    % of observed values. If there's one edge that's due to
                    % noise, this will prevent that from biasing center so
                    % the noise can be caught (hopefully)
                    xCenter = nanmean([max(x),min(x)]);
                    
                    
                    % xWidth is the effective width of your ROI, based on
                    % fly movement
                    xWidth = max(x)-min(x);
                    
                    if xWidth < maxXWidth
                        maxXWidth = xWidth-2;
                    end

                    while checkSpeed(length(checkSpeed)) > maxNoisyFrames && maxXWidth > 9
                        lowBound = xCenter - 0.5*maxXWidth; 
                        upBound = xCenter + 0.5*maxXWidth; 

                        set1 = x > lowBound;
                        set2 = x < upBound;
                        setAdd = set1+set2;

                        % Generate corrected x and y arrays
                        x(setAdd~=2) = NaN;
                        y(setAdd~=2) = NaN;

                        newSpeed = squeeze(diff(x).^2) + squeeze(diff(y).^2);
                        newSpeed = sqrt(newSpeed);
                        newSpeed(isnan(newSpeed)) = 0;

                        tooFast = newSpeed > speedCutoff;
                        checkSpeed = cumsum(tooFast);
                        maxXWidth = maxXWidth - 2;
                        
                    end    

                    % Once you've arrived at final denoised data, overwrite centroid data
                    expmt.Centroid.data(:,1,roi) = x;
                    expmt.Centroid.data(:,2,roi) = y;  
                    
                    % Save de-noising bounds
                    disp(strcat("ROI #: ", num2str(roi)," Low Bound: ",num2str(lowBound)," Upper Bound: ", num2str(upBound)));
                    xlswrite(survivalFile,{num2str(lowBound)},1,strcat('T',num2str(roi+1)));
                    xlswrite(survivalFile,{num2str(upBound)},1,strcat('U',num2str(roi+1)));
                    
                    % Plot de-noised y data, for comparison
                    subplot(3,1,3);
                    plot(scaleHt(expmt.Centroid.data(:,2,roi)),'Color',colors(1,:));
                    xlim([0 length(expmt.Centroid.data)]);
                    ylabel('Denoised: Y-position');
                    xlabel('Frame');

                    % Plot boundary box determined for denoising x data,
                    % for sanity check
                    subplot(3,1,2);
                    rectangle('Position',[0,lowBound,length(expmt.Centroid.data),upBound-lowBound]);
                    ylim([lowBound-2 upBound+2]);
                    xlim([0 length(expmt.Centroid.data)]);
                    set(gcf,'PaperUnits','inches','PaperPosition',[0 0 10 8]);
                    print([expDir,'ROI-',num2str(roi),'-denoised'],'-dpng');      
                    close();
                end
            end    
        end

        % Recalculate speed for ALL corrected data
        speed = squeeze(diff(expmt.Centroid.data(:,1,:)).^2) + squeeze(diff(expmt.Centroid.data(:,2,:)).^2);
        speed = sqrt(speed);
        speed(isnan(speed)) = 0;

        expmt.Speed.data = vertcat(zeros(1,size(expmt.Centroid.data,3)),speed);
        
        % Save corrected expmt struct    
        % Overwrite if already named _denoise
        if denoiseReq
            if strfind(expFiles{i},'denoise')
                save(expFiles{i},'expmt','-mat','-v7.3');  
            % otherwise make a new .mat file with suffix _denoise
            else
                filePre = split(expFiles{i},'.mat');
                filePre = filePre{1};
                outfile = strcat(filePre,'_autodenoise.mat');
                expFiles{i} = outfile;
                save(outfile,'expmt','-mat','-v7.3');       
            end
        end
    end
end