function demo3D12( option, frameworkflag, param )
%demo3D12 
%
% Trains a generative model of the framework using one of the four patterns in the HeLa
% dataset

% Created: Ivan E. Cao-Berg
%
% Copyright (C) 2012 Murphy Lab
% Lane Center for Computational Biology
% School of Computer Science
% Carnegie Mellon University
%
% July 27, 2012 I. Cao-Berg Modified demo so that it looks for framework.mat in the current directory as well as in the demo3D11 folder
% July 30, 2012 I. Cao-Berg Fixed a bug in the method that would not set theocation of the framework file is the number of input
%                           arguments was not zero
%               I. Cao-Berg Fixed model parameter that describes pattern name
%               I. Cao-Berg Fixed cytonuclearflag so that it is set to be nuclear when the nucleoli pattern is selected
% July 31, 2012 I. Cao-Berg Fixed model.proteinShape.class that was set to lysosome for all patterns
% Jan 20, 2012 I. Cao-Berg Updated method so that if decompressed folder is
%                          found, it skips decompression of the tarballs
% May 15, 2013 I. Cao-Berg Updated method to support wildcards
%
% March 17, 2014 I . Cao-Berg Updated method so that 3D nuclear models types
%                             is labelled 'major axis'
% April 24, 2014 I. Cao-Berg Fixed bug where it trying to load the
% framework from the models folder instead of the demo3D11 folder
%
% 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
    
curr_path = which('demo3D12.m');
curr_path = curr_path(1:end-10);
cd(curr_path);

patterns = {'Nuc', 'Mit', 'LAM', 'TfR' };
url = 'http://murphylab.web.cmu.edu/data/Hela/3D/multitiff';

if nargin == 0
 fprintf(1,'%s\n', 'demo2D02 - Train a 3D generative model' );
 fprintf(1,'%s\n%s\n%s\n%s\n%s\n', 'Select a dataset to download','(1) LAM', '(2) Mit', '(3) Nuc', '(4) TfR' );
 option = input('? ');

 fprintf(1,'%s\n', 'Would you like to use a framework trained using the four patterns in the HeLa dataset? (0) No (1) Yes)' );
 frameworkflag = input('? ');
end

%icaoberg 27/7/2012
if nargin == 0 | nargin == 1
 if strcmpi( lower(frameworkflag), 'yes' )
    frameworkflag = true;
 else
    frameworkflag = false;
 end
end

if ~exist('param', 'var')
    param = [];
end

if ~isa( frameworkflag, 'logical' )
   warning( 'Input variable framework flag must be boolean. Exiting demo.' );
   return
end

%icaoberg 07/30/2012
if frameworkflag
    if exist( './framework.mat' )
       frameworklocation = './framework.mat';
    elseif exist( '../demo3D11/framework.mat' )
       frameworklocation = '../demo3D11/framework.mat';
    else
       warning('File framework.mat is not present in the current directory. Setting frameworkflag to false.');
       return
    end
end

%icaoberg 12/21/2013
if nargin == 2
    param = [];
    model = [];
else
    try
        model = param.model;
    catch
        model = [];
    end
end

model = ml_initparam( model, ...
    struct( 'downsampling', [5,5,1] ) );
model = ml_initparam( model, ...
    struct( 'proteinUpsampleZ', 5 ) );

param = ml_initparam( param, ...
    struct( 'seed', 3 ) );
param = ml_initparam( param, ...
    struct( 'preprocess', true ) );

param.model = model;
clear model

switch option
case 1
   pattern = 'LAM';
   directory = [ pwd filesep 'LAM' ];
   param.protein.class = 'lysosome';
   param.protein.name = 'lamp2';
   param.nucleus.name = 'lamp2';
   param.cell.model = 'lamp2';
case 2
   pattern = 'Mit';
   directory = [ pwd filesep 'Mit' ];
   param.protein.class = 'mitochondrion';
   param.protein.name = 'mito';
   param.nucleus.name = 'mit';
   param.cell.model = 'mit';
case 3
   pattern = 'Nuc';
   directory = [ pwd filesep 'Nuc' ];
   param.protein.class = 'nucleoli';
   param.protein.name = 'nuc';
   param.nucleus.name = 'nuc';
   param.cell.model = 'nuc';
case 4
   pattern = 'TfR';
   directory = [ pwd filesep 'TfR' ];
   param.protein.class = 'endosome';
   param.protein.name = 'transferrin';
   param.nucleus.name = 'transferrin';
   param.cell.model = 'transferrin';
otherwise
   warning( 'CellOrganizer: Unknown/unrecognized option.' );
   return
end

tarball = [ '3DHela_' pattern '.tgz' ];
url = 'http://murphylab.web.cmu.edu/data/Hela/3D/multitiff';
   
if ~exist( [pwd filesep tarball] )
 disp('Downloading dataset');
 urlwrite([url filesep tarball], tarball);
 disp('Extracting files');
 untar( tarball );
else
    disp('Pattern found on disk. Extracting files from existing tarball');
    if ~exist( directory )
        disp('Extracting files');
        system(['tar -xvf ' tarball] );
    else
        disp('Directory found. Skipping decompression');
    end
end

dimensionality = '3D';
answer = false;

dna = [directory filesep 'cell*ch0*.tif'] ;
cell = [directory filesep 'cell*ch1*.tif'];
protein = [directory filesep 'cell*ch2*.tif'];
param.masks = [directory filesep 'cell*mask*.tif'];

% param.masks = [directory filesep 'cell*mask*.tif'];

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

% 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 = [ lower(pattern) '.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

% protein shape model options
% ---------------------------
% protein.type              (optional) Holds the protein model type. The default is "vesicle".
param.protein.type = 'vesicle';

% protein.id                (optional) Holds the id of the protein model. The default is empty.
try
   [status,result] = system( 'uuidgen' ); 
   param.protein.id = result(1:end-1);
catch
   param.protein.id = num2str(now);
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.
if strcmpi( param.protein.class, 'nuc' )
   param.protein.cytonuclearflag = 'nuc';
else
   param.protein.cytonuclearflag = 'cyto';
end

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

% debug                     (optional) Reports errors and warnings. Default is false.
param.debug = true;

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

%documentation
param.documentation.description = 'This model has been trained using demo3D12 from CellOrganizer';

%model resolution
%this is the resolution of the datasets
param.model.resolution = [0.049, 0.049, 0.2000];

answer = img2slml( dimensionality, dna, cell, protein, param );

if frameworkflag
   disp('Replacing current framework with a framework trained on the four protein patterns in the HeLa dataset');
   temp = load( frameworklocation );
   load([lower(pattern) '.mat']);
   model.nuclearShapeModel = temp.model.nuclearShapeModel;
   model.cellShapeModel = temp.model.cellShapeModel;
   save([lower(pattern) '.mat'], 'model' ); 
end
