function answer = img2slml( varargin )
% IMG2SLML Trains a generative model of protein subcellular location from a
% collection of microscope images and saves the model as an SLML instance. An SLML model
% consists of four components, a (optional) documentation component, a nuclear pattern model,
% a cell pattern model and a protein pattern model. The input argument param holds the valid
% options for these components.
%
% Arguments                   Description
% ---------                   ------------
% dimensionality              2D/3D
% dnaImagesDirectoryPath      DNA images collection directory
% cellImagesDirectoryPath     Cell images collection directory
% proteinImagesDirectoryPath  Protein images collection directory
% param                       Parameter structure
%
% The shape of param is described
%
% List Of Parameters        Descriptions
% ------------------        ------------
% documentation (optional)
% ------------------------
% This is an optional structure with multiple elements that holds documentation about this model.
%
% documentation.<name>      Holds the value of variable <name>. This is meant to be meta information. Default is empty.
%
% generic model options
% ---------------------
% model.name                (optional) Holds the name of the model. Default is empty.
% model.id                  (optional) Holds the id of the model. Default is empty.
% model.filename            Holds the output filename.
% model.resolution          Model resolution (in microns per pixel). This
%                           the resolution of the dataset used to train the model
% model.downsampling        Downsampling vector used during preprocessing. Default value is
%                           [5 5 1]. Final model resolution will be resolution * downsampling
%                           vector and will be saved in the model as well
%
% nuclear shape model options
% ---------------------------
% nucleus.type              Holds the nuclear model type. Default is
%                           "medial axis" for 2D and "major axis" for 3D
% nucleus.name              (optional) Holds the name of the nuclear model. Default is empty.
% nucleus.id                (optional) Holds the id of the nuclear model. Default is empty.
%
% cell shape model options
% ------------------------
% cell.type                 Holds the cell model type. Default is "ratio".
% cell.name                 (optional) Holds the name of the cell model. Default is empty.
% cell.id                   (optional) Holds the id the cell model. Default is empty.
%
% protein shape model options
% ---------------------------
% protein.type              (optional) Holds the protein model type. The default is "vesicle".
% protein.name              (optional) Holds the name of the protein model. The default is empty.
% protein.id                (optional) Holds the id of the protein model. The default is empty.
% protein.class             Holds the protein class, e.g. lysosome, endosome.
% protein.cytonuclearflag   (optional) Determines whether the protein pattern will be generated in
%                           the cytosolic space ('cyto'), nuclear space ('nuc') or everywhere ('all').
%                           Default is cyto.
%
% other options
% -------------
% verbose                   (optional) Displays messages to screen. Default is true.
% debug                     (optional) Reports errors and warnings. Default is false.
% train.flag                (optional) Selects what model is going to be trained ('nuclear',
%                           'framework', or 'all'). Default is 'all'.
% masks                     (optional) A string with 

% Author: Ivan E. Cao-Berg (icaoberg@cmu.edu)
%
% Copyright (C) 2007-2014 Murphy Lab
% Lane Center for Computational Biology
% School of Computer Science
% Carnegie Mellon University
%
% March 9, 2012 I. Cao-Berg Added documentation and updated license file
% March 9, 2012 I. Cao-Berg Added new input argument list for CellOrganizer but also
%               kept backward compatibility with SLML Toolbox
% March 9, 2012 I. Cao-Berg Removed output argument model.
% March 28, 2012 I. Cao-Berg Added a control structure under which if img2model returns
%                            an empty model structure, the method exits
% March 28, 2012 I. Cao-Berg Removed saving of temporary models for debugging purposes and
%                            added backward compatibility mode message to screen
% March 28, 2012 I. Cao-Berg Added verification of input arguments when running in compatibility
%                            mode (compatible with SLML Tools)
% March 28, 2012 I. Cao-Berg Added verification of input arguments when running in default
%                            mode (CellOrganizer)
% April 11, 2012 I. Cao-Berg Added debug flag to parameter structure and set the default value
%                            to false
% April 17, 2012 I. Cao-Berg Added cytonuclearflag to the protein model
% July 3, 2012   M. Mackie   Added train.flag to the parameter structure
%                            with the default value of 'all'
% July 5, 2012 I. Cao-Berg   Fixed a bug where the default value was not set properly
% July 9, 2012 I. Cao-Berg   Updated code so that when debug flag is set true, it saves the model as a mat file
%                            Fixed bug that replaced the model.id and model.name to the default values
%                            Updated code to include all possible options of the input parameter structure
% Nov 9, 2012 D. Sullivan    Fixed bug in the param try catch that set
%                            model.cellShapeModel.type to param.nucleus.type instead of param.cell.type
% Jan 20, 2013 I. Cao-Berg   Removed examples 1 and 2 from documentation.
%                            Users should refer to demos for examples.
% Jan 28, 2013 I. Cao-Berg   Updated method so that models are saved as mat
%                            files instead of XML models
% Jan 30, 2013 I. Cao-Berg   Updated code so that parameter display is
%                            always false
% Feb. 1, 2013 I. Cao-Berg   Method requires model resolution as part of
%                            the parameter structure
% Feb 22, 2013 D. Sullivan   Changed call to img2model to accept the
%                            updated param structure
% Feb 24, 2013 D. Sullivan   Added param.model.protein_resolution from
%                            param.model.original_resolution so it can be
%                            adjusted later.
% May 2, 2013 I. Cao-Berg    Fixed method so that it uses default value
%                            when param.train.flag not recognized
% May 9, 2013 I. Cao-Berg    Updated method so that if will save the
%                            metadata of the model iff a model exists. This prevents inclusion of
%                            empty model fields
% May 17, 2013 I. Cao-Berg   Updated methods so that they will save empty fields to SLML instance
% 
% March 17, 2014 I. Cao-Berg Updated method so that 3D nuclear models types
%                            are labelled 'major axis' instead of 'medial axis'
% March 19, 2014 I. Cao-Berg Updated demo so that if output filename is a
%                            folder it will create the file model.mat in
%                            that folder. Also if the extension is other
%                            then .mat it will save it as a mat file
% April 24, 2014 I. Cao-Berg Fixed bug that was saving the downsampled
%                            resolution to the protein model instead of the
%                            original resolution
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published
% by the Free Software Foundation; either version 2 of the License,
% or (at your option) any later version.
%
% This program is distributed in the hope that it will be useful, but
% WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
% General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
% 02110-1301, USA.
%
% For additional information visit http://murphylab.web.cmu.edu or
% send email to murphy@cmu.edu

%icaoberg 7/3/2013
answer = false;

%icaoberg moved upward so it is accesible to all methods

%checks the contents of the structure holding the parameters
try
    param = varargin{5};
    if ~isa( param, 'struct' )
        warning('CellOrganizer: Input parameter list must be a structure.');
    end
    param.slml.level = '1';
    param.slml.version = '1.1';
catch
    param = [];
    param.slml.level = '1';
    param.slml.version = '1.1';
    param.display = false;
    param.debug = false;
    param.verbose = true;
end

param = ml_initparam(param, ...
    struct('saveIntermediateResults', true));

try
    verbose = param.verbose;
    if ~isa( verbose, 'logical' )
        verbose = true;
    end
catch
    verbose = true;
end

%D. Sullivan 6/4/13 fixed assignment mismatch bug-verbose was being set
%instead of display
try
    display = param.display;
    if ~isa( display, 'logical' )
        dislpay = false;
    end
catch
    display = false;
    param.display = display;
end

try
    debug = param.debug;
    if ~isa( debug, 'logical' )
        param.debug = false;
        debug = false;
    end
catch
    param.debug = false;
    debug = false;
end

%CHECK INPUT ARGUMENTS
if length(varargin) == 5
    %icaoberg march 28, 2012
    dimensionality = varargin{1};
    if ~(strcmpi( dimensionality, '2d' ) || ...
            strcmpi( dimensionality, '3d' ))
        
        %icaoberg 7/3/2013
        warning('Unrecognized or unsupported dimensionality. Exiting method.');
        return
    else
        %icaoberg 9/16/2013
        param.dimensionality = dimensionality;
    end
    
    dnaImagesDirectoryPath = varargin{2};
    cellImagesDirectoryPath = varargin{3};
    proteinImagesDirectoryPath = varargin{4};
    
    %check the contents of param.model
    try
        temp = param.model.name;
        %icaoberg 7/9/2012
        if ~isa( temp, 'char' )
            warning(['CellOrganizer: Optional input argument param.model.name must be a string. ' ...
                'Changing to default value']);
            param.model.name = '';
        end
    catch
        param.model.name = '';
    end
    
    try
        temp = param.model.id;
        %icaoberg 7/9/2012
        if ~isa( temp, 'char' )
            warning(['CellOrganizer: Optional input argument param.model.id must be a string. ' ...
                'Changing to default value']);
            param.model.id = '';
        end
    catch
        param.model.id = '';
    end
    
    %icaoberg 06/02/2013
    try
        downsampling = param.model.downsampling;
    catch
        if strcmpi( dimensionality, '3D' )
            downsampling = [5 5 1];
        else
            downsampling = [1 1];
        end
    end
    
    % model.resolution
    try
        param.model.original_resolution = param.model.resolution;
        %D. Sullivan 2/24/13 added param.model.protein_resolution
        param.model.protein_resolution = param.model.original_resolution;
        
        param.model.downsampling = downsampling;
        param.model.resolution = param.model.resolution .* downsampling;
        clear downsampling
    catch
        disp('Model resolution not set. Exiting method.');
        
        answer = false;
        return
    end
    
    try
        temp = param.model.filename;
        if ~isa( temp, 'char' )
            error('CellOrganizer: Input parameter filename must be a string.');
        end
    catch err
        error( 'CellOrganizer: Unable to set output filename' );
    end
    
    %check the contents of param.nucleus, param.cell and param.protein
    compartments = { 'nucleus', 'cell', 'protein' };
    fields = { 'type', 'name', 'id' };
    for c=1:1:length(compartments)
        compartment = [ 'param.' compartments{c} ];
        for f=1:1:length(fields)
            field = [ compartment '.' fields{f} ];
            try
                eval(['temp=' field ';']);
                if ~isa( temp, 'char' )
                    eval([field '=''''' ';']);
                end
            catch
                eval([field '=''''' ';']);
            end
        end
    end
    
    try
        documentation = param.documentation;
        if ~isa( documentation, 'struct' )
            error('CellOrganizer: Documentation must be a structure.');
        end
    catch
        param.documentation = [];
    end
    
    %mmackie july 3, 2012
    %checking the training flag
    try
        trainFlag = param.train.flag;
        if ~isa( trainFlag, 'char' );
            error('CellOrganizer: training flag must be a string');
        end
    catch
        param.train.flag = 'all';
        %icaoberg july 5, 2012
        trainFlag = param.train.flag;
    end
    
    %icaoberg july 5, 2012
    if ~strcmpi( trainFlag, 'nuclear') && ...
            ~strcmpi( trainFlag, 'framework') && ...
            ~strcmpi( trainFlag, 'all')
        if debug
            disp('CellOrganizer: unrecognized training flag. Using default value.');
        end
        %%%TEMPORARY
        overrideTF = 1;
        if ~overrideTF
            trainFlag = 'all';
        else
            disp('This is a temporary option')
        end
    end
    
elseif length(varargin) == 10
    %icaoberg march 28, 2012
    if verbose
        fprintf( 1, '%s', 'Entering backward compatibility mode' );
    end
    
    dimensionality = varargin{1};
    if ~strcmpi( dimensionality, '2D' ) || ...
            ~strcmpi( dimensionality, '3D' )
        error('CellOrganizer: Unknown or unsupported dimensionality');
    end
    
    dnaImagesDirectoryPath = varargin{2};
    if ~exist( dnaImagesDirectory, 'dir' )
        error('CellOrganizer: DNA images directory does not exist.')
    end
    
    cellImagesDirectoryPath = varargin{3};
    if ~exist( cellImagesDirectory, 'dir' )
        error('CellOrganizer: Cell images directory does not exist.')
    end
    
    proteinImagesDirectoryPath = varargin{4};
    if ~exist( proteinImagesDirectory, 'dir' )
        error('CellOrganizer: Protein images directory does not exist.')
    end
    
    modelName = varargin{5};
    if ~isa( modelName, 'char' )
        error('CellOrganizer: Model name must be a string.');
    end
    
    cellName = varargin{6};
    if ~isa( cellName, 'char' )
        error('CellOrganizer: Cell name must be a string.');
    end
    
    compartmentName = varargin{7};
    if ~isa( compartmentName, 'char' )
        error('CellOrganizer: Compartment name must be a string.');
    end
    
    proteinName = varargin{8};
    if ~isa( proteinName, 'char' )
        error('CellOrganizer: Protein name must be a string.');
    end
    
    documentation = varargin{9};
    if isempty( documentation )
        warning('CellOrganizer: Documentation is empty.');
    elseif ~isa( documentation, 'struct' )
        error('CellOrganizer: Documentation must be a structure');
    end
    
    filename = varargin{10};
    if isempty( filename )
        error( 'CellOrganizer: Filename for output SLML instance cannot be empty.');
    elseif ~isa( filename, 'char' );
        error( 'CellOrganizer: Filename for output SLML instance must be a string.');
    end
else
    %there can only be 5 or 10 input arguments
    error('CellOrganizer: Wrong number of input arguments.');
end

if verbose
    fprintf( 1, '%s\n', 'Checking the existence of temporary folder' );
end

dimensionality = varargin{1};

%TRAIN THE GENERATIVE MODEL
if strcmpi( dimensionality, '2D' )
    % Train a generative model from a set of images
%     model = img2model( dimensionality, ...
%         dnaImagesDirectoryPath, ...
%         cellImagesDirectoryPath, ...
%         proteinImagesDirectoryPath, param );
    model = img2model( dimensionality, ...
        dnaImagesDirectoryPath, ...
        cellImagesDirectoryPath, ...
        proteinImagesDirectoryPath, param );


    %icaoberg march 28, 2012
    if isempty( model )
        disp('CellOrganizer: img2model returned an empty model. Exiting program.')
        return
    end
elseif strcmpi( dimensionality, '3D' )
    
    %D. Sullivan, 2/22/13 changed varargin{5} to updated param structure
    %D. Sullivan 5/3/13 changed varargin{2}-nuc to varargin{3}-cell so that
    %nuclear holefinding will still work
    %     model = img2model( dimensionality, varargin{2},...
    %         param );
    dnaImagesDirectoryPath = varargin{2};
    cellImagesDirectoryPath = varargin{3};
    proteinImagesDirectoryPath = varargin{4};
    
    model = img2model( dimensionality, ...
        dnaImagesDirectoryPath, ...
        cellImagesDirectoryPath, ...
        proteinImagesDirectoryPath, ...
        param );
    
    %icaoberg march 28, 2012
    if isempty( model )
        warning( ['CellOrganizer: img2model returned an empty model. ' ...
            'Exiting program.']);
        return
    end
else
    error(['CellOrganizer: Unknown dimensionality ' dimensionality ]);
end

%PARSE GENERATIVE MODEL INTO SLML INSTANCE
filename = param.model.filename;
if strcmpi( dimensionality, '2D' );
    % Convert the trained model into SLML format
    
    %model2slml( model, modelName, cellName, ...
    %    compartmentName, proteinName, ...
    %    documentation, filename );
    %July 27, 2012 Y.Yu Added the dimensionality field to the model
    if ~isfield(model,'dimensionality')
        model.dimensionality = '2D';
    end
    
    %July 27, 2012 Y.Yu Used the new model2slml method to save slml file
    %model2slml( model, filename );
    
    % model.name                (optional) Holds the name of the model. Default is empty.
    try
        if ~isempty( param.model.name )
            model.name = param.model.name;
        end
    catch
        if debug
            disp('Model name not set. Ignoring meta data field.')
        end
    end
    
    % model.id                  (optional) Holds the id of the model. Default is empty.
    try
        if ~isempty( param.model.id )
            model.id = param.model.id;
        end
    catch
        
        if debug
            disp('Model ID not set. Ignoring meta data field.')
        end
    end
    
    % model.filename            Holds the output filename.
    try
        if ~isempty( param.model.filename )
            model.filename = param.model.filename;
        end
    catch
        
        if debug
            disp('Model filename not set. Ignoring meta data field.')
        end
    end
    
    % nucleus
    % nucleus.name              (optional) Holds the name of the nuclear model. Default is empty.
    try
        if ~isempty( param.nucleus.name )
            model.nuclearShapeModel.name = param.nucleus.name;
        end
    catch
        if debug
            disp('Nuclear shape model name not set. Ignoring meta data field.')
        end
    end
    
    % nucleus.id                (optional) Holds the id of the nuclear model. Default is empty.
    try
        if ~isempty( param.nucleus.id )
            model.nuclearShapeModel.id = param.nucleus.id;
        end
    catch
        if debug
            disp('Nuclear shape model ID not set. Ignoring meta data field.')
        end
    end
    
    % nucleus.type              Holds the nuclear model type. Default is "medial axis"
    try
        if ~isempty( param.nucleus.type )
            model.nuclearShapeModel.type = param.nucleus.type;
        else
             model.nuclearShapeModel.type = 'medial axis';
        end
    catch
        if debug
            disp('Nuclear shape model type not set. Using default: medial axis.')
            model.nuclearShapeModel.type = 'medial axis';
        end
    end
    
    %at this point the param.model.resolution has been checked and is not
    %empty and it exists
    model.nuclearShapeModel.resolution = param.model.resolution;
    
    % cell
    % cell.name                 (optional) Holds the name of the cell model. Default is empty.
    if strcmpi( param.train.flag, 'framework' ) || strcmpi( param.train.flag, 'all' )
        try
            if ~isempty( param.cell.name )
                model.cellShapeModel.name = param.cell.name;
            end
        catch
            if debug
                disp('Cell shape model name not set. Ignoring meta data field.')
            end
        end
        
        % cell.id                   (optional) Holds the id the cell model. Default is empty.
        try
            if ~isempty( param.cell.id )
                model.cellShapeModel.id = param.cell.id;
            end
        catch
            if debug
                disp('Cell shape model ID not set. Ignoring meta data field.')
            end
        end
        
        % cell.type                 Holds the cell model type. Default is "ratio".
        try
            %DPS 11/9/12 fixed bug setting model.cellShapeModel.type to nucleuse
            %instead of cell.
            if ~isempty( para.cell.type )
                model.cellShapeModel.type = param.cell.type;
            else
                model.cellShapeModel.type = 'ratio';
            end
        catch
            if debug
                disp('Cell shape model type not set. Using default: ratio.')
                model.cellShapeModel.type = 'ratio';
            end
        end
        
        %at this point the param.model.resolution has been checked and is not
        %empty and it exists
        model.cellShapeModel.resolution = param.model.resolution;
    end
    
    % protein
    % protein.name              (optional) Holds the name of the protein model. The default is empty.
    if strcmpi( param.train.flag, 'all' )
        try
            if ~isempty( param.protein.name )
                model.proteinModel.name = param.protein.name;
            end
        catch
            if debug
                disp('Protein shape model name not set. Ignoring meta data field.')
            end
        end
        
        % protein.id  (optional) Holds the id of the protein model. The default is empty.
        try
            if ~isempty( param.protein.id )
                model.proteinModel.id = param.protein.id;
            end
        catch
            if debug
                disp('Protein shape model ID not set. Ignoring meta data field.')
            end
        end
        
        % protein.type              (optional) Holds the protein model type. The default is "vesicle".
        try
            if ~isempty( param.protein.type )
                model.proteinModel.type = param.protein.type;
            end
        catch
            if debug
                disp('Protein shape model type not set. Using default: vesicle.')
                model.proteinModel.type = 'vesicle';
            end
        end
        
        %at this point the param.model.resolution has been checked and is not
        %empty and it exists
        model.proteinModel.resolution = param.model.resolution;
        
        %if no class is assigned, set it to []
        model.proteinModel.class = [];
     end
    
    %icaoberg 9/10/2013
    %this helper method transforms the files in the temporary folder into
    %intermediate results
    disp( 'Building intermediate results' );
    make_intermediate_results_from_temp_folder( param );
    
    %icaoberg 9/10/2013
    %removes temp folder if debug set to true
    if ~debug
        disp( 'Removing temporary folder' );
        rmdir( [ pwd filesep 'temp' ], 's'  );
    end
    
    %July 26, 2012 Y.Yu Save the result as mat file instead of xml file
    save( [filename(1:end-3) 'mat'], 'model' );
    answer = true;
else
    % Conversion of the trained model into SLML format
    % unsupported for 3D models in the current version.
    model.dimensionality = dimensionality;
    
    % model.name                (optional) Holds the name of the model. Default is empty.
    try
        model.name = param.model.name;
    catch
        if debug
            disp('Model name not set. Ignoring meta data field.')
        end
    end
    
    % model.id                  (optional) Holds the id of the model. Default is empty.
    try
        model.id = param.model.id;
    catch
        if debug
            disp('Model ID not set. Ignoring meta data field.')
        end
    end
    
    % model.filename            Holds the output filename.
    try
        model.filename = param.model.filename;
    catch
        if debug
            disp('Model filename not set. Ignoring meta data field.')
        end
    end
    
    % nucleus
    % nucleus.name              (optional) Holds the name of the nuclear model. Default is empty.
    try
        model.nuclearShapeModel.name = param.nucleus.name;
    catch
        if debug
            disp('Nuclear shape model name not set. Ignoring meta data field.')
        end
    end
    
    
    % nucleus.id                (optional) Holds the id of the nuclear model. Default is empty.
    try
        model.nuclearShapeModel.id = param.nucleus.id;
    catch
        if debug
            disp('Nuclear shape model ID not set. Ignoring meta data field.')
        end
    end
    
    % nucleus.type              Holds the nuclear model type. Default is "medial axis"
    try
        model.nuclearShapeModel.type = param.nucleus.type;
    catch
        if debug
            disp('Nuclear shape model type not set. Using default: major axis.')
            model.nuclearShapeModel.type = 'major axis';
        end
    end
    
    if strcmpi( trainFlag, 'framework' ) || strcmpi( trainFlag, 'all' )
        % cell
        % cell.name                 (optional) Holds the name of the cell model. Default is empty.
        try
            model.cellShapeModel.name = param.cell.name;
        catch
            if debug
                disp('Cell shape model name not set. Ignoring meta data field.')
            end
        end
        
        % cell.id                   (optional) Holds the id the cell model. Default is empty.
        try
            model.cellShapeModel.id = param.cell.id;
        catch
            if debug
                disp('Cell shape model ID not set. Ignoring meta data field.')
            end
        end
        
        % cell.type                 Holds the cell model type. Default is "ratio".
        try
            %DPS 11/9/12 fixed bug setting model.cellShapeModel.type to nucleuse
            %instead of cell.
            model.cellShapeModel.type = param.cell.type;
        catch
            if debug
                disp('Cell shape model type not set. Using default: ratio.')
                model.cellShapeModel.type = 'ratio';
            end
        end
    end
    
    if strcmpi( trainFlag, 'all' )
        % protein
        % protein.name              (optional) Holds the name of the protein model. The default is empty.
        try
            if isfield( param.protein, 'name' ) && ~isempty( param.protein.name )
                model.proteinShape.name = param.protein.name;
            end
        catch
            if debug
                disp('Protein shape model name not set. Ignoring meta data field.')
            end
        end
        
        % protein.id  (optional) Holds the id of the protein model. The default is empty.
        try
            model.proteinShape.id = param.protein.id;
        catch
            if debug
                disp('Protein shape model ID not set. Ignoring meta data field.')
            end
        end
        
        % protein.type              (optional) Holds the protein model type. The default is "vesicle".
        try
            model.proteinShape.type = param.protein.type;
        catch
            if debug
                disp('Protein shape model type not set. Using default: vesicle.')
                model.proteinShapeModel.type = 'vesicle';
            end
        end
        
        % protein.class             Holds the protein class, e.g. lysosome, endosome.
        try
            model.proteinShape.class = param.protein.class;
        catch
            if debug
                disp('Protein shape model class not set. Ignoring meta data field.')
            end
        end
        
        % protein.cytonuclearflag   (optional) Determines whether the protein pattern will be generated in
        %                           the cytosolic space ('cyto'), nuclear space ('nuc') or everywhere ('all').
        %                           Default is cyto.
        try
            flag = param.protein.cytonuclearflag;
            if ~strcmpi( flag, 'cyto' ) && ~strcmpi( flag, 'nuc' ) ...
                    ... & ~strcmpi( flag, 'all' )
                    if debug
                    warning('Protein shape model cytonuclear flag is unrecognized. Using default: cyto.');
                    end
                    flag = 'cyto';
            end
            
            model.proteinShape.cytonuclearflag = flag;
            clear flag;
        catch
            if debug
                warning( 'Protein shape model cytonuclear flag not set. Using default: cyto.');
            end
            model.proteinShape.cytonuclearflag = 'cyto';
        end
        
        %set model dimensionality
        model.proteinShape.dimensionality = dimensionality;
        
        %dpsulliv 2/24/13
        %There are no assumptions of similar resolution, therefore there
        %must be separate resolutions tracked for framework and protein
        model.nuclearShapeModel.resolution = param.model.resolution;
        model.cellShapeModel.resolution = param.model.resolution;

        %icaoberg 4/23/2014
        %included missing protein shape resolution;
        %fixed bug where it was saving the wrong resolution. it was saving
        %the downsampled resolution instead of the protein resolution
        model.proteinShape.resolution = param.model.protein_resolution;
    end
    
    try
        model.documentation = param.documentation;
        model.documentation.date = date;
    catch
        model.documentation.date = date;
    end
   
    %icaoberg 3/19/2014
    if isdir( filename )
        if strcmpi( filename(end), filesep )
            filename = [ filename 'model.mat' ];
        else
            filename = [ filename filesep 'model.mat' ];
        end
    else
        [ path, name, extension ] = fileparts( filename );
        
        if strcmpi( extension, '.mat' )
            filename = filename;
        else
            if isempty( path )
                filename = [ pwd filesep name '.mat' ];
            else
                filename = [ path filesep name '.mat' ];
            end
        end
    end
    
    %icaoberg 3/19/2014
    %to make it work with older versions of matlab
    try
        save( filename, 'model', '-v7.3' );
    catch
        save( filename, 'model' );
    end
    
    answer = true;
    
    %icaoberg 9/10/2013
    %this helper method transforms the files in the temporary folder into
    %intermediate results
    if param.saveIntermediateResults
        make_intermediate_results_from_temp_folder( param );
    end
    %icaoberg 9/10/2013
    %removes temp folder if debug set to true
    if ~debug
        disp( 'Removing temporary folder' );
        rmdir( [ pwd filesep 'temp' ], 's'  );
    end
    
    
end%3D
end%img2slml
