function main_datasim(~,~)
%main_datasim Pilot the task SIMULATION OF AN OBSERVATION DATASET
% INPUT are ignored
%% ======================================================
global input_error;
input_error=[];
% input_error: fieldnames of  input_error will be equal to the tag property
% of the uicontrol where an error has been found by the function 
% control_saisie

%% Create the main figure

% Button help
help_icon = imread('SRC/IMG/help.jpg', 'jpg');

bgcolor = [0.95 0.95 0.95 ];
h=figure('units','normalized',...
    'color',[1 1 1],...
    'position',[.1 .1 .8 .8],...
    'numbertitle','off',...
    'menubar','none',...
    'resize','off',...
    'tag','interface',...
    'keypressfcn',@raccourci_clavier,...
    'userdata', {'simulation of an observation dataset', '1'}, ...
    'CloseRequestFcn',@my_closereq);
% full size figure
maximize
% figure title
set(h, 'Name', sprintf('FILTREX: SIMULATION OF AN OBSERVATION DATASET'));

%% menus of the top bar
% To center the menu above hpanel_control
for i=1:3
    uimenu(  'Label','      ');
end

% Model choice
edit = uimenu('Label','Dynamics');
uimenu(edit,'Label','Model equation',...
    'Accelerator','D',...
    'Callback',@dynamique_simul)
uimenu(edit,'Label','Fix/unfix parameters',...
    'tag','dynamique_tag',...
    'visible','off');
% plagesmax_mod: unused here
uimenu(edit,'Label','Set parameters to the maximal range', ...
    'tag', 'plagesmax_tag', ...
    'Callback',@plagesmax_mod, ...
    'visible','off');
uimenu(edit, 'Label', 'Reset parameters to default values', ...
       'tag', 'resetmod_tag', ...
       'Visible', 'off', ...
    'Callback',@reinit_mod);
uimenu(edit,'Label','Help about model equations', ...
    'Separator','on',...
    'Userdata', 1, ...
    'Callback',@help_dynamics);

% Reinitialisation
raz = uimenu('Label','Reset to default values');
uimenu(raz, 'Label', 'Simulation parameters', ...
    'Callback',@reinit_param_simuldon);
uimenu(raz, 'Label', 'Model parameters', ...
       'tag', 'resetdparam_tag', ...
       'Visible', 'off', ...
    'Callback',@reinit_mod);
uimenu(raz, 'Label', 'All', ...
    'Accelerator','Z',...
    'Callback',@reinitialiser);

%  Save
sauver = uimenu('Label','Save');
uimenu(sauver, 'Label', 'Save observations',...
    'Accelerator','S',...
    'Callback',@saveSimul);
uimenu(sauver, 'Label', 'Save project', ...
    'Callback',@sauver_sim);

% Restore project
uimenu('Label','Restore project',...
    'Interruptible','off',...
    'Accelerator','R',...
    'Callback',@restore_sim);

%% Infos
helpm=uimenu('Label','Help');
uimenu(helpm, 'Label','Pratical Tips',...
    'Callback',@filtrexSimulhelp,...
    'Accelerator','H');
uimenu(helpm, 'Label','Help about model equations', ...
    'Separator','on',...
    'Callback',@help_dynamics);

uimenu('Label','About',...
    'callback',@about);

%Menus to quit
uimenu('Label','Return to menu',...
    'Interruptible','off',...
    'userdata', {'' '2'}, ...
    'Callback',@my_closereq, ...
    'Separator','on');
uimenu('Label','Quit task',...
    'Interruptible','off',...
    'userdata', {'' '1'}, ...
    'Callback',@my_closereq, ...
    'Separator','on');
uimenu('Label','Quit FILTREX',...
    'Interruptible','off',...
    'Callback','delete(gcf)',...
    'Separator','on');
uimenu('Label','Quit Matlab',...
    'Interruptible','off',...
    'BusyAction','cancel',...
    'Callback','exit',...
    'Separator','on',...
    'Accelerator','Q');
%% End of topbar menus

% hpanel_control: input panel
hpanel_control=uipanel('FontSize',30,...
    'borderWidth',3,...
    'Position',[.05 .05 0.4 .92]);
% hpanel_work: result panel
hpanel_work=uipanel('FontSize',30,...
    'borderWidth',3,...
    'BackgroundColor',[1 1 1],...
    'Position',[.45 .05 0.5 .92]);

% Split hpanel_control into different parts
groupebutton2 = uibuttongroup('Parent',hpanel_control,...
    'backgroundcolor', bgcolor,...
    'Position',[0 .65 1 .35]);
groupebutton_filtre = uibuttongroup('Parent',groupebutton2,...
'backgroundcolor',bgcolor,...
    'Position',[.0 .9 1 .1]);
uicontrol('parent',groupebutton_filtre,...
    'units','normalized',...
    'fontsize',10,...
    'foregroundcolor',[.4 0 .2],...
    'backgroundcolor',bgcolor,...
    'position',[0 0 1 0.8],...
    'style','text',...
    'backgroundcolor',bgcolor,...
	  'string','SIMULATION PARAMETERS');


% Columns width
largeur=0.8/3;
marge=0.02;
bas=0.09;
uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'fontsize',9, ...
    'position',[marge .18 largeur .1],...
    'backgroundcolor',bgcolor,...
    'style','checkbox',...
    'tag','uniformeS_tag',...
    'value', 1, ...
    'callback', @MAJ_TIRAGE, ...
    'string','UNIFORM SAMPLING');

uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'fontsize',9, ...
    'position',[marge bas largeur .1],...
    'backgroundcolor',bgcolor,...
    'style','checkbox',...
    'tag','gaussienS_tag',...
    'callback', @MAJ_TIRAGE, ...
    'string','NORMAL SAMPLING');


uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'fontsize',9, ...
    'position',[marge+largeur .18 largeur .1],...
    'backgroundcolor',bgcolor,...
    'style','checkbox',...
    'tag','varcte_tag',...
    'value', 1, ...
    'callback', @maj_refvalue, ...
    'string','CONSTANT VARIANCE');

uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'fontsize',9, ...
    'position',[marge+largeur bas largeur .1],...
    'backgroundcolor',bgcolor,...
    'style','checkbox',...
    'tag','novarcte_tag',...
    'value', 0, ...
    'callback', @maj_refvalue, ...
    'string','NON CONSTANT VARIANCE');





groupebutton21 = uibuttongroup('Parent',groupebutton2,...
    'Position',[0 .32 .15 .58]);
uicontrol('parent',groupebutton21,...
    'units','normalized',...
    'position',[0 0 1 1],...
    'backgroundcolor', bgcolor,...
    'style','text', ...
    'tag','cvinparam_tag');
groupebutton22 = uibuttongroup('Parent',groupebutton2,...
'backgroundcolor', bgcolor,...
    'Position',[.15 .32 .25 .58]);


groupebutton23 = uibuttongroup('Parent',groupebutton2,...
'backgroundcolor', bgcolor,...
    'Position',[.4 .32 .4 .58]);
groupebutton24 = uibuttongroup('Parent',groupebutton2,...
'backgroundcolor', bgcolor,...
    'Position',[.8 .32 .2 .58]);

%% Characteristics of the observations dataset
groupebuttonfic= uibuttongroup('Parent',hpanel_control,...
    'backgroundcolor',bgcolor,...
    'Position',[0 0.6 1 .05]);
uicontrol('parent',groupebuttonfic,...
    'units','normalized',...
    'position',[0 0.05 1 0.95],...
    'FontSize', 10, ...
    'style','text',...
    'tag','fichier_chemin_tag',...
    'backgroundcolor',bgcolor,...
    'visible', 'off');
uicontrol('parent',groupebuttonfic,...
    'units','normalized',...
    'position',[0 0 1 0.5],...
    'FontSize', 10, ...
    'style','text',...
	  'String', 'Equidistant times', ...
    'tag','fichier_descr_tag',...
    'backgroundcolor',bgcolor,...
    'visible', 'on');

%% Model panels
groupebutton3 = uibuttongroup('Parent',hpanel_control,...
    'Position',[0 0 1 .6],...
    'tag','groupebutton3_tag');
uicontrol('parent',groupebutton3,...
    'units','normalized',...
    'fontsize',15,...
    'position',[0 0 1 1],...
    'style','text',...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor',[0 0 0],...
    'tag','modele_tag',...
    'string','');
uicontrol('parent',groupebutton3,...
    'units','normalized',...
    'fontsize',10,...
    'position',[.25 .8 .50 .05],...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor','k',...
    'style','text',...
    'string','A PRIORI PARAMETER VALUES',...
    'tag','val_tag',...
    'visible','off');
% Parameters names
uibuttongroup('Parent',groupebutton3,...
    'Position',[.25 0 .15 .8],...
    'tag','groupebutton30_tag');
% Parameters values
uibuttongroup('Parent',groupebutton3,...
    'Position',[.4 0 .10 .80],...
    'tag','groupebutton31_tag');
% Note: MIN, MAX et bruit ignores ici  mais les panels doivent exister
% pour pouvoir appeler trace_modele
uicontrol('parent',groupebutton3,...
    'units','normalized',...
    'fontsize',10,...
    'position',[.3 .80 .12 .05],...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor','k',...
    'style','text',...
    'string','MIN',...
    'tag','min_tag',...
    'visible','off');
uicontrol('parent',groupebutton3,...
    'units','normalized',...
    'fontsize',10,...
    'position',[.45 .80 .12 .05],...
    'style','text',...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor','k',...
    'string','MAX',...
    'tag','max_tag',...
    'visible','off');
uibuttongroup('Parent',groupebutton3,...
    'Position',[.45 0 .15 .80],...
    'tag','groupebutton32_tag');
uicontrol('parent',groupebutton3,...
    'units','normalized',...
    'fontsize',10,...
    'position',[.6 .80 .4 .05],...
    'style','text',...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor','k',...
    'string','NOISE of log10(CFU/ml) in %',...
    'tag','bruit_tag',...
    'visible','off');
uibuttongroup('Parent',groupebutton3,...
    'Position',[.6 0 .3 .80],...
    'tag','groupebutton33_tag');




uicontrol('parent',hpanel_control,...
    'units','normalized',...
    'position',[ 0.92 0 0.08 0.05],...
    'FontUnits', 'normalized', ...
    'FontSize', 0.3, ...
    'interruptible','on',...
    'BusyAction','cancel',...
    'tag','simulation_tag',...
    'Style','pushbutton',...
    'String','GO',...
    'userdata',0,...
    'backgroundcolor','r', ...
    'callback',@SIMULATION);


data = init_simulation(largeur, groupebutton2, groupebutton21,groupebutton22,...
    groupebutton23,groupebutton24, ...
    help_icon, bgcolor);
% Initialisation de l'unite de temps
data.uniteT=2;
data.uniteT_libelle='hour';



%% save the graphical components of the panels
handles=guihandles(1);
% concatenation of the structures handles and data
data=catstruct(handles,data);

% save the results panel
data.hpanel_work=hpanel_work;
%  uptodate the main structure: data
guidata(1,data);
ecr_data();

end %% end main_datasim
%% ======================================================
function[data]= init_simulation(largeur,groupebutton2, groupebutton21,	groupebutton22, ...
    groupebutton23,	groupebutton24,help_icon, bgcolor)
%init_simulation Initialisation of the main structure data:
% add into it the structures Basemodeles, CVs, etc... 
% INPUT
% The components of the input panel
%% ======================================================

data.Basemodeles=init_Basemodeles();
% Note: On n'a pas besoin des CVs, mais les initialiser pour pouvoir utiliser trace_modele
data.CVs=init_CVs();
data.Simul = init_Simul();
data.Filtre=init_Filtre();

% Model variables
data.modelepop={};
data.nomparam={};
data.fctprior={};
data.ajoutbruit=[];
% Observations
data.tobs=[]; % vide mais le champ doit exister pour trace_modele
data.releveobs={};
% Observations time unit is initialized in hour
data.uniteT =2;
data.uniteT_pourcalcul=data.uniteT;
% Time step, supposed to be 1 (used for "reset to default", only):
data.deltaT =1;


%%  Observations model
% Simulation parameters
leschaines = { 'SEED', ...
    '%NOISE of log10(cfu/ml)',  'NUMBER OF TIMES', ...
    'MAXIMAL TIME (hour)', 'NUMBER OF REPLICATIONS', ...
    'REFERENCE MASS (g)'};
% Order in which the Simulation parameters will be displayed
ipres=[6 4 2 1 3 5];

hautcase = 1/6;  %6 boxes; box height
decal=0.02; % gap to put the text a little up when the box is of style 'edit'
bas=0.09;

for i=1:length(data.Simul.nomparamD)
    ii=find(ipres==i);
    var = data.Simul.nomparamD{ii};
    data.(var) = data.Simul.valparamD{ii};
    tag=[var 'txt_tag'];
    if i <length(data.Simul.nomparamD)
        uicontrol('parent',groupebutton23,...
            'units','normalized',...
            'fontsize',8,...
            'foregroundcolor',[.4 0 .2],...
            'backgroundcolor',bgcolor,...
            'position',[0 (1-hautcase*i)-decal 1 hautcase-2*decal],...
            'style','text',...
            'tag', tag, ...
            'string',leschaines{ii});
    else
        % Repositioning to adjust the last box
        uicontrol('parent',groupebutton23,...
            'units','normalized',...
            'fontsize',8,...
            'foregroundcolor',[.4 0 .2],...
            'backgroundcolor',bgcolor,...
            'position',[0 0 1 hautcase-2*decal],...
            'style','text',...
            'tag', tag, ...
            'string',leschaines{ii});
    end
    
    tag=[var,'_tag'];
    
    if strfind(leschaines{ii}, 'SEED')
        %  alpha-numeric value to be checked
        hd=uicontrol('parent',groupebutton24,...
            'units','normalized',...
            'position',[0 1-hautcase*i 1 hautcase],...
            'backgroundcolor','w',...
            'tag',tag, ...
            'callback',@control_saisie_an, ...
            'userdata', {data.Simul.DF{ii},leschaines{ii}}, ...
            'interruptible','off',...
            'style','edit');
    else
        hd=uicontrol('parent',groupebutton24,...
            'units','normalized',...
            'position',[0 1-hautcase*i 1 hautcase],...
            'backgroundcolor','w',...
            'tag',tag, ...
            'callback', @control_saisie_data, ...
            'userdata', {data.Simul.DF{ii},leschaines{ii}}, ...
            'interruptible','off',...
            'style','edit');
    end
    
    set(hd,'string',eval(['data.',var]))
    
end %for i


% Help icon sur les temps
uicontrol('parent',groupebutton23,...
    'units','normalized',...
    'fontsize',8,...
    'foregroundcolor',[.4 0 .2],...
    'backgroundcolor',bgcolor,...
    'position',[0.8 0.7 0.05 0.1],...
    'tag', 'help_maxtime_tag', ...
    'cdata', help_icon, ...
    'enable', 'inactive', ...
    'ButtonDownFcn', @help_maxtime);



    
% To save tobs
uicontrol('tag', 'tobs_tag', ...
    'value', [], ...
    'visible','off');

uicontrol('parent',groupebutton21,...
    'units','normalized',...
    'fontsize',9,...
    'foregroundcolor',[.3 .1 .5],...
    'backgroundcolor',bgcolor,...
    'position',[0 1-(3*hautcase) 1 hautcase],...
    'style','text',...
    'string', {'OBSERVATION', ' TIMES'});

% Choice of the way the times are specified
groupechoix1 = uibuttongroup('Parent',groupebutton22,...
'Position',[0 0.5 1 0.5], ...
   'SelectionChangeFcn', @gestion_choixtemps);

% Make a frame around groupechoix1
uibuttongroup('parent',groupebutton22,...
'backgroundcolor', bgcolor,...
 'units','normalized',...
'Position',[0 0.5 1 0.5]);


nchoix=1/3;
for i=1:3 % they are 3 ways to enter the observations times
    valeur=0; % initialisation to "no selectionned"
    switch i
        case 1
            chaine='KEYBOARD';
        case 2
            chaine='FILE';
        case 3
            chaine='EQUIDISTANT';
            valeur=1; %default choice
    end
    

        hd=    uicontrol('parent',groupechoix1, ...
            'units','normalized',...
            'fontsize',9,...
            'foregroundcolor',[.3 .1 .5],...
            'backgroundcolor',bgcolor,...
            'position',[0 1-nchoix*i 1 nchoix],...
            'tag', chaine, ...
            'style','radiobutton',...
             'string',chaine);
        set(hd, 'value', valeur);
end

%% Help button sur les modes de saisie
uicontrol('parent',groupebutton22,...
    'units', 'normalized', ...
    'style', 'pushbutton', ...
    'position',[0.7 0.7 0.07 0.1],...
    'backgroundcolor',bgcolor,...
    'cdata', help_icon, ...
    'enable', 'inactive', ...
    'ButtonDownFcn', @help_temps);



%% Choice of the time unit

 groupechoix2 = uibuttongroup('Parent',groupebutton22,...
      'SelectionChangeFcn', @gestion_unittemps, ...
      'Position',[0 0 1 0.5]);
% Make a frame around groupechoix2
uibuttongroup('parent',groupebutton22,...
'backgroundcolor', bgcolor,...
 'units','normalized',...
'Position',[0 0 1 0.5]);

  for i=1:3 % they are 3 ways to enter the time unit
      valeur=0; % initialisation to "no selectionned"
      switch i
          case 1
              chaine='IN DAY';
              letag='day';
          case 2
              chaine='IN HOUR';
              letag='hour';
              % no default choice valeur=1; 
          case 3
              chaine='IN MN';
              letag='mn';
      end
      
  
      hd2=    uicontrol('parent',groupechoix2, ...
          'units','normalized',...
          'fontsize',9,...
          'foregroundcolor',[.3 .1 .5],...
          'backgroundcolor',bgcolor,...
          'position',[0 1-nchoix*i 1 nchoix],...
          'tag', letag, ...
          'style','radiobutton',...
                    'string',chaine);
      set(hd2, 'value', valeur);
  end

% Un invisible uicontrol pour que trace_modele sache l'unite de temps
uicontrol('Visible', 'off', ...
    'value',data.uniteT, ...
    'tag','uniteT_tag');

%% Buttons relative to the variance
uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'fontsize',9, ...
    'position', [2*largeur .15 largeur .1],...
    'backgroundcolor',bgcolor,...
    'style','text',...
    'tag','reftxt_tag',...
    'string',data.Simul.chaines{1});



uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'position',[0.8 0.18 0.2 .1],...
    'backgroundcolor','w',...
    'tag', [data.Simul.valnom{1} '_tag'], ...
    'userdata', {{'0.1', '12'}, data.Simul.chaines{1}}, ...
    'string', data.Simul.valD{1}, ...
    'callback',@control_saisie, ...
    'interruptible','off',...
    'visible', 'on', ...
    'style','edit');

% Case where the variance is non constant
uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'fontsize',9, ...
    'position', [2*largeur .15 largeur .1],...
    'backgroundcolor',bgcolor,...
    'style','text',...
    'tag','cpuistxt_tag', ...
    'string',data.Simul.chaines{2}, ...
    'Visible', 'off');

uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'position',[0.8 0.18 0.2 .1],...
    'backgroundcolor','w',...
    'tag',[data.Simul.valnom{2} '_tag'], ...
    'userdata', {{'-10', '10'}, data.Simul.chaines{2}}, ...
    'string', data.Simul.valD{2}, ...
    'callback',@control_saisie, ...
    'interruptible','off',...
    'visible', 'off', ...
    'style','edit');


% %ref value if bias
uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'fontsize',9, ...
    'position', [2*largeur bas largeur .1],...
    'backgroundcolor',bgcolor,...
    'style','text',...
    'tag','deltareftxt_tag',...
    'string',{'', data.Simul.chaines{3}});




uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'position',[0.8 bas 0.2 .1],...
    'backgroundcolor','w',...
    'tag',[data.Simul.valnom{3} '_tag'], ...
    'userdata', {{'0', '50'}, data.Simul.chaines{3}}, ...
    'string', data.Simul.valD{3}, ...
    'callback',@control_saisie, ...
    'interruptible','off',...
    'visible', 'on', ...
    'style','edit');

uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'fontsize',9, ...
    'position', [2*largeur bas largeur .1],...
    'backgroundcolor',bgcolor,...
    'style','text',...
    'tag','biaistxt_tag',...
    'visible', 'off', ...
    'string',{'', data.Simul.chaines{4}});

uicontrol('parent',groupebutton2,...
    'units','normalized',...
    'position',[0.8 bas 0.2 .1],...
    'backgroundcolor','w',...
    'tag',[data.Simul.valnom{4} '_tag'], ...
    'userdata', {{'0', '100'}, data.Simul.chaines{4}}, ...
    'string', data.Simul.valD{4}, ...
    'callback',@control_saisie, ...
    'interruptible','off',...
    'visible', 'off', ...
    'style','edit');

%  Help buttons
% when variance is cte
uicontrol('parent',groupebutton2,...
    'units', 'normalized', ...
    'style', 'pushbutton', ...
    'position',[0.45  0.03 0.02 0.045],...
    'backgroundcolor',bgcolor,...
    'tag', 'help_variance_tag', ...
    'cdata', help_icon, ...
    'enable', 'inactive', ...
    'ButtonDownFcn', @help_variance);
% when variance is non cte
uicontrol('parent',groupebutton2,...
    'units', 'normalized', ...
    'style', 'pushbutton', ...
    'position',[0.45  0.03 0.02 0.045],...
    'backgroundcolor',bgcolor,...
    'tag', 'help_powercoeff_tag', ...
    'cdata', help_icon, ...
    'enable', 'inactive', ...
  'Visible', 'off', ...
    'ButtonDownFcn', @help_powercoeff);


end % end function init_simulation
%% ======================================================
function gestion_choixtemps(obj, event)
%gestion_choixtemps Pilot the programs which read the times according to 
% the way these are entered.

%% ======================================================

choix = get(event.NewValue, 'tag');
data=guidata(gcf);
tobs={};
set(data.fichier_chemin_tag,'visible', 'off');

if ~strcmp(choix, 'EQUIDISTANT')
    switch choix
        case 'KEYBOARD'
            [tobs, arret]=saisie_tpsobs();
        case 'FILE'
            [tobs, arret]=read_tpsobs();
        case 'WORKSPACE VARIABLE'
% case removed (kept "au cas ou")
            [tobs, arret]=rapatrie_tobs();
    end
    if arret==1
        % User interruption
        set(obj,'interruptible','on','userdata',0)
        return;
    end
    
    n=size(tobs);
    nelem=n(1)*n(2);
    tobs=reshape(tobs,1,nelem);
    if ~isnumeric(tobs) || any(tobs<0) || isempty(tobs) || length(tobs) <3
        errordlg('The times should be positive or null values and the number of times should  be greater than 2', 'BAD INPUT');
        set(obj,'interruptible','on','userdata',0)
        tobs={};
        Idle(1)
    end
    tobs=sort(tobs);
    
    if ~isempty(tobs)
        % Values have been read
        if tobs(1) ~= 0
            % We add the first value: time 0 always included
            tobs=[0 tobs] ;
        end
        set(data.tobs_tag,'value', tobs);
        set(data.obSmax_tag, 'string', num2str(max(tobs)));
        set(data.help_maxtime_tag, 'Visible', 'off');
        ntobs=length(tobs);
        set(data.nbtimes_tag, 'string', num2str(ntobs));

ecr_data_file(ntobs);

    end
end

if isempty(tobs)|| strcmp(choix, 'EQUIDISTANT')
    % Either fail to enter the times, or switch to   equidistant:
    % reset the relative boxes to default values   
    set(data.EQUIDISTANT, 'value',1);
    set(data.obSmax_tag, 'string', data.Simul.valparamD{4});
         set(data.help_maxtime_tag, 'Visible', 'on');
    set(data.nbtimes_tag, 'string', data.Simul.valparamD{3});
    set(data.tobs_tag,'value',[]) ; % function SIMULATION will generate the times
ecr_data();

end

guidata(1,data);
end % end gestion_choixtemps
%% ======================================================
%% ======================================================
function gestion_unittemps(obj, event)
%gestion_unittemps Pilot the change of the times unit

%% ======================================================
global input_error;
input_error=[];


choix = get(event.NewValue, 'tag');
data=guidata(gcf);

if ~isempty(regexpi(choix, 'day'))
  data.uniteT=1;
  data.uniteT_libelle='day';
end
if ~isempty(regexpi(choix, 'hour'))
  data.uniteT=2;
  data.uniteT_libelle='hour';
end
if ~isempty(regexpi(choix, 'mn'))
  data.uniteT=3;
  data.uniteT_libelle='mn';
end
%l'unite de temps des calculs=celle des donnees
data.uniteT_pourcalcul= data.uniteT;
data.uniteT_pourcalcul_libelle=data.uniteT_libelle;

set(data.obSmaxtxt_tag, 'String', ...
 ['MAXIMAL TIME (' data.uniteT_libelle ' )']);
% l'invisible uicontrol pour que trace_modele sache l'unite de temps
set(data.uniteT_tag, 'value',data.uniteT);


% La verif dela valeur du temps maxi selon l'unite sera faite lors de
% l'exécution 

% Maj de l'affichage du modele selon l'unite de temps des données
maj_timeparam(data, data.uniteT)

guidata(1,data);
end % end gestion_unittemps
%% ======================================================
function[tobs]= genere_tpsobs_bis()
%genere_tpsobs_bis Generate equidistant times
% when the time step is provided in nbtimes_tag rather than the number of times
%% ======================================================
tobs=[];
data=guidata(gcf);
obSmax = str2double(get(data.obSmax_tag, 'string'));
deltaT = str2double(get(data.nbtimes_tag, 'string'));
if deltaT>= obSmax
    %Error
    errordlg(' TIME STEP should be less than  MAXIMAL TIME');
    return
end

tobs = 0:deltaT:obSmax;
if tobs(end) ~= obSmax
    tobs(end+1)=obSmax;
end


set(data.tobs_tag,'value', tobs);
guidata(1,data);
end % end genere_tpsobs_bis

%% ======================================================
function[tobs, deltaT]= genere_tpsobs()
%genere_tpsobs Generate equidistant times
%% ======================================================
tobs=[];
data=guidata(gcf);
obSmax = str2double(get(data.obSmax_tag, 'string'));
nbtemps = str2double(get(data.nbtimes_tag, 'string'));
deltaT= obSmax / (nbtemps-1);
tobs = 0:deltaT:obSmax;

set(data.tobs_tag,'value', tobs);
guidata(1,data);
end % end genere_tpsobs

%% ======================================================
function[tobs, arret]= rapatrie_tobs()
%rapatrie_tobs Get the times from a variable located in the user workspace 
% case removed (kept "au cas ou")
%% ======================================================
arret=0;
prompt = {'Type in the workspace variable which contains the observation times'};
dlg_title = 'Type in the name of the observation times variable';
num_lines = 1;
tobsname = inputdlg(prompt,dlg_title,num_lines);
if isempty(tobsname)
    tobs=[];
    arret=1;
    return;
    % User interruption
end

try
    tobs=  evalin('base', tobsname{1});
catch
    % variable not found
    tobs=[];
end

end %end rapatrie_tobs
%% ======================================================
function ecr_data_file(ntobs)
% ecr_data_file ecrit le cadre des caracteristiques des data
%% ======================================================

data= guidata(1);
nrepet=get(data.repetS_tag, 'string');

set(data.fichier_descr_tag,'visible', 'on', ...
    'String', ...
    [num2str(ntobs) ' observation times; ' ...
    nrepet ' replications. ']);
end % end ecr_data_file
%% ======================================================
function[ret, arret]= saisie_tpsobs()
%saisie_tpsobs Get the times when they are typed in a FILTREX window
%% ======================================================
tobs=[];
arret=0;
prompt = {'Enter observation times, spaced by a new line'};
dlg_title = 'Observation times';
num_lines = 20;
tobs = inputdlg(prompt,dlg_title,num_lines);
if isempty(tobs)
    arret=1;
    return;
    %User interruption
end
ntobs=length(tobs{1});
ret=zeros(ntobs, 1);
for i =1:ntobs
    ret(i)=str2double(tobs{1}(i,:));
end
end %end saisie_tpsobs
%% ======================================================
function[tobs, arret]= read_tpsobs()
%read_tpsobs Get the times when they are stored in a file
%% ======================================================
tobs=[];
arret=0;

[fileName, pathName] = uigetfile( ...
    {'*.xls', 'Excel Files (*.xls)'; ...
    '*.csv', 'CSV files (*.csv)'; ...
    '*.mat', 'MAT-Files (*.mat)'; ...
    '*.*', 'All Files (*.*)'}, ...
    'Select a filename');
if isequal(fileName,0) || isequal(pathName,0)
    arret=1;
    return;
end
chemin=fullfile(pathName, fileName);

data=guidata(1);
set(data.fichier_chemin_tag,'visible', 'on', ...
    'string', ['DATA FILENAME : ', fileName]);

try
    tobs=xlsread(chemin);
catch errx
    try
        tobs=csvread(chemin);
    catch erro
        try
            lu=load(chemin); %lu is a structure
            var=fieldnames(lu); % names of the variables read on the file
            tobs=eval(['lu.' var{1}]); % get the first one
        catch err
            err.message
            errordlg('Reading error');
            tobs=[];
        end
        
        
    end
end

end % end read_tpsobs

%% ======================================================
function raccourci_clavier(~,event)

%% ======================================================
if strcmpi(event.Key,'return')
    SIMULATION()
end
end


%% ======================================================
function MAJ_TIRAGE(obj, ~)
%MAJ_TIRAGE Uptodate the buttons which depend on the way the replications are generated
% INPUT
% Property 'tag' of 'obj' contains the way the replications are generated
%% ======================================================

data=guidata(gcf);
mode = get(obj, 'tag');
switch mode
    case 'gaussienS_tag'
        set(data.uniformeS_tag, 'value', 0);
        set(data.gaussienS_tag, 'value', 1);
    case 'uniformeS_tag'
        set(data.gaussienS_tag, 'value', 0);
        set(data.uniformeS_tag, 'value', 1);
end
% uptodate the main structure: data
guidata(1,data);
end % end MAJ_TIRAGE
%% ======================================================
function SIMULATION(obj,~)
%SIMULATION Main program of the task Dataset Simulation
% INPUT/OUTPUT
% Property 'userdata' of 'obj'is equal to 0 when execution is stopped,
% and 1 otherwise
%% ======================================================
data=guidata(1);
global input_error;
% Input check
if verif_input(obj)==1
    return
end
if control_temps() ==1
    return
end
% Verif des entrees sans valeur par defaut
nbtemps = str2double(get(data.nbtimes_tag, 'string'));
binf= str2double(data.Simul.DF{3}{1});
bsup=str2double(data.Simul.DF{3}{2});
if isnan(nbtemps) || nbtemps < binf || nbtemps > bsup
    errordlg(['Set an integer value to NUMBER OF TIMES between ', ...
        data.Simul.DF{3}{1}, ' and ', data.Simul.DF{3}{2}]);
    input_error.(ntimes)=1;
end

obSmax = str2double(get(data.obSmax_tag, 'string'));
binf= str2double(data.Simul.DF{4}{1});
bsup=str2double(data.Simul.DF{4}{2});
if isnan(obSmax) || obSmax < binf || obSmax > bsup
     errordlg(['Set an integer value to MAXIMAL TIME between ', ...
        data.Simul.DF{4}{1}, ' and ', data.Simul.DF{4}{2}]);
     input_error.(maxtime)=1;
end

% Return if errors
if verif_input(obj)==1
    return
end



% Set property "Pointer" of the figure to busy state
Busy(1)
% Change the GO/STOP button
if get(obj,'userdata')
    set(obj,'interruptible','off','userdata',0)
    return
else
    set(obj,'interruptible','on','userdata',1,'string','STOP')
end


% Uptodate the graphical changes
drawnow
% Delete the possible sons of the input panel hpanel_work
delete(get(data.hpanel_work,'children'))



tobs=get(data.tobs_tag, 'value');

%% Generate the times when they are equidistant
if isempty(tobs)|| get(data.EQUIDISTANT, 'value')==1
    % The times have not been read nor typed in
    [tobs, ~] = genere_tpsobs();
    if isempty(tobs)
        return %error
    end
end % end if


ntobs=length(tobs);

%% NOTE: AFFICHAGE DU NBRE DE TEMPS DE CALCUL
%Calcul du nombre de temps de calcul afin de l'afficher à l'utilisateur:
% on fait un calcul tous les temps entre tobs(end) et 0
% ceux-ci compris
%NOTE: le 1ier temps de calcul est tjrs 0.
% nbtps sert uniquement pour information de l'utilisateur
% nbtps = idivide(int32(tobs(end)), int32(deltaT))+1;
%Prevenir l'utilisateur  du nbre de temps ou il y aura un calcul
% hm=questdlg(['Le pas de temps des calculs  est ', ...
%      int2str(deltaT), ...
%      '=> il y aura ', int2str(nbtps), ' temps de calcul. On y va?'], ...
%      'Accepte-nb-temps', 'Oui', 'Non', 'Oui');
%  switch hm
%      case 'Non'
%          set(obj,'interruptible','on','userdata',0,'string','GO')
%          Idle(1)
%          return;
%  end
%% FIN AFFICHAGE

%% Check that a model has been chosen
if isempty(data.modelepop)
    errordlg('Please, select the dynamics equation model', 'NO MODELE');
    set(obj,'interruptible','on','userdata',0,'string','GO')
    Idle(1)
    return
end

%% Get the parameters values: here, all are fixed
data.nomparam= {};
nomparamS=data.nomparamS;
for i=1:length(nomparamS)
    var=nomparamS{i};
    try
        eval(['data.',var,'=eval(get(data.([var ''_tag'']),''string''));'])
    catch  err
        errordlg(['You have to fix the value of ' var],'Bad value');
        set(obj,'interruptible','on','userdata',0,'string','GO')
        Idle(1)
        return
    end
end

%% No variation  coefficients  here
data.cvinparam_in=0; % CV are not to be estimated

%%  Get the random seed
graine=get(data.graineAleaS_tag,'string');
graineAleaS=str2num(graine);

if isempty(graineAleaS)
    graineAleaS=sum(100*clock);
end
try
    rng(graineAleaS);
catch
    RandStream.setDefaultStream(RandStream('mt19937ar','seed',graineAleaS)); % version 2008b matlab
end

%% Store the model index, and the sort direction (reverse or not) 
% in which the columns D,E,F of the dataset array should be sorted.
% strip the possible blank characters inside the model name
lemodele = strrep(data.modelepop,' ', '');
% strip the possible dashes inside the model name
lemodele = strrep(lemodele,'-', '');
modelepop= eval(['@' lemodele]);

if model_decroit(data.modelepop)==1
        % decreasing models
        triD = 'descend';
        triEF = 'ascend';
else
        % increasing models
        triD = 'ascend';
        triEF = 'descend';
end % end if


%% Build the state vector (vecteur d'etat)
Xt=initialisation_particules_simul(data);

%% uptodate the main structure: data
handles=guihandles(1);
ndata=catstruct(data,handles);
guidata(gcf,ndata);

%% Loop over the times: model calculation
Ytheorique=zeros(ntobs,1);

for i=1:ntobs
    ti=tobs(i);
    Xt = modelepop(Xt,ti,0,  ...
        data.nomparam, data.nomparamS, data);
    
    if any(any(isnan(Xt)))
        % Fail to compute the model
        errordlg(['An error occurred when computing the model at time ' , ...
            num2str(ti)]);
        % uptodate the calling subroutine handle 
        set(obj,'interruptible','on','userdata',0,'string','GO')
        Idle(1)
        return;
    end

    % Ramener a des valeurs valides
        Xt(end, Xt(end, :) < 0) = 0.0;


    % calculation of the theoretical observation 
    Ytheorique(i)=Xt(end);
end % end Loop over the times

%% Generate the columns B,C,D,E,F
[B C D E F]=generBCDEF(data, ntobs);

%% Create the dataset without replications
Xobs = zeros(1, 9, ntobs); % 1 replication, 9 columns
Xobs(1,1,:) =tobs;
Xobs(1,2,:) =repmat(B,  ntobs,1);
Xobs(1,3,:) =repmat(C,  ntobs,1);

% Sort columns D,E,F
Xobs(1,4,:) = sort(D, triD);
switch  triEF
    case 'ascend'
        ind = ntobs:-1:1;
        Xobs(1,5,:) = E(ind);
        Xobs(1,6,:) = F(ind);
    otherwise
        Xobs(1,5,:) =E;
        Xobs(1,6,:) =F;
end


% Note: Sert a rien: Xobs(1,8,:) = Ytheorique; % colonne H

clear B C D E F;


%% Adjust E according to D
% When D=0, we set 1 to E and when C=1 and E=1, we modify E
Xobs(1,5, Xobs(1,4,:)==0) = 1;
Xobs(1,5, (Xobs(1,5,:)==1) & (Xobs(1,3,:)==1)) = 1.0e-2;

% If D (nb dilutions en tube) is not null, E should not 1
Xobs(1,5, (Xobs(1,4,:) ~=0) & (Xobs(1,5,:)==1)) = 0.1;

%% Generation of the replications
% Get the noise or replications variance
pourcentbruitS= eval(get(data.bruitS_tag,'string'));

% Get the way replications should be generated
gaussien = get(data.gaussienS_tag, 'value');

% Get the number of replications 
nrepet = eval(get(data.repetS_tag,'string'));


if get(data.novarcte_tag, 'value') ==1
    % get the bias
    biais0 = eval(get(data.biaisvalue_tag, 'string'));
    % get the exponent
    cpuis=eval(get(data.cpuisvalue_tag, 'string'));
else
    % get the reference value of constant variance
    refvalue= eval(get(data.refvalue_tag, 'string'));
    deltaref=eval(get(data.deltaref_tag, 'string'));
    %  bias indicator
    if deltaref==0
        nobiais= 1;
    else
        nobiais=0;
    end
    
    % 9/9/2013 version : variation gap around constant mean
    ecart = (pourcentbruitS*refvalue)/2;
    becart = (deltaref*refvalue)/100; % for the case with bias
    roundecart= round(ecart)+1; % for the case uniform; randi generates integers from 1
    % it is why we add 1 to the upper bound to the variation interval
    ecart = ecart/100; % for the case gaussian; transform in percentage
end


% Organize the dataset as  observationsX(times, columns B à I)
%shiftdim: we remove the first dimension "repetition"
a=permute(shiftdim(Xobs), [2 1]); % put the times in lines
% Replicate the lines
XXobs = repmat(a, nrepet ,1);
% Sort according to times
Xobs = sortrows(XXobs,1);
clear a XXobs;


badG=0; % number of times when column G is not valid
minG = 1;
maxG = 1500;
% Initialize column G
Xobs(:,7) =maxG+1;

%% Is the model output a neperian log?
if regexp(data.modelepop, 'Ln') ==1
    logy= Ytheorique/log(10); % model output is a neperian log: we convert it into a log10
else
  if model_log10(data.modelepop)==1
        logy=Ytheorique; % already in log10
    else
        logy=log10(Ytheorique); % model calculated under its exponential form
    end
end
labelord='log10 (cfu/ml)';

% We don't accept responses < 1, i.e those for which log10 is <0
logy(logy<0)=0;

%% We generate replications as long as column G is not valid
while any(Xobs(:,7)<minG) || any(Xobs(:,7)>maxG)
    % Note: on fait les calculs, temps par temps, et non pas sur la totalité
    % des vecteurs pour ne pas prendre trop de place mémoire
    ixobs =1;
    
    if get(data.novarcte_tag, 'value') ==1
        Xobs(:, 9)= simulvarnocte(logy,  biais0, pourcentbruitS, cpuis, gaussien, nrepet);
    else
        if ~gaussien
            %  uniform random generation
            %  we put half of the generated replications above 
            %  Ytheorique, and the others below
            % (with a gap, if bias)
            i1 = round(nrepet/2); % number of replications less than Ytheorique
            i2 = nrepet -i1; % number of replications greater than Ytheorique
            for i=1:ntobs
                if roundecart <1
                    % first argument of randi should be >=1
                    repet = zeros(nrepet, 1);
                else
                    repet = randi(roundecart, nrepet, 1);
                    % we subtract 1 because randi has generate from 1
                    repet = (repet-1)/100;
                end
                if nobiais==0
                    % bias
                    signe= randi(2, 1, 1); % integer =1 or =2
                    if signe==2
                        signe=-1;
                    end
                end
                
                
                
                % replications less than Ytheorique
                if (i1>0)
                    
                    Xobs(ixobs:ixobs+i1-1, 9)= logy(i) - repet(1:i1);
                    if nobiais==0
                        Xobs(ixobs:ixobs+i1-1, 9)=Xobs(ixobs:ixobs+i1-1, 9)+(signe.*becart);
                    end
                    ixobs= ixobs +i1;
                end
                % replications greater than Ytheorique
                if (i2>0)
                    Xobs(ixobs: ixobs+i2-1, 9) = logy(i) + repet(i1+1:end);
                    if nobiais==0
                        Xobs(ixobs:ixobs+i2-1, 9)=Xobs(ixobs:ixobs+i2-1, 9)+(signe.*becart);
                    end
                    ixobs=ixobs+i2;
                end
                
                
            end % end i
        else
            % gaussian random generation
            
            for i=1:ntobs
                % Note:le bruit est dans un intervalle de 2*sigma autour de la valeur calculée
                repet = normrnd(0, (ecart/2), nrepet, 1) ;
                Xobs(ixobs: ixobs+nrepet-1, 9) = logy(i)+repet;
                if nobiais==0
                    % biais
                    signe= randi(2, 1, 1); % integer =1 or =2
                    if signe==2
                        signe=-1;
                    end
                    Xobs(ixobs: ixobs+nrepet-1, 9) = Xobs(ixobs: ixobs+nrepet-1, 9)+(signe.*becart);
                end
                ixobs=ixobs+nrepet;
                
            end % fin for i
            
        end % fin gaussien
    end % fin variance cte
    
    %% After replications generation, it is possible that there are responses < 1, i.e for which log is <0
    Xobs(Xobs(:,9)<0, 9)=0;
    
    
    %% Deduce columns H (concentration) and G (nbe de colonies)
    reponse = 10.^Xobs(:,9); % inverse de log10
    Xobs(:,8) = reponse;
    
    Xobs(:,7) = ceil(reponse .* Xobs(:,3) .* Xobs(:,5) .* Xobs(:,6));% colonne G= H*C*E*F
    
    badG = badG+1;
    % Check G is valid
    if (any(Xobs(:,7) < minG) || any(Xobs(:,7) > maxG)) &&  ( nrepet==0 || badG >5)
        errordlg(['Generation of a valid G-column in the data file is not possible', ...
            ' after ', num2str(badG), ' attempts: try again with another seed or change some input values (see User Guide).']);
        set(obj,'interruptible','on','userdata',0,'string','GO')
        Idle(1)
        return
        
    end
    
    
end % end while


%% Store results in data so we will be able to write them in a file, if user asks to Save them
data.releveobs=Xobs;
clear Xobs colI;


%% Plot
% To number the panels of hpanel_work
uicontrol('parent',data.hpanel_work,...
    'units','normalized',...
    'foregroundcolor','k',...
    'backgroundcolor',[1 1 1],...
    'position',[0 0  1 .02],...
    'tag','com_tab_tag',...
    'style','text');
% modify  backgroundcolor of hpanel_work
set(data.hpanel_work,'backgroundcolor',[1 1 1])

%  plot
plot_ysimulS( data, tobs, logy, data.releveobs, nrepet, labelord);



%% Reset the GO button
set(obj,'interruptible','on','userdata',0,'backgroundcolor','r','string','GO')



drawnow
Idle(1)
handles=guihandles(1);
ndata=catstruct(data,handles);
guidata(gcf,ndata)
end % end SIMULATION

%% ======================================================
function dynamique_simul(~, ~)
%dynamique_simul Choice of the model 
% Here, we simulate a dataset: all the parameters are fixed
% INPUT
% Ignored
%% ======================================================
global input_error;
data=guidata(gcf);
Basemodeles=init_Basemodeles();
data.Basemodeles=Basemodeles;
% oter les modeles Ln
str={};
for i=1:length(data.Basemodeles.nom)
    if isempty(strfind(data.Basemodeles.nom{i}, 'Ln')) && ...
            strcmpi(data.Basemodeles.nom{i}, 'LogLinear')==0
        str{end+1}= data.Basemodeles.nom{i};
    end
end


[p,v] = listdlg('PromptString','Select model:',...
    'ListSize',[200 350],...
    'SelectionMode','single',...
    'ListString',str);
s=find(strcmpi(data.Basemodeles.nom, str(p)));
guidata(1,data);
if v
    % cancel the previous errors
    input_error=[];
    % Fix all the parameters
    data.Basemodeles.nomparamS{s} = [data.Basemodeles.nomparamP{s}, data.Basemodeles.nomparamS{s}];
    data.Basemodeles.nomparamP{s}={''};
    guidata(1,data);
    % set the default time unit in the same unit than the parameters
    % if no data have been read or typed (tobs empty, => choice is equidistant times) and
    % the default choice has not been changed
    tobs=get(data.tobs_tag,'value');
    if isempty(tobs) && data.uniteT==2
        data= recup_temps(data, data.Basemodeles.nomparamS{s}, data.Basemodeles.type);
    end
    
        
    trace_modele(s, 1); % display the model, with the default values and parameters fixed
    
    
    delete(get(data.dynamique_tag,'children'))
end
 % Buttons relative to the model parameters
 set(data.resetmod_tag, 'visible','on')
    set(data.resetdparam_tag, 'visible','on')
end % end dynamique_simul
%% ======================================================
function  plot_1y(parent, temps, logy, Xobs, nrepet, modelepop, labelord)
%plot_1y heart of the plot operation
%% ======================================================

subplot(1,1,1, 'parent',parent);
plot(temps, logy);
hold on;
a=sort(repmat(temps,1, nrepet));
 plot(a, Xobs(:,9), 'x');


%title(['DYNAMIQUE SIMULÉE. Modele ', modelepop]);
 title(['SIMULATION OF AN OBSERVATION DATASET. Model: ', modelepop]);

%legend('dynamique simulée', 'données simulées', 0, 'location','Best');
 legend('simulated dynamics', 'simulated data', 0, 'location','Best');
ylabel(labelord);

data=guidata(1);
unite=data.uniteT_libelle;
xlabel(['time (' unite ')']);

end % end plot_1y

%% ======================================================
function  plot_ysimulS( data, temps, logy, Xobs, nrepet, labelord)
%plot_ysimulS Plot of the simulated Y
%% ======================================================
% Note: Mettre dans une structure 'filtrexplot' situé dans 'base'
% ce qui est nécessaire aux graphiques de façon à pouvoir
% les retracer si clic gauche dessus
sauve_hp('filtrexplot', 1,  'temps',  temps, ...
    'logy', logy, 'Xobs', Xobs, ...
    'nrepet', nrepet, 'modelepop', data.modelepop, ...
    'labelord', labelord);


tag='panel_tag';
hp2=uipanel('parent',data.hpanel_work,...
    'tag',tag,...
    'BorderType', 'none', ...
    'BackgroundColor',[1 1 1],...
    'Position',[0 .02 1 0.98]);
plot_1y(hp2, temps, logy, Xobs, nrepet, data.modelepop, labelord)
set(gca,'buttondownfcn',@dessin_simul);
end % end plot_ysimulS
%% ======================================================
function dessin_simul(obj, evt, numfig)
%dessin_simul Plot in a graphical Matlab window of the simulated Y
%% ======================================================
donnees = evalin('base', 'filtrexplot');
hfig=figure('Name', 'SIMULATED DYNAMICS');
plot_1y(hfig, donnees.temps, donnees.logy, donnees.Xobs, donnees.nrepet, donnees.modelepop, ...
    donnees.labelord)
end % end dessin_simul

%% ======================================================
function saveSimul(~,~)
%saveSimul Save the simulated dataset
%% ======================================================

data=guidata(1);
if ~isfield(data, 'modelepop') || ~isfield(data, 'releveobs') || ...
        isempty(data.modelepop) || isempty(data.releveobs)
    errordlg('No execution has been done: it is not possible to save anything');
    return
end

tronc = [getenv('DATADIR') '/SIMULATED_DATA/sd' ...
	       datestr(now, 'yyyymmdd'), ...
	       data.shortmodel ];
[filename, dirname] = uiputfile(  [tronc '.xls'], ...
    'Simulated data filename; ONLY CSV FILES ON LINUX');
[~, ~, extension]= fileparts(filename);

chemin=[dirname filesep filename];
ecrit=0; % indique si on a ecrit ou non
labelunite= ['time (' data.uniteT_libelle ')'] ;

if ~isempty(strfind(extension, '.xls'))
    try
        A={ labelunite, data.releveobs};
        xlswrite(chemin, A); % on ne peut pas ecrire des cells et cree format CSV sur linux
        ecrit=1;
    catch
        % xlswrite echoue: on ecrit en csv
        extension = '.csv';        
        filename=regexprep(filename, 'xls.*', 'csv');
        chemin=[dirname filesep filename];
        hm=msgbox(['Cannot write in ' extension ' format: ',...
        filename ' written instead']);
        waitfor(hm);
        if exist(chemin, 'file')
            button= questdlg(['File ' filename ' exists: replace it?']);
            if ~strcmp(button, 'Yes')
                return
            end
        end
            
    end % fin try
end

if strcmp(extension, '.csv')
    fid=fopen(chemin, 'w');
    %  Fix the time unit 
   fprintf(fid, '%s \n', labelunite);
    % Write the values
    [nrows,ncols]= size(data.releveobs);
    for i=1:nrows
        for j=1:(ncols-1)
            fprintf(fid, '%g, ', data.releveobs(i,j));
        end
        fprintf(fid, '%g\n', data.releveobs(i,ncols));
    end
    fclose(fid);
    ecrit=1;
end

if ecrit==0
    hm=msgbox(['Cannot write in ' extension ' format: no file written']);
    waitfor(hm);
end

%% NOTE
% aussi possible: csvwrite( [dirname filename], data.releveobs);
% NOTE xlswrite('SIMULDATA.xls', data.releveobs); marche pas si on a pas le
%Excel de microsoft



end % end saveSimul
%% ======================================================
function ecr_data()
% ecr_data Write data characteristics when equidistant
data= guidata(1);

% Write the data characteristics
[tobs, deltaT] = genere_tpsobs();
if isempty(tobs)
    return %error
end

descr='Equidistant times';
if ~isnan(deltaT)
    descr=[descr '; Time step: ', num2str(deltaT)];
end
set(data.fichier_descr_tag, 'String', descr);

end % end ecr_data


%% ======================================================
function Fstruct=init_Simul()
%init_Simul Initialize the simulation parameters by default values
%% ======================================================
Simul.nomparamD = {'graineAleaS', 'bruitS', 'nbtimes', 'obSmax', 'repetS', 'masseS'};
% les bornes de validité:
Simul.DF= {{'10' '99999', 'CLOCK'}, {'0', '500'}, {'3', '1000'}, {'.01', '525600'}, {'1', '100'}, {'1', '100'}};
% les valeurs par défaut:
Simul.valparamD = { 'CLOCK','10', '-', '-', '3', '10'};
% le  mode de tirage par défaut
Simul.modeD = { 'uniformeS', 'varcte'};
% le biais et mode de tirage non par défaut
Simul.modeND = { 'gaussienS', 'novarcte'};
% les valeurs numériques
Simul.valnom={'refvalue', 'cpuisvalue', 'deltaref', 'biaisvalue'};
Simul.chaines={'REFERENCE VALUE', 'POWER COEFFICIENT', ...
'%REFERENCE BIAS', '%BIAS'};
Simul.valD={'5', '1', '0', '0'};
Fstruct=Simul;
end
%% ======================================================
function Xt=initialisation_particules_simul(data)
%initialisation_particules_simul Create the state vector (vecteur d'etat)
% OUTPUT
% state vector:
% Xt=[parametres;eventuels coefficients de variation;effectif]
%% ======================================================
len=length(data.nomparamS);
n=1; % fixed parameters: no random drawn between parameters bounds => no need of particles number
Xt=zeros(len,n);
for i=1:len
    var=data.nomparamS{i};
    Xt(i,:)=eval(['data.',var]);
end

if isfield(data, 'N0')
    Xt(end+1,:)=data.N0;
end
if isfield(data, 'LnN0')
    Xt(end+1,:)=data.LnN0;
end
if isfield(data, 'N0W')
    Xt(end+1,:)=data.N0W;
end
if isfield(data, 'log10N0')
    Xt(end+1,:)=data.log10N0;
end

end %end initialisation_particules_simul
%% ======================================================
function [B C D E F]=generBCDEF(data, ntobs)
% generBCDEF Generate columns B,C,D,E,F
%% ======================================================
B = str2double(get(data.masseS_tag,'string')); % la masse (g): fixed by the user
C =0.1; %  initial dilution factor: we fix it
%D: nb dilutions en tubes: we generate it by uniform random numbers between  0 and 3
D=randi(4, ntobs, 1) -1;
%E: facteur de dilution en tubes total:
% nbplages ranges of same length, constant value on each of them
nbplages = 4;
lgplage = round(ntobs/nbplages);
E=zeros(ntobs,1);
valE = [1, 1.0e-3, 1.0e-4, 1.0e-5 ];

for i=1: (nbplages-1)
    E(lgplage*(i-1)+1: i*lgplage, 1) = valE(i);
end
% Last range:
E(lgplage*(nbplages-1)+1:end,1) =valE(nbplages);
%F volume: we generate it by uniform random numbers between 0.5 and 1 at the beginning then fix to 0.05
F=zeros(ntobs,1);
lgplage = round(ntobs/10);
F(1:lgplage,1) = randi(2,1,1)/2;
F(lgplage+1:end,1) = 0.05;
end % end generBCDEF
%% ======================================================
  function rep=control_temps()
% control_temps check maximal time according to the time unit
%% ======================================================
global input_error;
rep=0;
data=guidata(1);
switch data.uniteT
    case 1
        DF={'0.01', '365'};
    case 2
        DF={'0.25', '8760'};
    case 3
        DF={'15', '525600'};
end
user_entry = str2double(get(data.obSmax_tag, 'String'));
if user_entry> str2double(DF{2}) ||  user_entry < str2double(DF{1})
    errordlg(['When the time unit is ',data.uniteT_libelle,', the maximal time should be between ',DF{1},' and ',DF{2}] ,'Bad Input','modal')
    input_error.obSmax_tag=1;
    rep=1;
end
  end % fin control_temps
%% ======================================================

function control_saisie_data(obj, event)
% control_saisie_data check input and reset data characteristics
%% ======================================================
global input_error;
letag = get(obj, 'tag');

control_saisie(obj, event);
% Il y a une erreur sur le tag courant
if ~isempty(input_error) && isfield(input_error, letag)
    return
end

% Si le tag concerne qqche qui modifie les caracteristiques
% des donnees, les modifier
if strcmp(letag, 'nbtimes_tag') || ...
    strcmp(letag, 'obSmax_tag') || ...
    strcmp(letag, 'repetS_tag')
    ecr_data();
end



end %end control_saisie_data
%% ======================================================
function sauver_sim(obj,event)
%sauver_sim Save data simulation task
%% ======================================================
data=guidata(1);
if ~isfield(data, 'shortmodel')
    errordlg('No model is selected: it is not possible to save anything');
end
%% stockage du maximal time
data.obSmax = get(data.obSmax_tag, 'string');
%% stockage du number of times
data.nbtimes=get(data.nbtimes_tag, 'string');

%% stockage de la valeur de la graine aleatoire
data.graineAlea_in=get(data.graineAleaS_tag,'string');


%% Sauvegarde du mode de entree des temps, de la unité de temps
types= {{'KEYBOARD', 'FILE', 'EQUIDISTANT'}, ...
    {'day', 'hour', 'mn'}, ...
    {'uniformeS_tag', 'gaussienS_tag', 'varcte_tag', 'novarcte_tag'}};

for ii=1:length(types)
    untypes=types{ii};
    for i=1:length(untypes)
        val=get(data.(untypes{i}), 'value');
        if val==1
            nom=[untypes{i}, '_in'];
            data.(nom)=1;
        end
    end
end

%% Sauvegarde des options string
for i=1:length(data.Simul.valnom)
    letag= [data.Simul.valnom{i}, '_tag' ];
    data.([data.Simul.valnom{i}, '_in']) = get(data.(letag), 'String');
end


%% sauvegarde du modele
[data, ~]=sauver_mod(data, '');


 uisave('data', [getenv('PROJECTDIR') '/DATA_SIMULATION/ds' ...
                datestr(now, 'yyyymmdd') data.shortmodel   '.mat']);
            
end



%% ======================================================

function  restore_sim(obj,event)
%restore_sim Restaure un projet de simulation de données
% Le nom du fichier  à restaurer est demandé à l'utilisateur
%% ======================================================

[fileName, pathName] = uigetfile( ...
    [getenv('PROJECTDIR') '/DATA_SIMULATION/*.mat'],  'Select a Matlab file');
if isequal(fileName,0) || isequal(pathName,0)
    return;
end
chemin=fullfile(pathName, fileName);
load(chemin);
%% Maintenant, la structure 'data' est chargée:
% on la garde dans datalu, et on charge dans 'data' ce qui est affiché
% i.e le cadre (handle) par défaut.
% On va le modifier en y mettant les valeurs lues
datalu=data;
data=guidata(1);

%% Nettoyer les eventuels résultats précédents
delete(get(data.hpanel_work,'children'))
%% Afficher le nom du fichier restauré
set(data.fichier_chemin_tag, 'String', ...
    ['RESTORED FILENAME : ', fileName], 'Visible', 'on');

%% Restauration du maximal time
set(data.obSmax_tag, 'string', datalu.obSmax );
set(data.obSmaxtxt_tag, 'String', ...
    ['MAXIMAL TIME (' datalu.uniteT_libelle ' )']);

%% Restauration du number of times
set(data.nbtimes_tag, 'string', datalu.nbtimes);

set(data.uniteT_tag, 'value',datalu.uniteT);
if ~isempty(datalu.tobs)
    % des données ont été générées
    set(data.tobs_tag,'value',datalu.tobs);
end

%% Restauration du mode de entree des temps
types= {{'KEYBOARD', 'FILE', 'EQUIDISTANT'}, ...
    {'day', 'hour', 'mn'}, ...
    {'uniformeS_tag', 'gaussienS_tag', 'varcte_tag', 'novarcte_tag'}};


for ii=1:length(types)
    untypes=types{ii};
    for i=1:length(untypes)
        nom=[untypes{i}, '_in'];
        if isfield(datalu, nom)
            set(data.(untypes{i}), 'value', 1);
        else
            set(data.(untypes{i}), 'value',0);
        end
    end
end
% Maj des boutons quand l'utilisateur choisit la variance cte ou non cte
if get(data.varcte_tag, 'value') == 1
    lechoix='varcte_tag';
else
    lechoix='novarcte_tag';
end
lobj= uicontrol('Visible', 'off', ...
    'tag', lechoix);
maj_refvalue(lobj,event);


%% Restauration  des options string
for i=1:length(datalu.Simul.valnom)
    letag= [datalu.Simul.valnom{i}, '_tag' ];
    set(data.(letag), 'String',  datalu.([datalu.Simul.valnom{i}, '_in']));
end

%% Restauration  de la graine
set(data.graineAleaS_tag,'string', datalu.graineAlea_in);


%% Restauration du cadre qui concerne le modèle
% D'abord, tracer le cadre avec les val par defaut:
% Le 3ieme argu signifie qu'on est dans le cas de la simulation de données
restore_dynamique(data,datalu, 1);
data=guidata(1);
% Modification des val par defaut par celles lues sur le fichier:
s=find(strcmpi(datalu.Basemodeles.nom,datalu.modelepop));

%% Restauration de la valeur des paramètres fixes:
nomparamfixes=datalu.Basemodeles.nomparamS{s};
if ~isempty(nomparamfixes)
    for i=1:length(nomparamfixes)
        var=nomparamfixes{i};
        tag=[nomparamfixes{i},'_tag'];
        lin=[var,'_in'] ;
        set(data.(tag),'string',eval(['datalu.',lin]),'backgroundcolor','w');
        if any(strcmpi(nomparamfixes{i}, datalu.CVs.nomparamS))
            % le parametre est un CV
            set(data.([nomparamfixes{i},'_fixtag']), 'string',eval(['datalu.',lin]));
        end
    end
end % length(nomparamfixes)>0

%% Lancer l'exécution

lobj=uicontrol( ...
    'interruptible','on',...
    'BusyAction','cancel',...
    'tag','simulation_tag',...
    'Style','pushbutton',...
    'String','GO',...
    'userdata',0,...
    'Visible', 'off');

SIMULATION(lobj, event);

end

