function answer = demo3D21( param )
%demo3D21
%
% Trains a generative model of the framework using the holefinding
% functionality. The same demo as demo3D18 but with no scaling of the
% images.

% Created: Ivan E. Cao-Berg
%
% Copyright (C) 2013-2015 Murphy Lab
% Lane Center for Computational Biology
% School of Computer Science
% Carnegie Mellon University
%
% 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
directory = what('demo3D21');

if isfield( directory, 'path' )
    directory = directory.path;
end

cd( directory );

if nargin == 0
    param = struct([]);
end

zipfile = 'cellorganizer_demo_3D3T3.zip';
url = ['http://murphylab.web.cmu.edu/data/3D/3T3' filesep zipfile ];
directory = [ pwd filesep 'jarvik_3D_3T3'];

if ~exist( [pwd filesep zipfile] )
    disp('Downloading dataset');
    urlwrite( url, zipfile );
    disp('Extracting files');
    unzip( zipfile );
else
    disp('Dataset found on disk. Extracting files from existing zipfile');
    if ~exist( [ pwd filesep directory ] );
        unzip( zipfile );
    else
        disp( 'Folder found, skipping unzipping.');
    end
end

%move all the crop images to their own directory
imdir = [ pwd filesep 'jarvik_3D_3T3/'];
cropdir = [imdir 'masks/'];
if ~exist(cropdir, 'dir')
    mkdir(cropdir)
end

files = dir([imdir filesep '*.tif']);

for i = 1:length(files)
    if strfind(files(i).name, 'crop')
        movefile([imdir files(i).name], cropdir)
    end
end

files = dir([imdir '*.tif']);
files = sort_nat({files.name});

for i = 1:length(files)
    cell{i} = @() flipdim(ml_readimage([imdir files{i}]),3);
end

param = ml_initparam( param, ...
    struct( 'masks', [cropdir filesep '*crop.tif']) );

% generic model options
% ---------------------
% model.name                (optional) Holds the name of the model. Default is empty.
param.model.name = '3D_3T3_framework';

% model.id                  (optional) Holds the id of the model. Default is empty.
try
    [status,result] = system( 'uuidgen' );
    param.model.id = result(1:end-1);
catch
    param.model.id = num2str(now);
end

% model.filename            Holds the output filename.
param.model.filename = [ 'model.xml' ];

% nuclear shape model options
% ---------------------------
% nucleus.type              Holds the nuclear model type. Default is "major axis".
param.nucleus.type = 'major axis';

% nucleus.id                (optional) Holds the id of the nuclear model. Default is empty.
try
    [status,result] = system( 'uuidgen' );
    param.nucleus.id = result(1:end-1);
catch
    param.nucleus.id = num2str(now);
end

% cell shape model options
% ------------------------
% cell.type                 Holds the cell model type. Default is "ratio".
param.cell.type = 'ratio';

% cell.id                   (optional) Holds the id the cell model. Default is empty.
try
    [status,result] = system( 'uuidgen' );
    param.cell.id = result(1:end-1);
catch
    param.cell.id = num2str(now);
end

% other options
% -------------
% verbose                   (optional) Displays messages to screen. The default is true.
param = ml_initparam( param, ...
    struct( 'verbose', true ) );

% debug                     (optional) Reports errors and warnings. Default is false.
param = ml_initparam( param, ...
    struct( 'debug', false ) );

% train.flag                (optional) Selects what model is going to be trained ('nuclear',
%                           'framework', or 'all'). Default is 'all'
param.train.flag = 'framework';

% continuous integration flags
param.training = true;
param.synthesis = false;
param.postprocessing = false;

%documentation
param.documentation.description = 'This model has been trained using demo3D21 from CellOrganizer';
param.documentation.dataset = '3D 3T3';
param.documentation.dataset_reference = 'K. Huang and R. F. Murphy (2004) From Quantitative Microscopy to Automated Image Understanding. J. Biomed. Optics 9: 893-912.';
param.documentation.dataset_hyperlink = 'http://murphylab.web.cmu.edu/data/#3D3T3';
param.documentation.author = 'Gregory Johnson';
param.documentation.email = 'gj@andrew.cmu.edu';
param.documentation.copyright = 'Copyright (c) 2007-2015 by the Murphy Lab, Carnegie Mellon University';

%model dimensionality
dimensionality = '3D';

%dataset resolution
param.model.resolution = [0.11, 0.11, 0.5];

%downsampling vector
param.model.downsampling = [2, 2, 1];

%run demo and make profile
if param.training
    profile on
    answer = img2slml( dimensionality, [], cell, [], param );
    profile off
    profsave( profile('info'), 'profile' );
    zip( 'profile.zip', 'profile' )
    rmdir( 'profile', 's' );
end

if param.synthesis
    %try to synthesize images from model
    try
        state = rng(3);
    catch
        state = RandStream.create('mt19937ar','seed', 11);
        RandStream.setDefaultStream(state);
    end
    
    try
        outputDirectory = pwd;
        param = [];
        param.targetDirectory = outputDirectory;
        param.prefix = 'synthesizedImages';
        param.numberOfSynthesizedImages = 5;
        param.compression = 'lzw';
        param.microscope = 'none';
        param.synthesis = 'framework';
        param.verbose = true;
        param.debug = true;
        
        slml2img( {'./model.mat'}, param );
        
        folders = dir( [ pwd filesep filesep param.prefix filesep 'cell*' ] );
        for i=1:1:length(folders)
            folder = folders(i).name;
            synthetic_images_directory = [ pwd filesep param.prefix filesep folder ];
            disp( synthetic_images_directory );
            synthetic_images = dir( [ synthetic_images_directory filesep '*.tif']);
            for j=1:1:length( synthetic_images )
                disp( [ synthetic_images_directory filesep synthetic_images(j).name ] )
                img = tif2img( [ synthetic_images_directory filesep synthetic_images(j).name ] );
                img = im2projection( img );
                img = uint8( img );
                imwrite( img, [ pwd filesep 'synthesizedImages' filesep folder '_ch' num2str(j) '.jpg' ] );
            end
        end
        exit;
    catch
        warning( 'Unable to synthesize images from existing model');
    end
end

if param.postprocessing
    try
        directory = [ pwd filesep 'temp' filesep 'preprocessing' ];
        files = dir( [ directory filesep 'cell*.mat'] );
        
        preprocessed_images_directory = [ pwd filesep 'preprocessed' ];
        if ~exist( preprocessed_images_directory )
            mkdir( preprocessed_images_directory );
        end
        
        for index=1:1:length( files )
            file = [ directory filesep files(index).name ];
            load( file );
            [path, filename, extension ] = fileparts( file );
            img1 = im2projection( segcell );
            img2 = im2projection( segdna );
            img = [ img1 img2 ];
            imwrite( img, [ preprocessed_images_directory filesep filename '.jpg'] );
            clear img img2 img1
        end
    catch
        warning( 'Unable to postprocess images' );
    end
end
end
