classdef ProbeDealer_Win < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        ProbeDealerUIFigure             matlab.ui.Figure
        GenerateprobesButton            matlab.ui.control.Button
        UploadFASTAExcelspreadsheetofyourtargetsequencesLabel  matlab.ui.control.Label
        UploadtargetsequencesEditField  matlab.ui.control.EditField
        BrowseTargetSequenceButton      matlab.ui.control.StateButton
        OutputfiletoEditFieldLabel      matlab.ui.control.Label
        OutputfiletoEditField           matlab.ui.control.EditField
        BrowseOutputPathButton          matlab.ui.control.StateButton
        HowmanyprobesdoyouwantforeachinputsequenceEditFieldLabel  matlab.ui.control.Label
        HowmanyprobesdoyouwantforeachinputsequenceEditField  matlab.ui.control.EditField
        probesPerSequenceNote           matlab.ui.control.Label
        ProvidethepathtogenomefilesLabel  matlab.ui.control.Label
        ProvidethepathtogenomefilesEditField  matlab.ui.control.EditField
        chooseYourProbeTypeLabel        matlab.ui.control.Label
        OnlytargetantisensestrandofgenesCheckBox  matlab.ui.control.CheckBox
        probeTypeButtonGroup            matlab.ui.container.ButtonGroup
        chromatintracingButton          matlab.ui.control.RadioButton
        MERFISHnomorethan140sequencesButton  matlab.ui.control.RadioButton
        sequentialRNAFISHButton         matlab.ui.control.RadioButton
        probeAdditionalFeaturesLabel    matlab.ui.control.Label
        AvoidexonregionsCheckBox        matlab.ui.control.CheckBox
        Step1Label                      matlab.ui.control.Label
        Step2Label                      matlab.ui.control.Label
        chromatinTracingProbeFeatureLabel  matlab.ui.control.Label
        Step3Label                      matlab.ui.control.Label
        Step4Label                      matlab.ui.control.Label
        BrowsePathtoCustomizedGenomeFilesButton  matlab.ui.control.StateButton
        OutputTypeGroup                 matlab.ui.container.ButtonGroup
        templateprobelibraryButton      matlab.ui.control.RadioButton
        primaryprobesequencesButton     matlab.ui.control.RadioButton
        chooseOutputTypeLabel           matlab.ui.control.Label
    end

    % Callbacks that handle component events
    methods (Access = private)

        % Value changed function: BrowseTargetSequenceButton
        function BrowseTargetSequenceButtonValueChanged(app, event)
            value = app.BrowseTargetSequenceButton.Value;
            [file,path,indSeqFile] = uigetfile(...
                {'*.fasta; *.fas; *.fa; *.xls; *.xlsx; *.csv','Fasta Files (*.fasta; *.fas; *.fa)';...
                '*.xls; *.xlsx; *.csv','Spreadsheet Files (*.xls; *.xlsx; *.csv)';...
                },'Upload sequences');
            app.UploadtargetsequencesEditField.Value = ...
                fullfile(path, file); 
            
        end

        % Button pushed function: GenerateprobesButton
        function GenerateprobesButtonPushed(app, event)
            if exist('BLAST_output_t_plus.txt')
                delete('BLAST_output_t_plus.txt');
            end
            if exist('BLAST_output_t_minus.txt')
                delete('BLAST_output_t_minus.txt');
            end
            if exist('BLAST_output_g.txt')
                delete('BLAST_output_g.txt');
            end
            if exist('BLAST_output_shorttx.txt')
                delete('BLAST_output_shorttx.txt');
            end            
            if exist('oligos.fasta')
                delete('oligos.fasta');
            end
            if exist('InputSeq.fasta')
                delete('InputSeq.fasta');
            end
            % 1. load in genome
            probeType = app.probeTypeButtonGroup.SelectedObject.Text;
            genomePath = app.ProvidethepathtogenomefilesEditField.Value;
            if strcmp('chromatin tracing',probeType)
            % define genome path for custom genome
                genomeName = dir([genomePath '/genome/*.fasta']);
                if length(genomeName)==0
                    genomeName = dir([genomePath '/genome/*.fa']);
                end
                if length(genomeName)==0
                    genomeName = dir([genomePath '/genome/*.fas']);
                end
                genome = [genomeName.folder '/' genomeName.name];
                if app.OnlytargetantisensestrandofgenesCheckBox.Value == 1
                % define unspliced transcriptome path for custom genome
                    unsplicedTxName = dir([genomePath '/unsplicedTx/*.fasta']);
                    if length(unsplicedTxName)==0
                        unsplicedTxName = dir([genomePath '/unsplicedTx/*.fa']);
                    end
                    if length(unsplicedTxName)==0
                        unsplicedTxName = dir([genomePath '/unsplicedTx/*.fas']);
                    end
                    unsplicedTx = [unsplicedTxName.folder '/' unsplicedTxName.name];
                end
                    
                if app.AvoidexonregionsCheckBox.Value == 1                    
                % define transcriptome for custome genome
                    TxShortHeaderName = dir([genomePath '/TxShortHeader/*.fasta']);
                    if length(TxShortHeaderName)==0
                        TxShortHeaderName = dir([genomePath '/TxShortHeader/*.fa']);
                    end
                    if length(TxShortHeaderName)==0
                        TxShortHeaderName = dir([genomePath '/TxShortHeader/*.fas']);
                    end
                    TxShortHeader = [TxShortHeaderName.folder '/' TxShortHeaderName.name];  
                end
            else
                TxShortHeaderName = dir([genomePath '/TxShortHeader/*.fasta']);
                if length(TxShortHeaderName)==0
                    TxShortHeaderName = dir([genomePath '/TxShortHeader/*.fa']);
                end
                if length(TxShortHeaderName)==0
                    TxShortHeaderName = dir([genomePath '/TxShortHeader/*.fas']);
                end
                TxShortHeader = [TxShortHeaderName.folder '/' TxShortHeaderName.name];       
                    
                TxName = dir([genomePath '/Tx/*.fasta']);
                if length(TxName)==0
                    TxName = dir([genomePath '/Tx/*.fa']);
                end
                if length(TxName)==0
                    TxName = dir([genomePath '/Tx/*.fas']);
                end
                Tx = [TxName.folder '/' TxName.name];    
            end
            
            % 2. read in sequences and process oligos
            d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",'Reading sequences...','Indeterminate','on');
            sequenceFileName = strsplit(app.UploadtargetsequencesEditField.Value,'.');
            inputHeader = {};
            inputSeq = {};
            inputMatrix = {};
            if strcmp('chromatin tracing',probeType)
                secondary = readcell('primers and secondary sequences/DNA secondaries.xlsx','NumHeaderLines',1);
            elseif strcmp('sequential RNA FISH',probeType)
                secondary = readcell('primers and secondary sequences/RNA secondaries.xlsx','NumHeaderLines',1,'Sheet','sequential RNA FISH');
            else
                secondary = readcell('primers and secondary sequences/RNA secondaries.xlsx','NumHeaderLines',1,'Sheet','MERFISH');                
            end 
            for i = 1:size(secondary,1)
                if ismissing(secondary{i,1})
                    secondary{i,1} = '';
                end
                if ismissing(secondary{i,2})
                    secondary{i,2} = '';
                end
            end
            % read in buildOligoArray.m parameters
            oligoparam = readcell('oligoparameter.xlsx');
            ProbeLength = oligoparam{1,2};
            MinTm = oligoparam{2,2};
            MaxTm = oligoparam{3,2};
            SecondaryStructureTm = oligoparam{4,2};
            CrossHybTm = oligoparam{5,2};
            MinGC = oligoparam{6,2};
            MaxGC = oligoparam{7,2};
            ExcludeSeq = oligoparam{8,2};
            ProbeGap = oligoparam{9,2};
            % determine input file type: fasta file or spreadsheet, use
            % 1-based coordinates!!!
            if strcmp('fasta',sequenceFileName{end}) || strcmp('fa',sequenceFileName{end}) || strcmp('fas',sequenceFileName{end})
                [inputHeader, inputSeq] = fastaread(app.UploadtargetsequencesEditField.Value);
                if ~iscell(inputSeq)
                    SeqString = inputSeq;
                    HeadString = inputHeader;
                    clear inputHeader
                    clear inputSeq
                    inputSeq{1} = SeqString;
                    inputHeader{1} = HeadString;
                end
                if size(secondary,1) < length(inputHeader)
                    uialert(app.ProbeDealerUIFigure,'Not enough secondary sequences! Existing...','ProbeDealer');
                    return                
                end
                val=cellfun(@(x) numel(x),inputSeq); % find the longest string
                d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",...
                    ['Generating initial probes... May take ' num2str(ceil(length(inputHeader)*max(val)/1000*max(val)/1000/350)) ' minutes for long sequences, Please be patient...'],'Indeterminate','on');
                Oligo = buildOligoArray(app.UploadtargetsequencesEditField.Value,...
                    'ProbeLength', ProbeLength, 'MinTm', MinTm,'MaxTm',MaxTm,'SecondaryStructureTm',SecondaryStructureTm,'CrossHybTm',CrossHybTm,'MinGC',MinGC,'MaxGC',MaxGC,'ExcludeSeq',ExcludeSeq,'ProbeGap',ProbeGap);
            else % input file is spreadsheet
                inputMatrix = readcell(app.UploadtargetsequencesEditField.Value);
                if strcmp('chromatin tracing',probeType)
                    [genomeHeader,genomeSeq] = fastaread(genome);
                    for i = 1:size(inputMatrix,1)
                        if ~ischar(inputMatrix{i,1})
                            inputMatrix{i,1}=num2str(inputMatrix{i,1});
                        end
                        inputHeader{end+1} = [inputMatrix{i,1} ':' num2str(inputMatrix{i,2}) '-' num2str(inputMatrix{i,3})];
                        Idx = find(strcmp(inputMatrix{i,1},genomeHeader));
                        if isempty(Idx)
                            uialert(app.ProbeDealerUIFigure,['Record ' num2str(i) ' in input sheet not found in genome! Existing...'],'ProbeDealer');
                            return
                        end
                        inputSeq{end+1} = genomeSeq{Idx}(inputMatrix{i,2}:inputMatrix{i,3});
                    end
                else
                    [txHeader,txSeq] = fastaread(TxShortHeader);
                    for i = 1:size(inputMatrix,1)
                        inputHeader{end+1} = inputMatrix{i,1};
                        Idx = find(strcmp(inputMatrix{i,1},txHeader));
                        if isempty(Idx)
                            uialert(app.ProbeDealerUIFigure,['Record ' num2str(i) ' in input sheet not found in transcriptome! Existing...'],'ProbeDealer');
                            return
                        end
                        inputSeq{end+1} = txSeq{Idx};
                    end
                end
                if app.MERFISHnomorethan140sequencesButton.Value ~= 1 && size(secondary,1) < length(inputHeader)
                    uialert(app.ProbeDealerUIFigure,'Not enough secondary sequences! Existing...','ProbeDealer');
                    return                
                end
                if app.MERFISHnomorethan140sequencesButton.Value == 1 && length(inputSeq)>140
                    uialert(app.ProbeDealerUIFigure,'Too many input sequences for MERFISH! Existing...','ProbeDealer');
                    return
                end
                if app.MERFISHnomorethan140sequencesButton.Value == 1 && size(inputMatrix,2)<2
                    uialert(app.ProbeDealerUIFigure,'FPKM missing for MERFISH! Existing...','ProbeDealer');
                    return
                end
                fastawrite('InputSeq.fasta',inputHeader,inputSeq);
                val=cellfun(@(x) numel(x),inputSeq);
                
                d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",...
                    ['Generating initial probes... May take ' num2str(ceil(length(inputHeader)*max(val)/1000*max(val)/1000/350)) ' minutes for long sequences, Please be patient...'],'Indeterminate','on');
                Oligo = buildOligoArray('InputSeq.fasta',...
                    'ProbeLength', ProbeLength, 'MinTm', MinTm,'MaxTm',MaxTm,'SecondaryStructureTm',SecondaryStructureTm,'CrossHybTm',CrossHybTm,'MinGC',MinGC,'MaxGC',MaxGC,'ExcludeSeq',ExcludeSeq,'ProbeGap',ProbeGap);
            end
            
            if isempty(Oligo)
                uialert(app.ProbeDealerUIFigure,'No good oligos can be generated! Existing...','ProbeDealer');
                return
            end
            
            % divide oligos into different files if too many oligos
            probePerFile = 20000;
            Oligo_split = {};
            splitFile = ceil(length(Oligo)/probePerFile);
            for i = 1:splitFile
                if i < splitFile
                    Oligo_split{i} = Oligo(probePerFile*(i-1)+1:probePerFile*i);
                    if exist(['oligos' num2str(i) '.fasta'])
                        delete(['oligos' num2str(i) '.fasta']);
                    end
                    fastawrite(['oligos' num2str(i) '.fasta'],Oligo_split{i});
                else
                    Oligo_split{i} = Oligo(probePerFile*(i-1)+1:end);
                    if exist(['oligos' num2str(i) '.fasta'])
                        delete(['oligos' num2str(i) '.fasta']);
                    end
                    fastawrite(['oligos' num2str(i) '.fasta'],Oligo_split{i});
                end
            end
            
            % 3. blast according to settings
            d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",'BLASTing probes...','Indeterminate','on');
            %setenv('PATH', [getenv('PATH') ':/usr/local/ncbi/blast/bin']);
            % DNA probe: genome
            if strcmp('chromatin tracing',probeType)
                if exist('oligos.fasta')
                    delete('oligos.fasta');
                end
                for i = 1:splitFile
                    system(['blastn -query oligos' num2str(i) '.fasta -db ' genome ' -out BLAST_output_g' num2str(i) '.txt']);
                end
                d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",'Analyzing BLAST results...','Indeterminate','on');
                i = 1; % oligo number
                for jj = 1:splitFile
                    Line = [];
                    dLine = [];
                    icurrentfile = 1; % record the oligo number in the current file
                    N = length(Oligo_split{jj}); % number of all oligos in the current file
                    fid = fopen(['BLAST_output_g' num2str(jj) '.txt'], 'r');
                    tline = fgetl(fid);
                    n = 0; % line number
                    while ischar(tline)
                        n = n+1;
                        if strfind(tline, ['Query= ' num2str(i) '_'])==1
                            Line(icurrentfile) = n; % this records the line number for oligo name oligoi
                            i = i+1;
                            icurrentfile = icurrentfile+1;
                        end
                        tline = fgetl(fid);
                    end
                    fclose(fid);
                    Line(icurrentfile) = n-8;
                    dLine = Line(2:end)-Line(1:end-1);
                    for t = 1:N
                        if dLine(t) ~= 32
                            Oligo((jj-1)*probePerFile+t).genome = 0;
                        else
                            Oligo((jj-1)*probePerFile+t).genome = 1; % dLine = 32 meaning only 1 match, here need to find unique match in genome
                        end
                    end
                end
                if app.OnlytargetantisensestrandofgenesCheckBox.Value == 0
                    clear GoodOligo;
                    j = 1;
                    for i = 1:length(Oligo)
                        if Oligo(i).genome == 1
                            GoodOligo(j).Header = [num2str(j) '_' Oligo(i).FragID];
                            GoodOligo(j).Sequence = Oligo(i).Sequence;
                            GoodOligo(j).FragID = Oligo(i).FragID;
                            j = j+1;
                        end
                    end
                else
                    for i = 1:splitFile
                        system(['blastn -query oligos' num2str(i) '.fasta -db ' unsplicedTx ' -strand plus -out BLAST_output_t' num2str(i) '_plus.txt']); % blast against unspliced transcriptome
                        system(['blastn -query oligos' num2str(i) '.fasta -db ' unsplicedTx ' -strand minus -out BLAST_output_t' num2str(i) '_minus.txt']); % blast against unspliced transcriptome
                    end
                    d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",'Analyzing BLAST results...','Indeterminate','on');
                    i = 1; % oligo number
                    for jj = 1:splitFile
                        Line = [];
                        dLine = [];
                        icurrentfile = 1; % record the oligo number in the current file
                        N = length(Oligo_split{jj}); % number of all oligos in the current file
                        fid = fopen(['BLAST_output_t' num2str(jj) '_plus.txt'], 'r');
                        tline = fgetl(fid);
                        n = 0; % line number
                        while ischar(tline)
                            n = n+1;
                            if strfind(tline, ['Query= ' num2str(i) '_'])==1
                                Line(icurrentfile) = n; % this records the line number for oligo name oligoi
                                i = i+1;
                                icurrentfile = icurrentfile+1;
                            end
                            tline = fgetl(fid);
                        end
                        fclose(fid);
                        Line(icurrentfile) = n-8;
                        dLine = Line(2:end)-Line(1:end-1);
                        for t = 1:N
                            if dLine(t) ~= 19
                                Oligo((jj-1)*probePerFile+t).plus = 0;
                            else
                                Oligo((jj-1)*probePerFile+t).plus = 1; % 19 = "No mathcing found" situation
                            end
                        end
                    end
                    i = 1; % oligo number
                    for jj = 1:splitFile
                        Line = [];
                        dLine = [];
                        icurrentfile = 1; % record the oligo number in the current file
                        N = length(Oligo_split{jj}); % number of all oligos in the current file
                        fid = fopen(['BLAST_output_t' num2str(jj) '_minus.txt'], 'r');
                        tline = fgetl(fid);
                        n = 0; % line number
                        while ischar(tline)
                            n = n+1;
                            if strfind(tline, ['Query= ' num2str(i) '_'])==1
                                Line(icurrentfile) = n; % this records the line number for oligo name oligoi
                                i = i+1;
                                icurrentfile = icurrentfile+1;
                            end
                            tline = fgetl(fid);
                        end
                        fclose(fid);
                        Line(icurrentfile) = n-8;
                        dLine = Line(2:end)-Line(1:end-1);
                        for t = 1:N
                            if dLine(t) ~= 19
                                Oligo((jj-1)*probePerFile+t).minus = 0;
                            else
                                Oligo((jj-1)*probePerFile+t).minus = 1; % 19 = "No mathcing found" situation
                            end
                        end
                    end

                    clear GoodOligo;
                    j = 1;
                    for i = 1:length(Oligo)
                        if Oligo(i).genome == 1
                            if Oligo(i).plus == 1
                                GoodOligo(j).Header = [num2str(j) '_' Oligo(i).FragID];
                                GoodOligo(j).Sequence = Oligo(i).Sequence;
                                GoodOligo(j).FragID = Oligo(i).FragID;
                                j = j+1;
                            else
                                if Oligo(i).minus == 1
                                    GoodOligo(j).Header = [num2str(j) '_' Oligo(i).FragID];
                                    GoodOligo(j).Sequence = seqrcomplement(Oligo(i).Sequence);
                                    GoodOligo(j).FragID = Oligo(i).FragID;
                                    j = j+1;
                                end
                            end
                        end
                    end
                end
                if app.AvoidexonregionsCheckBox.Value == 1
                    if exist('GoodOligo.fasta')
                        delete('GoodOligo.fasta');
                    end
                    fastawrite('GoodOligo.fasta',GoodOligo);
                    if exist('BLAST_output_shorttx.txt')
                        delete('BLAST_output_shorttx.txt');
                    end
                    system(['blastn -query GoodOligo.fasta -db ' TxShortHeader ' -out BLAST_output_shorttx.txt']); % blast against transcriptome
                    d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",'Analyzing BLAST results...','Indeterminate','on');
                    clear Oligo;
                    Oligo = fastaread('GoodOligo.fasta');
                    delete('GoodOligo.fasta');
                    N = length(Oligo);
                    fid = fopen(['BLAST_output_shorttx.txt'], 'r');
                    tline = fgetl(fid);
                    i = 1; % oligo number
                    n = 0; % line number
                    while ischar(tline)
                        n = n+1;
                        if strfind(tline, ['Query= ' num2str(i) '_'])==1
                            Line(i) = n; % this records the line number for oligo name oligoi
                            i = i+1;
                        end
                        tline = fgetl(fid);
                    end
                    fclose(fid);
                    Line(i) = n-8;
                    dLine = Line(2:end)-Line(1:end-1);
                    for i = 1:N
                        if dLine(i) ~= 19 % 19 = "No matching found" situation
                            %        if dLine(i) < 32
                            Oligo(i).minus = 0;
                        else
                            Oligo(i).minus = 1;
                        end
                    end
                    clear GoodOligo;
                    j = 1;
                    for i = 1:length(Oligo)
                        if Oligo(i).minus == 1
                            Idx = length(num2str(i))+1;
    	                    GoodOligo(j).Header = [num2str(j) '_' Oligo(i).Header(Idx+1:end)];
    	                    GoodOligo(j).Sequence = Oligo(i).Sequence;
                            j = j+1;
                        end
                    end      
                end   
            else % here design RNA probes
                d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",'BLASTing probes...','Indeterminate','on');
                system(['blastn -query oligos.fasta -db ' TxShortHeader ' -out BLAST_output_shorttx.txt']); % blast against tx
                d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",'Analyzing BLAST results...','Indeterminate','on');
               [HeadTx SeqTx] = fastaread(Tx);
                for i = 1:length(SeqTx)
                    parseHeadTx = strsplit(HeadTx{i},'|');
                    TxID = strsplit(parseHeadTx{1},'.');
                    ascTx = abs(TxID{1});
                    Idx = find(ascTx>=48 & ascTx<=57);
                    AllTranscriptIDs(i) = str2num(TxID{1}(Idx(1):end));
                    GeneID = strsplit(parseHeadTx{2},'.');
                    ascGene = abs(GeneID{1});
                    Idx = find(ascTx>=48 & ascTx<=57);
                    AllGeneIDs(i) = str2num(GeneID{1}(Idx(1):end));
                end
                Seg = Idx(1);

                fid = fopen(['BLAST_output_shorttx.txt'], 'r');
                tline = fgetl(fid);
                i = 1;
                GoodOligo = [];
                while ischar(tline)
                    if strfind(tline, ['Query= ' num2str(i) '_'])==1
                        tline = fgetl(fid);
                        tline = fgetl(fid);
                        tline = fgetl(fid);
                        tline = fgetl(fid);
                        tline = fgetl(fid);
                        tline = fgetl(fid);
                        flag = 1;
                        if length(tline)>0
                            StringCellArray = strsplit(tline);
                            TranscriptID1 = str2num(StringCellArray{1}(Seg:end));
                            GeneID1 = AllGeneIDs(find(AllTranscriptIDs == TranscriptID1));
                        else
                            flag = 0;
                        end
                        tline = fgetl(fid);
            
        
                        while length(tline)>0
                            StringCellArray = strsplit(tline);
                            TranscriptID2 = str2num(StringCellArray{1}(Seg:end));
                            GeneID2 = AllGeneIDs(find(AllTranscriptIDs == TranscriptID2));
                            if GeneID1 ~= GeneID2
                                flag = 0;
                            end
                            tline = fgetl(fid);
                        end
                        if flag == 1
                            Oligo(i).Tx = 1;
                        else
                            Oligo(i).Tx = 0;
                        end
                        i = i+1;
                    end
                    tline = fgetl(fid);
                end
                clear GoodOligo;
                j = 1;
                for i = 1:length(Oligo)
                    if Oligo(i).Tx == 1
                        Idx = length(num2str(i))+1;
    	                GoodOligo(j).Header = [num2str(j) '_' Oligo(i).Header(Idx+1:end)];
    	                GoodOligo(j).Sequence = Oligo(i).Sequence;
                        j = j+1;
                    end
                end 
            end
            
            if exist('GoodOligo')~=1
                uialert(app.ProbeDealerUIFigure,'No good oligos can be generated! Existing...','ProbeDealer');
                return
            elseif isempty(GoodOligo)
                uialert(app.ProbeDealerUIFigure,'No good oligos can be generated! Existing...','ProbeDealer');
                return
            end
            
            % 4. generate final probes
            % step1: arrange probes to meet customized probeperSeq
            % requirement
            d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",...
                'Generating final results...', 'Indeterminate','on');
            probeCount = zeros(length(inputHeader),1);           
            if exist([app.OutputfiletoEditField.Value '/log.txt'])
                delete([app.OutputfiletoEditField.Value '/log.txt']);
            end
            fout = fopen([app.OutputfiletoEditField.Value '/log.txt'],'wt');
            groupOligo = cell(length(probeCount),1);
            selectOligo = cell(length(probeCount),1);
            FinalOligo = {};
            for i = 1:length(GoodOligo)                
                Idx1 = length(num2str(i))+1;
                Pos = strfind(GoodOligo(i).Header,'_Seq');
                Idx2 = Pos(end);
                probeName = GoodOligo(i).Header(Idx1+1:Idx2-1);
                Ind = find(strcmp(inputHeader,probeName));
                if Ind>0
                    probeCount(Ind) = probeCount(Ind)+1;
                    groupOligo{Ind} = [groupOligo{Ind} GoodOligo(i)];
                end
            end
            % arrange oligos according to customized probePerSeq
            if ~strcmp('all',app.HowmanyprobesdoyouwantforeachinputsequenceEditField.Value)
                probePerSeq = str2num(app.HowmanyprobesdoyouwantforeachinputsequenceEditField.Value);
                if strcmp('chromatin tracing', probeType)
                    for i = 1:length(probeCount)
                        if probeCount(i)<probePerSeq && probeCount(i)>0
                            fprintf(fout,...
                                [inputHeader{i} ' has only ' num2str(probeCount(i)) ' probes. Some probes are duplicated to generate ' num2str(probePerSeq) ' probes. \n']);
                        elseif probeCount(i)==0
                            fprintf(fout,...
                                [inputHeader{i} ' has 0 probes. \n ']);
                        end
                        selectOligo{i} = groupOligo{i}(ceil(probeCount(i)*(1:probePerSeq)/probePerSeq));
                    end
                else
                    for i = 1:length(probeCount)
                        if probeCount(i)<probePerSeq && probeCount(i)>0
                            fprintf(fout,...
                                [inputHeader{i} ' has only ' num2str(probeCount(i)) ' probes. \n']);
                            selectOligo{i} = groupOligo{i};
                        elseif probeCount(i)==0
                            fprintf(fout,...
                                [inputHeader{i} ' has 0 probes. \n ']);
                        elseif probeCount(i)>=probePerSeq
                            selectOligo{i} = groupOligo{i}(ceil(probeCount(i)*(1:probePerSeq)/probePerSeq));
                        end
                    end
                    
                end
            else
                selectOligo = groupOligo;
            end
            
            % add primers and secondaries according to customized design
            AllOligosToOrder = [];
            OligosToOrder = [];
            primer_all = readcell('primers and secondary sequences/Primers.xlsx','NumHeaderLines',1);   
            primer = {};
            if strcmp('chromatin tracing',probeType)
                primer{1,1} = primer_all{1,1};
                primer{2,1} = primer_all{2,1};
            elseif strcmp('MERFISH (no more than 140 sequences)',probeType)
                primer{1,1} = primer_all{3,1};
                primer{2,1} = primer_all{4,1};
            else
                primer{1,1} = primer_all{5,1};
                primer{2,1} = primer_all{6,1};
            end
            
            outputType = app.OutputTypeGroup.SelectedObject.Text;
            % generate MERFISH probes
            
            if strcmp('MERFISH (no more than 140 sequences)',probeType)
                GoodCodes = generateSECDED16(4);
                FPKM = cell2mat(inputMatrix(:,2));
                % rearrange the code so that the FPKM values per bit are more uniform
                [A, ind] = sort(FPKM,'descend');
                if length(inputHeader)>=1
                    C = GoodCodes{ind(1)};
                    GoodCodes{ind(1)} = GoodCodes{3};
                    GoodCodes{3} = C;
                end
                
                if length(inputHeader)>=2
                    C = GoodCodes{ind(2)};
                    GoodCodes{ind(2)} = GoodCodes{18};
                    GoodCodes{18} = C;
                end

                if length(inputHeader)>=3
                    C = GoodCodes{ind(3)};
                    GoodCodes{ind(3)} = GoodCodes{77};
                    GoodCodes{77} = C;
                end

                if length(inputHeader)>=4
                    C = GoodCodes{ind(4)};
                    GoodCodes{ind(4)} = GoodCodes{134};
                    GoodCodes{134} = C;
                end

                if length(inputHeader)>=5
                    C = GoodCodes{ind(5)};
                    GoodCodes{ind(5)} = GoodCodes{140};
                    GoodCodes{140} = C;
                end

                if length(inputHeader)>=6
                    C = GoodCodes{ind(6)};
                    GoodCodes{ind(6)} = GoodCodes{39};
                    GoodCodes{39} = C;
                end
                
                if length(inputHeader)>=7
                    C = GoodCodes{ind(7)};
                    GoodCodes{ind(7)} = GoodCodes{14};
                    GoodCodes{14} = C;
                end

                if length(inputHeader)>=8
                    C = GoodCodes{ind(8)};
                    GoodCodes{ind(8)} = GoodCodes{1};
                    GoodCodes{1} = C;
                end
                % later save GoodCodes into Allcodes.mat for MERFISH
                % analysis
                
                if strcmp(outputType,'template probe library')
                    n = 0;
                    Codebooksheet= {};
                    Codebook = [];
                    for i = 1:length(inputHeader)
                        if length(selectOligo{i})>=0
                            n = n+1;
                            Code = GoodCodes{n};
                            Codebooksheet{n,1} = inputHeader{i};
                            Codebook(n).ChosenIsoform = inputHeader{i};
                            Codebooksheet{n,2} = Code;
                            Codebook(n).Code = Code;
                            Codebook(n).FPKM = FPKM(i);
                            OneBits = findstr(GoodCodes{n}, '1');  
                            OligosToOrder = [];
                            for j = 1:length(selectOligo{i})
                                OligosToOrder(j).Header = [selectOligo{i}(j).Header '_Code' GoodCodes{n}];
                                if mod(j,4) == 1
                                    OligosToOrder(j).Sequence = [primer{1,1} secondary{OneBits(2),1} selectOligo{i}(j).Sequence ...
                                        secondary{OneBits(3),1} secondary{OneBits(4),1} primer{2,1}];
                                elseif mod(j,4) == 2
                                    OligosToOrder(j).Sequence = [primer{1,1} secondary{OneBits(3),1} selectOligo{i}(j).Sequence ...
                                        secondary{OneBits(4),1} secondary{OneBits(1),1} primer{2,1}];
                                elseif mod(j,4) == 3
                                    OligosToOrder(j).Sequence = [primer{1,1} secondary{OneBits(4),1} selectOligo{i}(j).Sequence ...
                                        secondary{OneBits(1),1} secondary{OneBits(2),1} primer{2,1}];
                                elseif mod(j,4) == 0
                                    OligosToOrder(j).Sequence = [primer{1,1} secondary{OneBits(1),1} selectOligo{i}(j).Sequence ...
                                        secondary{OneBits(2),1} secondary{OneBits(3),1} primer{2,1}];
                                end                               
                            end
                            AllOligosToOrder = [AllOligosToOrder OligosToOrder];
                        end
                    end
                else
                    n = 0;
                    Codebooksheet = {};
                    Codebook = [];
                    for i = 1:length(inputHeader)
                        if length(selectOligo{i})>=0
                            n = n+1;
                            Code = GoodCodes{n};
                            Codebooksheet{n,1} = inputHeader{i};
                            Codebook(n).ChosenIsoform = inputHeader{i};
                            Codebooksheet{n,2} = Code;
                            Codebook(n).Code = Code;
                            Codebook(n).FPKM = FPKM(i);
                            OneBits = findstr(GoodCodes{n}, '1');
                            OligosToOrder = [];
                            for j = 1:length(selectOligo{i})
                                OligosToOrder(j).Header = [selectOligo{i}(j).Header '_Code' GoodCodes{n}];  
                                if mod(j,4) == 1
                                    OligosToOrder(j).Sequence = seqrcomplement([secondary{OneBits(2),1} selectOligo{i}(j).Sequence ...
                                        secondary{OneBits(3),1} secondary{OneBits(4),1}]);
                                elseif mod(j,4) == 2
                                    OligosToOrder(j).Sequence = seqrcomplement([secondary{OneBits(3),1} selectOligo{i}(j).Sequence ...
                                        secondary{OneBits(4),1} secondary{OneBits(1),1}]);
                                elseif mod(j,4) == 3
                                    OligosToOrder(j).Sequence = seqrcomplement([secondary{OneBits(4),1} selectOligo{i}(j).Sequence ...
                                        secondary{OneBits(1),1} secondary{OneBits(2),1}]);
                                elseif mod(j,4) == 0
                                    OligosToOrder(j).Sequence = seqrcomplement([secondary{OneBits(1),1} selectOligo{i}(j).Sequence ...
                                        secondary{OneBits(2),1} secondary{OneBits(3),1}]);
                                end                                                    
                            end
                            AllOligosToOrder = [AllOligosToOrder OligosToOrder];
                        end
                    end
                end
                
            else
                if strcmp(outputType,'template probe library')
                    for i = 1:length(inputHeader)
                        if length(selectOligo{i})>=0    
                            OligosToOrder = [];
                            for j = 1:length(selectOligo{i})
                                OligosToOrder(j).Header = selectOligo{i}(j).Header;
                                OligosToOrder(j).Sequence = [primer{1,1} secondary{i,1} selectOligo{i}(j).Sequence secondary{i,2} primer{2,1}];                               
                            end
                            AllOligosToOrder = [AllOligosToOrder OligosToOrder];
                        end
                    end    
                else
                    for i = 1:length(inputHeader)
                        if length(selectOligo{i})>=0   
                            OligosToOrder = [];
                            for j = 1:length(selectOligo{i})
                                OligosToOrder(j).Header = selectOligo{i}(j).Header;
                                OligosToOrder(j).Sequence = seqrcomplement([secondary{i,1} selectOligo{i}(j).Sequence secondary{i,2}]);                               
                            end
                            AllOligosToOrder = [AllOligosToOrder OligosToOrder];
                        end
                    end                     
                end
            end
            
            % print files
            if exist([app.OutputfiletoEditField.Value '/FinalOligos.fasta'])
                d = uiconfirm(app.ProbeDealerUIFigure,[app.OutputfiletoEditField.Value '\FinalOligos.fasta already exists! Delete existing file?'],'ProbeDealer','Icon','warning','Options',{'OK','Cancel'});
                if strcmp(d,'OK')
                    delete([app.OutputfiletoEditField.Value '/FinalOligos.fasta']);
                else
                    uialert(app.ProbeDealerUIFigure,['Writing ' app.OutputfiletoEditField.Value '\FinalOligos.fasta failed.'],'ProbeDealer');
                    return
                end
            end
            if exist([app.OutputfiletoEditField.Value '/FinalOligos.xlsx'])
                d = uiconfirm(app.ProbeDealerUIFigure,[app.OutputfiletoEditField.Value '\FinalOligos.xlsx already exists! Delete existing file?'],'ProbeDealer','Icon','warning','Options',{'OK','Cancel'});
                if strcmp(d,'OK')
                    delete([app.OutputfiletoEditField.Value '\FinalOligos.xlsx']);
                else
                    uialert(app.ProbeDealerUIFigure,['Writing ' app.OutputfiletoEditField.Value '\FinalOligos.xlsx failed.'],'ProbeDealer');
                    return
                end
            end
            fastawrite([app.OutputfiletoEditField.Value '/FinalOligos.fasta'],AllOligosToOrder);
            AllOligosToOrder_sheet = fastaread([app.OutputfiletoEditField.Value '/FinalOligos.fasta']);
            AllOligosToOrder_cell = struct2cell(AllOligosToOrder_sheet);
            AllOligosToOrder_cell = AllOligosToOrder_cell';
            writecell(AllOligosToOrder_cell,[app.OutputfiletoEditField.Value '/FinalOligos.xlsx']);
            
            % print codebook for MERFISH
            if strcmp('MERFISH (no more than 140 sequences)',probeType)
                if exist([app.OutputfiletoEditField.Value '/Codebook.xlsx'])
                    d = uiconfirm(app.ProbeDealerUIFigure,[app.OutputfiletoEditField.Value '\Codebook.xlsx already exists! Delete existing file?'],'ProbeDealer','Icon','warning','Options',{'OK','Cancel'});
                    if strcmp(d,'OK')
                        delete([app.OutputfiletoEditField.Value '/Codebook.xlsx']);
                    else
                        uialert(app.ProbeDealerUIFigure,['Writing ' app.OutputfiletoEditField.Value '\Codebook.xlsx failed.'],'ProbeDealer');
                        return
                    end
                end 
                writecell(Codebooksheet, [app.OutputfiletoEditField.Value '/Codebook.xlsx'])
                if exist([app.OutputfiletoEditField.Value '/AllCodes.mat'])
                    d = uiconfirm(app.ProbeDealerUIFigure,[app.OutputfiletoEditField.Value '\AllCodes.mat already exists! Delete existing file?'],'ProbeDealer','Icon','warning','Options',{'OK','Cancel'});
                    if strcmp(d,'OK')
                        delete([app.OutputfiletoEditField.Value '/AllCodes.mat']);
                    else
                        uialert(app.ProbeDealerUIFigure,['Writing ' app.OutputfiletoEditField.Value '\Allcodes.mat failed.'],'ProbeDealer');
                        return
                    end
                end 
                save([app.OutputfiletoEditField.Value '/AllCodes.mat'],'GoodCodes'); % save AllCodes.mat for later MERFISH analysis
                % generate CodeMatrices folder
                if exist([app.OutputfiletoEditField.Value '/CodeMatrices'])
                    d = uiconfirm(app.ProbeDealerUIFigure,[app.OutputfiletoEditField.Value '\CodeMatrices folder already exists! Delete existing folder?'],'ProbeDealer','Icon','warning','Options',{'OK','Cancel'});
                    if strcmp(d,'OK')
                        rmdir([app.OutputfiletoEditField.Value '/CodeMatrices'],'s');
                        d = uiprogressdlg(app.ProbeDealerUIFigure,'Value',0.3,'Title','ProbeDealer',"Message",...
                    'Deleting existing folder...','Indeterminate','on');
                    else
                        uialert(app.ProbeDealerUIFigure,['Exporting ' app.OutputfiletoEditField.Value '\CodeMatrices failed.'],'ProbeDealer');
                        return
                    end
                end 
                CodeMatricesFolderPath = [app.OutputfiletoEditField.Value '/CodeMatrices'];
                mkdir(CodeMatricesFolderPath);
                NumCodesAll = length(GoodCodes);
                ImageSize = 1536;
                for ii = 1:NumCodesAll
                    Matrix = [];
                    for i = 1:16
                        Matrix = cat(3, Matrix, ones(ImageSize,ImageSize,1)*str2num(GoodCodes{ii}(i)));
                    end
                    CodeMatrix = Matrix;
                    save([CodeMatricesFolderPath '/CodeMatrix' num2str(ii) '.mat'],'CodeMatrix');
                end
                % save Codebook.mat
                if exist([app.OutputfiletoEditField.Value '/Codebook.mat'])
                    d = uiconfirm(app.ProbeDealerUIFigure,[app.OutputfiletoEditField.Value '\Codebook.mat already exists! Delete existing file?'],'ProbeDealer','Icon','warning','Options',{'OK','Cancel'});
                    if strcmp(d,'OK')
                        delete([app.OutputfiletoEditField.Value '/Codebook.mat']);
                    else
                        uialert(app.ProbeDealerUIFigure,['Writing ' app.OutputfiletoEditField.Value '\Codebook.mat failed.'],'ProbeDealer');
                        return
                    end
                end 
                save([app.OutputfiletoEditField.Value '/Codebook.mat'],'Codebook');
            end
            
            % clean up
            fid = dir([app.OutputfiletoEditField.Value '/log.txt']);
            if fid.bytes == 0
                delete([app.OutputfiletoEditField.Value '/log.txt']);
            end
            d = uiconfirm(app.ProbeDealerUIFigure,'Probe succesfully generated!','ProbeDealer','Icon','success','Options',{'OK'});
           

       
        end

        % Value changed function: BrowseOutputPathButton
        function BrowseOutputPathButtonValueChanged(app, event)
            value = app.BrowseOutputPathButton.Value;
            path = uigetdir;
            app.OutputfiletoEditField.Value = fullfile(path); 
            app.OutputfiletoEditField.Value = app.OutputfiletoEditField.Value;
        end

        % Callback function
        function ChoosefrombuiltingenomeDropDownValueChanged(app, event)
            value = app.ChoosefrombuiltingenomeDropDown.Value;
            if strcmp('Customize',value)
                app.ProvidethepathtogenomefilesEditField.Enable = 1;
                app.ProvidethepathtogenomefilesEditField.Editable = 1;
                app.BrowsePathtoCustomizedGenomeFilesButton.Enable = 1;
            end
        end

        % Value changed function: 
        % BrowsePathtoCustomizedGenomeFilesButton
        function BrowsePathtoCustomizedGenomeFilesButtonValueChanged(app, event)
            value = app.BrowsePathtoCustomizedGenomeFilesButton.Value;
            path = uigetdir;
            app.ProvidethepathtogenomefilesEditField.Value = fullfile(path);
            app.ProvidethepathtogenomefilesEditField.Value = ...
                app.ProvidethepathtogenomefilesEditField.Value;
            
        end

        % Selection changed function: probeTypeButtonGroup
        function probeTypeButtonGroupSelectionChanged(app, event)
            %selectedButton = app.probeTypeButtonGroup.SelectedObject;
            if app.chromatintracingButton.Value == 1
                app.OnlytargetantisensestrandofgenesCheckBox.Enable = 1;
                app.AvoidexonregionsCheckBox.Enable = 1;
                app.HowmanyprobesdoyouwantforeachinputsequenceEditField.Value = '1000';
            else
                app.OnlytargetantisensestrandofgenesCheckBox.Value = 0;
                app.AvoidexonregionsCheckBox.Value = 0;
                app.OnlytargetantisensestrandofgenesCheckBox.Enable = 0;
                app.AvoidexonregionsCheckBox.Enable = 0;
                app.HowmanyprobesdoyouwantforeachinputsequenceEditField.Value = '48';
            end
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create ProbeDealerUIFigure and hide until all components are created
            app.ProbeDealerUIFigure = uifigure('Visible', 'off');
            app.ProbeDealerUIFigure.Position = [100 100 1004 430];
            app.ProbeDealerUIFigure.Name = 'ProbeDealer';

            % Create GenerateprobesButton
            app.GenerateprobesButton = uibutton(app.ProbeDealerUIFigure, 'push');
            app.GenerateprobesButton.ButtonPushedFcn = createCallbackFcn(app, @GenerateprobesButtonPushed, true);
            app.GenerateprobesButton.FontSize = 14;
            app.GenerateprobesButton.FontWeight = 'bold';
            app.GenerateprobesButton.Position = [467 42 131 26];
            app.GenerateprobesButton.Text = 'Generate probes!';

            % Create UploadFASTAExcelspreadsheetofyourtargetsequencesLabel
            app.UploadFASTAExcelspreadsheetofyourtargetsequencesLabel = uilabel(app.ProbeDealerUIFigure);
            app.UploadFASTAExcelspreadsheetofyourtargetsequencesLabel.HorizontalAlignment = 'right';
            app.UploadFASTAExcelspreadsheetofyourtargetsequencesLabel.Position = [546 332 186 28];
            app.UploadFASTAExcelspreadsheetofyourtargetsequencesLabel.Text = {'Upload FASTA/Excel spreadsheet'; 'of your target sequences:'};

            % Create UploadtargetsequencesEditField
            app.UploadtargetsequencesEditField = uieditfield(app.ProbeDealerUIFigure, 'text');
            app.UploadtargetsequencesEditField.Position = [746 335 168 22];

            % Create BrowseTargetSequenceButton
            app.BrowseTargetSequenceButton = uibutton(app.ProbeDealerUIFigure, 'state');
            app.BrowseTargetSequenceButton.ValueChangedFcn = createCallbackFcn(app, @BrowseTargetSequenceButtonValueChanged, true);
            app.BrowseTargetSequenceButton.Text = 'Browse..';
            app.BrowseTargetSequenceButton.Position = [923 335 63 22];

            % Create OutputfiletoEditFieldLabel
            app.OutputfiletoEditFieldLabel = uilabel(app.ProbeDealerUIFigure);
            app.OutputfiletoEditFieldLabel.HorizontalAlignment = 'right';
            app.OutputfiletoEditFieldLabel.Position = [653 92 79 22];
            app.OutputfiletoEditFieldLabel.Text = 'Output file to:';

            % Create OutputfiletoEditField
            app.OutputfiletoEditField = uieditfield(app.ProbeDealerUIFigure, 'text');
            app.OutputfiletoEditField.Position = [743 92 171 22];

            % Create BrowseOutputPathButton
            app.BrowseOutputPathButton = uibutton(app.ProbeDealerUIFigure, 'state');
            app.BrowseOutputPathButton.ValueChangedFcn = createCallbackFcn(app, @BrowseOutputPathButtonValueChanged, true);
            app.BrowseOutputPathButton.Text = 'Browse..';
            app.BrowseOutputPathButton.Position = [923 92 63 22];

            % Create HowmanyprobesdoyouwantforeachinputsequenceEditFieldLabel
            app.HowmanyprobesdoyouwantforeachinputsequenceEditFieldLabel = uilabel(app.ProbeDealerUIFigure);
            app.HowmanyprobesdoyouwantforeachinputsequenceEditFieldLabel.HorizontalAlignment = 'right';
            app.HowmanyprobesdoyouwantforeachinputsequenceEditFieldLabel.Position = [559 289 173 28];
            app.HowmanyprobesdoyouwantforeachinputsequenceEditFieldLabel.Text = {'How many probes do you want'; 'for each input sequence?'};

            % Create HowmanyprobesdoyouwantforeachinputsequenceEditField
            app.HowmanyprobesdoyouwantforeachinputsequenceEditField = uieditfield(app.ProbeDealerUIFigure, 'text');
            app.HowmanyprobesdoyouwantforeachinputsequenceEditField.Position = [746 295 168 22];
            app.HowmanyprobesdoyouwantforeachinputsequenceEditField.Value = '1000';

            % Create probesPerSequenceNote
            app.probesPerSequenceNote = uilabel(app.ProbeDealerUIFigure);
            app.probesPerSequenceNote.Position = [746 228 213 70];
            app.probesPerSequenceNote.Text = {'Note: default setting:'; '1000 for 100kb DNA region'; '48 for RNA transcripts'; 'Input "all" to retain all possible probes.'};

            % Create ProvidethepathtogenomefilesLabel
            app.ProvidethepathtogenomefilesLabel = uilabel(app.ProbeDealerUIFigure);
            app.ProvidethepathtogenomefilesLabel.HorizontalAlignment = 'right';
            app.ProvidethepathtogenomefilesLabel.Position = [60 332 183 22];
            app.ProvidethepathtogenomefilesLabel.Text = 'Provide the path to genome files:';

            % Create ProvidethepathtogenomefilesEditField
            app.ProvidethepathtogenomefilesEditField = uieditfield(app.ProbeDealerUIFigure, 'text');
            app.ProvidethepathtogenomefilesEditField.Position = [257 332 168 22];

            % Create chooseYourProbeTypeLabel
            app.chooseYourProbeTypeLabel = uilabel(app.ProbeDealerUIFigure);
            app.chooseYourProbeTypeLabel.HorizontalAlignment = 'right';
            app.chooseYourProbeTypeLabel.Position = [104 203 139 22];
            app.chooseYourProbeTypeLabel.Text = 'Choose your probe type:';

            % Create OnlytargetantisensestrandofgenesCheckBox
            app.OnlytargetantisensestrandofgenesCheckBox = uicheckbox(app.ProbeDealerUIFigure);
            app.OnlytargetantisensestrandofgenesCheckBox.Text = 'Only target antisense strand of genes';
            app.OnlytargetantisensestrandofgenesCheckBox.Position = [257 111 224 22];

            % Create probeTypeButtonGroup
            app.probeTypeButtonGroup = uibuttongroup(app.ProbeDealerUIFigure);
            app.probeTypeButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @probeTypeButtonGroupSelectionChanged, true);
            app.probeTypeButtonGroup.BorderType = 'none';
            app.probeTypeButtonGroup.Position = [249 154 256 76];

            % Create chromatintracingButton
            app.chromatintracingButton = uiradiobutton(app.probeTypeButtonGroup);
            app.chromatintracingButton.Text = 'chromatin tracing';
            app.chromatintracingButton.Position = [11 50 116 22];
            app.chromatintracingButton.Value = true;

            % Create MERFISHnomorethan140sequencesButton
            app.MERFISHnomorethan140sequencesButton = uiradiobutton(app.probeTypeButtonGroup);
            app.MERFISHnomorethan140sequencesButton.Text = 'MERFISH (no more than 140 sequences)';
            app.MERFISHnomorethan140sequencesButton.Position = [11 28 242 22];

            % Create sequentialRNAFISHButton
            app.sequentialRNAFISHButton = uiradiobutton(app.probeTypeButtonGroup);
            app.sequentialRNAFISHButton.Text = 'sequential RNA FISH';
            app.sequentialRNAFISHButton.Position = [11 5 135 22];

            % Create probeAdditionalFeaturesLabel
            app.probeAdditionalFeaturesLabel = uilabel(app.ProbeDealerUIFigure);
            app.probeAdditionalFeaturesLabel.HorizontalAlignment = 'right';
            app.probeAdditionalFeaturesLabel.FontSize = 13;
            app.probeAdditionalFeaturesLabel.FontWeight = 'bold';
            app.probeAdditionalFeaturesLabel.Position = [117 137 126 22];
            app.probeAdditionalFeaturesLabel.Text = 'Additional features:';

            % Create AvoidexonregionsCheckBox
            app.AvoidexonregionsCheckBox = uicheckbox(app.ProbeDealerUIFigure);
            app.AvoidexonregionsCheckBox.Text = 'Avoid exon regions';
            app.AvoidexonregionsCheckBox.Position = [257 87 124 22];

            % Create Step1Label
            app.Step1Label = uilabel(app.ProbeDealerUIFigure);
            app.Step1Label.HorizontalAlignment = 'right';
            app.Step1Label.FontSize = 18;
            app.Step1Label.FontWeight = 'bold';
            app.Step1Label.Position = [31 370 212 25];
            app.Step1Label.Text = 'Step 1: Choose genome';

            % Create Step2Label
            app.Step2Label = uilabel(app.ProbeDealerUIFigure);
            app.Step2Label.HorizontalAlignment = 'right';
            app.Step2Label.FontSize = 18;
            app.Step2Label.FontWeight = 'bold';
            app.Step2Label.Position = [31 229 235 25];
            app.Step2Label.Text = 'Step 2: Choose probe type';

            % Create chromatinTracingProbeFeatureLabel
            app.chromatinTracingProbeFeatureLabel = uilabel(app.ProbeDealerUIFigure);
            app.chromatinTracingProbeFeatureLabel.HorizontalAlignment = 'right';
            app.chromatinTracingProbeFeatureLabel.Position = [106 111 137 22];
            app.chromatinTracingProbeFeatureLabel.Text = 'chromatin tracing probe:';

            % Create Step3Label
            app.Step3Label = uilabel(app.ProbeDealerUIFigure);
            app.Step3Label.HorizontalAlignment = 'right';
            app.Step3Label.FontSize = 18;
            app.Step3Label.FontWeight = 'bold';
            app.Step3Label.Position = [530 370 231 25];
            app.Step3Label.Text = 'Step 3: Upload sequences';

            % Create Step4Label
            app.Step4Label = uilabel(app.ProbeDealerUIFigure);
            app.Step4Label.HorizontalAlignment = 'right';
            app.Step4Label.FontSize = 18;
            app.Step4Label.FontWeight = 'bold';
            app.Step4Label.Position = [530 180 129 25];
            app.Step4Label.Text = 'Step 4: Output';

            % Create BrowsePathtoCustomizedGenomeFilesButton
            app.BrowsePathtoCustomizedGenomeFilesButton = uibutton(app.ProbeDealerUIFigure, 'state');
            app.BrowsePathtoCustomizedGenomeFilesButton.ValueChangedFcn = createCallbackFcn(app, @BrowsePathtoCustomizedGenomeFilesButtonValueChanged, true);
            app.BrowsePathtoCustomizedGenomeFilesButton.Text = 'Browse..';
            app.BrowsePathtoCustomizedGenomeFilesButton.Position = [432 332 63 22];

            % Create OutputTypeGroup
            app.OutputTypeGroup = uibuttongroup(app.ProbeDealerUIFigure);
            app.OutputTypeGroup.BorderType = 'none';
            app.OutputTypeGroup.Position = [733 124 172 48];

            % Create templateprobelibraryButton
            app.templateprobelibraryButton = uiradiobutton(app.OutputTypeGroup);
            app.templateprobelibraryButton.Text = 'template probe library';
            app.templateprobelibraryButton.Position = [11 22 140 22];
            app.templateprobelibraryButton.Value = true;

            % Create primaryprobesequencesButton
            app.primaryprobesequencesButton = uiradiobutton(app.OutputTypeGroup);
            app.primaryprobesequencesButton.Text = 'primary probe sequences';
            app.primaryprobesequencesButton.Position = [11 1 159 22];

            % Create chooseOutputTypeLabel
            app.chooseOutputTypeLabel = uilabel(app.ProbeDealerUIFigure);
            app.chooseOutputTypeLabel.HorizontalAlignment = 'right';
            app.chooseOutputTypeLabel.Position = [589 141 143 31];
            app.chooseOutputTypeLabel.Text = 'Choose your output type:';

            % Show the figure after all components are created
            app.ProbeDealerUIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = ProbeDealer_Win

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.ProbeDealerUIFigure)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.ProbeDealerUIFigure)
        end
    end
end