diff --git a/setupgrind.m b/setupgrind.m
index 0bcebe12f6e006cbcf675347d4b461b50702ccf9..44b24190ec48b111d432223a568b72616ec49a73 100644
--- a/setupgrind.m
+++ b/setupgrind.m
@@ -23,9 +23,9 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setupgrind')">commands setupgrind</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
-function setupgrind(option)
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
+function res=setupgrind(option)
     %urls for downloading
     if ~isoctave && verLessThan('matlab', '7.6')
         error('grind:setup', 'MATLAB version R2008a or newer is required for GRIND');
@@ -34,16 +34,23 @@ function setupgrind(option)
         checkversions(true);
         return;
     end
-    urls = {'http://content.alterra.wur.nl/webdocs/internet/aew/downloads/', 'http://www.sparcs-center.org/uploads/files/'};
-    url = urls{1};
-    for i = 1:length(urls)
-        %find first valid url
-        [dummy, status] = urlread(sprintf('%s%s', urls{i}, 'grindversion.txt')); %#ok<ASGLU>
-        if status == 1
-            url = urls{i};
-            break;
-        end
+    %this url should redirect to grindversion.txt and return the exact urls
+    %for grind.zip etc
+    urls = read_grindversion('https://sparcs-center.org/grindfiles/grindversion.txt');
+    if nargin > 0 && strcmp(option, '-version')
+        res=urls;
+        return;
     end
+%     for i = 1:length(urls)
+%         %find first valid url
+%         try
+%         dummy = webread(sprintf('%s%s', urls{i}, 'grindversion.txt')); %#ok<ASGLU>
+%         catch err
+%             if strcmp(err.identifier,'MATLAB:webservices:HTTP404StatusCodeError')
+%             url = urls{i};
+%             end
+%         end
+%     end
     doanyway = 0;
     uninstall = 0;
     addstartup = 0;
@@ -53,19 +60,19 @@ function setupgrind(option)
             doanyway = 1;
         end
         if strncmpi(option, '-up', 3)
-            updategrindfromweb(url);
+            updategrindfromweb(urls);
             if isempty(which('grind_coco'))
                 addpath(fullfile(grindpath, 'sys2'));
             end
             %update coco from the grind website (only if coco is available)
-            if ~isempty(grind_coco.findupdate(false, url))
-                grind_coco.findupdate(true, url);
+            if ~isempty(grind_coco.findupdate(false, urls))
+                grind_coco.findupdate(true, urls);
             end
-            if ~isempty(grind_matcont.findupdate(false, url, true))
-                grind_matcont.findupdate(true, url, true);
+            if ~isempty(grind_matcont.findupdate(false, urls, true))
+                grind_matcont.findupdate(true, urls, true);
             end
-            if ~isempty(grind_matcont.findupdate(false, url, false))
-                grind_matcont.findupdate(true, url, false);
+            if ~isempty(grind_matcont.findupdate(false, urls, false))
+                grind_matcont.findupdate(true, urls, false);
             end
         elseif strncmpi(option, '-u', 2)
             uninstall = 1;
@@ -83,7 +90,7 @@ function setupgrind(option)
             fprintf('Grind uninstalled from %s (no files removed)\n', thegrindpath);
         else
             checkversions(false); %if version < 7.12 [~, ] is not supported (replaced with [DUMM]
-            if exist_newversion(url) < 1
+            if exist_newversion(urls) < 1
                 warning('GRIND:setupgrind:newerversion', 'There is a newer version available, use <a href="matlab: updategrind">updategrind</a> to update.');
             end
             fprintf('Grind was already installed in %s\n', thegrindpath);
@@ -100,7 +107,7 @@ function setupgrind(option)
         warning on MATLAB:MKDIR:DirectoryExists
         cd(folder);
         fprintf('Downloading GRIND...\n')
-        unzip([url 'grind.zip']);
+        unzip(urls.grind_url);
         disp('Successfully downloaded');
         cd grind
         setupgrind
@@ -225,12 +232,12 @@ end
 
 
 
-function updategrindfromweb(url)
+function updategrindfromweb(urls)
  
     % if ~exist('urlread','file') %exists in R2008
     %    error('GRIND:updategrind:MATLABversion','This function works only for newer versions of MATLAB');
     % end
-    [nonewer, web, current] = exist_newversion(url);
+    [nonewer, web, current] = exist_newversion(urls);
     if isempty(web)
         error('GRIND:updategrind:noconnection', 'Cannot download GRIND, is internet connected?')
     end
@@ -266,7 +273,7 @@ function updategrindfromweb(url)
         cd ..
         cd ..
         fprintf('Downloading new version (%s)...\n', web.date)
-        unzip([url 'grind.zip']);
+        unzip(urls.grind_url);
         cd(gp)
         cd('csolver')
         if exist('compile1.bat', 'file') == 2
@@ -281,22 +288,22 @@ function updategrindfromweb(url)
     fprintf('GRIND version %s\nRelease date: %s\n', web.version, web.date);
 end
 
-function [existnew, web, current] = exist_newversion(url)
+function [existnew, web, current] = exist_newversion(urls)
     existnew = 1;
     current = [];
     web = [];
-    try
-        [s, status] = urlread([url 'grindversion.txt']);
-        if status == 1
-            h = str2cell(s);
-        else
-            return;
-        end
-    catch
-        return;
-    end
-    web.version = h{1};
-    web.date = h{2};
+%     try
+%         [s, status] = urlread([url 'grindversion.txt']);
+%         if status == 1
+%             h = str2cell(s);
+%         else
+%             return;
+%         end
+%     catch
+%         return;
+%     end
+    web.version = urls.grind_version;
+    web.date = urls.grind_build;
     fid = fopen('use.m', 'r');
     while ~feof(fid)
         line = fgetl(fid);
@@ -310,7 +317,8 @@ function [existnew, web, current] = exist_newversion(url)
     end
     fclose(fid);
     try
-        existnew = datenum(web.date) - datenum(current.date) < 1E-4;
+        f='dd-mm-yyyy HH:MM:SS';
+        existnew = datenum(web.date,f) - datenum(current.date,f) < 1E-4;
     catch
         return
     end
@@ -505,4 +513,47 @@ function currdir = getgrinddir_dlg(currdir1)
 end
 
 
+function str = read_grindversion(url_or_file)
+    %reads the grind version and file locations from an url or filename
+    if nargin == 0
+        url_or_file = 'http://sparcs-center.org/grindfiles/grindversion.txt';
+    end
+    if strncmp(url_or_file, 'https:', 6) || strncmp(url_or_file, 'http:', 5)
+        s = webread(url_or_file, weboptions('contenttype', 'text'));
+        
+    else
+        s = evalc(['type ' url_or_file]);
+    end
+    s = regexp(s, '[^=\n]*', 'match');
+    str = struct(s{:});
+    f = fieldnames(str);
+    for i = 1:length(f)
+        if isempty(strfind(f{i}, '_url'))
+            % [~, name, ext] = fileparts(str.(f{i}));
+            % str.([f{i}(1:end - 4) '_file']) = [name ext];
+            %for some reason matlab removes \\ while reading url
+            str.(f{i}) = regexprep(str.(f{i}), 'http:[\/]([^\/].*)', 'http://$1');
+            str.(f{i}) = regexprep(str.(f{i}), 'https:[\/]([^\/].*)', 'https://$1');
+        end
+    end
+    str.current_grind_version = '';
+    str.current_grind_build = '';
+
+    if exist('use', 'file')
+        fid = fopen('use.m', 'r');
+        while ~feof(fid)
+            line = fgetl(fid);
+            f = strfind(line, 'Revision:');
+            if ~isempty(f)
+                f1 = strfind(line, '$');
+                str.current_grind_version = strtrim(line(f + 9:f1(1) - 1));
+                f = strfind(line, 'Date:');
+                str.current_grind_build = strtrim(line(f + 5:f1(end) - 1));
+            end
+        end
+        fclose(fid);
+    end
+end
+
+
 
diff --git a/sys/addmode.m b/sys/addmode.m
index 2311b8b5fcf6c8fb0607651a503478e021cf0b0f..dda0319efdb3b9028255a2a1d1ccd7329637446b 100644
--- a/sys/addmode.m
+++ b/sys/addmode.m
@@ -22,8 +22,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('addmode')">commands addmode</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function addmode(varargin)
     %(state, opt)
     global g_grind g_Y; %#ok<GVMIS>
diff --git a/sys/adjr2.m b/sys/adjr2.m
index 9a3806fe79fe6b78a7501f4ac4a5247aedee2edb..f85297d5c3ff690ecc4c3c5bb39a0466a78e9bf3 100644
--- a/sys/adjr2.m
+++ b/sys/adjr2.m
@@ -12,8 +12,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('adjr2')">commands adjr2</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function meanAdjR2 = adjr2(npars)
     global g_data t g_Y g_t; %#ok<GVMIS>
     if strncmp(npars, '??', 2)
diff --git a/sys/analunits.m b/sys/analunits.m
index c6eb5100d30bce04ce386154c9fc2d8649a1917e..ffe0ae5762073689f078be8b826f1e29e82954cc 100644
--- a/sys/analunits.m
+++ b/sys/analunits.m
@@ -49,8 +49,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('analunits')">commands analunits</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function [un, vars] = analunits(varargin)
     %(mod, varlist, unitlist)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/arrows.m b/sys/arrows.m
index 6debba05e6a34c398499e664a3be80da53bf3351..706eed856265ed8484930b0a7908084fba198f86 100644
--- a/sys/arrows.m
+++ b/sys/arrows.m
@@ -19,8 +19,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('arrows')">commands arrows</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function arrows(hax, narrow, arg2)
     nearest = [];
     if nargin == 1 && ischar(hax) && strncmp(hax, '??', 2)
diff --git a/sys/attrbasin.m b/sys/attrbasin.m
index 25311f3c6bbd8ed9a250000fa37a8b4b0bfc213b..123b6c4e3e08e621c4c9c98073b934def24b8ff6 100644
--- a/sys/attrbasin.m
+++ b/sys/attrbasin.m
@@ -20,8 +20,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('attrbasin')">commands attrbasin</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function EndsVar = attrbasin(varargin)
     %(n, var2, EndsX)
     global g_Y t g_grind g_t; %#ok<GVMIS>
diff --git a/sys/back_euler.m b/sys/back_euler.m
index 3c823283f5a76e472a810bd6286e44f44cfecd99..f24422717a16204c9a055df6de9f6ed900207902 100644
--- a/sys/back_euler.m
+++ b/sys/back_euler.m
@@ -38,7 +38,7 @@ function [tout, yout] = back_euler(odefunct, tspan, y0, options)
         Jfun = options.Jacobian;
     end
     if nargin >= 4
-        nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast'));
+        nonNegative = ~isempty(odeget(options, 'NonNegative', []));
         %if nonNegative
         %    warning('GRIND:back_euler:NonNegativeIgnored', 'BACK_EULER does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.');
         %end
diff --git a/sys/backw.m b/sys/backw.m
index 25ce063c4500648cf3738511c32ea2b43d4d8e6b..e636ed620906de45d8d90b3577e6ad202d1e0085 100644
--- a/sys/backw.m
+++ b/sys/backw.m
@@ -26,8 +26,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('backw')">commands backw</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function backw(varargin)
     %(ndays,dotrunc)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/boxcarinflow.m b/sys/boxcarinflow.m
index ab1114e66cb04ef65aee844a38bb2dea4201c3bd..665657b66b35ab1f8c127f2f0aae138291489742 100644
--- a/sys/boxcarinflow.m
+++ b/sys/boxcarinflow.m
@@ -11,8 +11,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('boxcarinflow')">commands boxcarinflow</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function res = boxcarinflow(A, inflow)
     res = zeros(size(A));
     if numel(inflow) > 1
diff --git a/sys/boxcartrain.m b/sys/boxcartrain.m
index 3bc45ad8a967236954cdb53adb8827489affe3a1..8067b77c90a77d7bc89cd69000e3ed3924be8f0e 100644
--- a/sys/boxcartrain.m
+++ b/sys/boxcartrain.m
@@ -21,8 +21,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('boxcartrain')">commands boxcartrain</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function [res, Anew] = boxcartrain(boxnr, A, devrate, cv_devrate)
     global g_grind; %#ok<GVMIS>
     if nargin < 4
diff --git a/sys/combfig.m b/sys/combfig.m
index 406337b3091646bb1bf13644a980cfdbd741930b..50cf2644f7b16ffdc12ff3b6b60051b1641b22c4 100644
--- a/sys/combfig.m
+++ b/sys/combfig.m
@@ -36,8 +36,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('combfig')">commands combfig</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function ndx = combfig(varargin)
     %(fignrs, Cells, starti)
     if ~exist('i_figno', 'file')
diff --git a/sys/commands.m b/sys/commands.m
index 4563b4190eb076cfbcb1c5b3b36036f708146769..956ce37c2730bcdd0043ce7688bda178d80e428d 100644
--- a/sys/commands.m
+++ b/sys/commands.m
@@ -154,7 +154,7 @@ function commands(varargin)
                             k1 = k1 + 1;
                             line = fgets(fid);
                         end
-                        
+ 
                         fid3 = fopen(fname, 'w');
                         fprintf(fid3, '%s', lines{:});
                         fwrite(fid3, sprintf('%%\n%%   Reference page in Help browser:\n%%      <a href="matlab:commands(''%s'')">commands %s</a>\n', aname, aname));
@@ -219,20 +219,24 @@ function commands(varargin)
         cd(ddir);
         cd ..
         cd setup
-        try
-            cocoversion = dir('\\SCOMP5341\Webdocs$\Internet\aew\Downloads\coco*.zip');
-            if length(cocoversion) ~= 1
-                error('grind:commands', 'There must be one coco version on the website');
-            end
-            fid = fopen('cocoversion.txt', 'w');
-            fprintf(fid, '%s\n', cocoversion.name);
-            fclose(fid);
-        catch
-            warning('grind:commands', 'cannot open webdocs');
+        %         try
+        %             cocoversion = dir('\\SCOMP5341\Webdocs$\Internet\aew\Downloads\coco*.zip');
+        %             if length(cocoversion) ~= 1
+        %                 error('grind:commands', 'There must be one coco version on the website');
+        %             end
+        %             fid = fopen('cocoversion.txt', 'w');
+        %             fprintf(fid, '%s\n', cocoversion.name);
+        %             fclose(fid);
+        %         catch
+        %             warning('grind:commands', 'cannot open webdocs');
+        %         end
+        if ~exist('i_use', 'file')
+            addpath([grindpath filesep 'sys2']);
         end
-        fid = fopen('grindversion.txt', 'w');
-        fprintf(fid, '%s\n%s\n', grindver, updatedat);
-        fclose(fid);
+        versions = read_grindversion;
+        versions.grind_version = versions.current_grind_version;
+        versions.grind_build = versions.current_grind_build;
+        write_grindversion(versions, 'grindversion.txt')
         s = grindpath;
         f = strfind(s, filesep);
         s = s(1:f(end) - 1);
@@ -431,3 +435,14 @@ function commands(varargin)
     end
 end
 
+function write_grindversion(str, filename)
+    f = fieldnames(str);
+    fid = fopen(filename, 'w');
+    for i = 1:length(f)
+        if ~strcontains(f{i}, 'current_')
+            fprintf(fid, '%s=%s\n', f{i}, str.(f{i}));
+        end
+    end
+    fclose(fid);
+end
+
diff --git a/sys/connectmat.m b/sys/connectmat.m
index 23c4e3ce1b8028fb56f13c55fad29e4015651f8a..e6bf9432ba16e36a0f4fc5ccc9717d0ebedd1117 100644
--- a/sys/connectmat.m
+++ b/sys/connectmat.m
@@ -18,8 +18,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('connectmat')">commands connectmat</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function [M] = connectmat(varargin)
     %(s1,s2,isround)
     fieldnams = {'size', 'i>1', 'size of the matrix.', []; ...
diff --git a/sys/contbif.m b/sys/contbif.m
index f1e12821a06f9031d2ead1a562abaafb7213c3aa..e545c7e2619264201b4495f8b0d2d995a9ff7de4 100644
--- a/sys/contbif.m
+++ b/sys/contbif.m
@@ -11,8 +11,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('contbif')">commands contbif</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function contbif(varargin)
     if nargin > 0
         conteq('-contbif', varargin{:});
diff --git a/sys/contents.m b/sys/contents.m
index c30b77803b926d82ef63319d7a16e4941d1c8401..f51b3ae5f79f3bd3b07a60b80ae87488060af554 100644
--- a/sys/contents.m
+++ b/sys/contents.m
@@ -134,8 +134,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('contents')">commands contents</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 %start
 disp('')
 
diff --git a/sys/conteq.m b/sys/conteq.m
index 2e279591d0677a7edf085d62c16a82d5460d12fb..34671361a0bc4d5c3bdc038bacff84ab2570e319 100644
--- a/sys/conteq.m
+++ b/sys/conteq.m
@@ -1,6 +1,6 @@
 %CONTEQ   Continue an equilibrium or bifurcation with COCO or MatCont
 %   This command can do an 1D or 2D bifurcation analysis using the package
-%   <a href="matlab:help coco">COCO (Continuation Core and Toolboxes)</a> or <a href="matlab:commands matcont">MatCont</a>.
+%   <a href="matlab:commands coco">COCO (Continuation Core and Toolboxes)</a> or <a href="matlab:commands matcont">MatCont</a>.
 %   Select an equilibrium with <a href="matlab:help findeq">findeq</a>, then you can continue the stable or 
 %   unstable equilibrium. It can (currently) detect a fold (=saddle-node), transcritical and a Hopf bifurcation. 
 %   A plot of the equilibrium and the eigenvalues is made.
@@ -33,7 +33,7 @@
 %     'stateranges' [number] - min/max value for each of the state variables, or one row if all are the same (default: [Nan NaN])
 %     'symbolic' [logical] - if available use the symbolic toolbox for Jacobians (default 1)
 %    
-%     <a href="matlab:help Coco">Specific options for COCO</a>
+%     <a href="matlab:commands Coco">Specific options for COCO</a>
 %     <a href="matlab:commands matcont">Specific options for MatCont</a> for differential equations
 %     <a href="matlab:commands matcontm">Specific options for MatContM</a> (for difference equations)
 %       
@@ -69,32 +69,45 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('conteq')">commands conteq</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function conteq(varargin)
+    % Set up global variables for continuation analysis
     evalin('base', 'global g_cont;');
     global g_grind g_cont; %#ok<GVMIS>
+    
+    % Check for a correct model
     if ~(nargin == 1 && strncmp(varargin{1}, '??', 2))
         i_parcheck;
     end
+    
+    % Initialize g_grind.cont fields based on the type of continuation engine
     if isa(g_cont, 'grind_matcont') && ~isfield(g_grind.cont, 'matcont')
         g_grind.cont.matcont = g_cont;
         g_grind.cont.engine = g_cont.settings.derived.engine;
     end
+    
     if isa(g_cont, 'grind_coco') && ~isfield(g_grind.cont, 'coco')
         g_grind.cont.coco = g_cont;
         g_grind.cont.engine = 'coco';
     end
+    
+    % Initialize a flag for continuation bifurcation analysis
     docontbif = false;
+    
+    % Select output plots
     if nargin > 0 && strncmp(varargin{1}, '-o', 2)
         if nargin == 1
             i_paranaloutdlg('Edit Plots for conteq');
             conteq;
         else
+            % Call paranal function with additional input arguments
             paranal(varargin{:});
         end
         return;
     end
+    
+    % Clear continuation session if specified
     if nargin > 0 && strncmp(varargin{1}, '-c', 2) && ~strncmp(varargin{1}, '-co', 3)
         if ~isempty(g_cont)
             disp('cleared conteq session')
@@ -103,17 +116,22 @@ function conteq(varargin)
         return;
     end
     
+    % Display about selected plots 
     if nargin > 0 && strncmp(varargin{1}, '-l', 2)
         if ~isfield(g_grind, 'paranal')
             paranal('-default');
         end
         for i = 1:length(g_grind.paranal.plots)
-            fprintf('conteq -out %d [''%s'' ''%s'' ''%s''] [%g %g] [%g %g] [%g %g]\n', i, strtrim(sprintf('%s ', g_grind.paranal.plots{i}.xaxis{:})), ...
-                strtrim(sprintf('%s ', g_grind.paranal.plots{i}.yaxis{:})), strtrim(sprintf('%s ', g_grind.paranal.plots{i}.zaxis{:})), ...
+            fprintf('conteq -out %d [''%s'' ''%s'' ''%s''] [%g %g] [%g %g] [%g %g]\n', i, ...
+                strtrim(sprintf('%s ', g_grind.paranal.plots{i}.xaxis{:})), ...
+                strtrim(sprintf('%s ', g_grind.paranal.plots{i}.yaxis{:})), ...
+                strtrim(sprintf('%s ', g_grind.paranal.plots{i}.zaxis{:})), ...
                 g_grind.paranal.plots{i}.xlim, g_grind.paranal.plots{i}.ylim, g_grind.paranal.plots{i}.zlim);
         end
         return;
     end
+    
+    % Handle specific input arguments related to continuation analysis
     if nargin > 0
         ndx = cellfun(@ischar, varargin);
         f1 = strcmp(varargin(ndx), '-contbif');
@@ -135,6 +153,7 @@ function conteq(varargin)
         varargin = varargin(~(f1 | f2 | f3));
     end
     
+    % Update continuation engine based on user input
     if strncmp(g_grind.cont.engine, 'matcont', 7) && ~isa(g_cont, 'grind_matcont')
         if isfield(g_grind.cont, 'matcont') && ~isempty(g_cont)
             g_cont = g_grind.cont.matcont;
@@ -143,6 +162,7 @@ function conteq(varargin)
             g_grind.cont.matcont = g_cont;
         end
     end
+    
     if strcmp(g_grind.cont.engine, 'coco') && ~isa(g_cont, 'grind_coco')
         if isfield(g_grind.cont, 'coco') && ~isempty(g_cont)
             g_cont = g_grind.cont.coco;
@@ -151,10 +171,14 @@ function conteq(varargin)
             g_grind.cont.coco = g_cont;
         end
     end
+    
+    % Set up additional arguments for the continuation engine
     args = struct('opt', '');
     if ~isempty(varargin)
         args = g_cont.set(varargin{:});
     end
+    
+    % Load a saved session if specified in the arguments
     if isfield(args, 'file')
         g_cont = g_cont.load_session(args.file);
         g_grind.cont.engine = g_cont.settings.derived.engine;
@@ -164,6 +188,8 @@ function conteq(varargin)
             g_grind.cont.matcont = g_cont;
         end
     end
+    
+    % Perform continuation analysis or display GUI based on user input
     if ~(isfield(args, 'par1') || isfield(args, 'par2')) || isempty(g_cont.settings.derived.freepars)
         if docontbif
             g_cont.gui('contbif');
@@ -174,9 +200,12 @@ function conteq(varargin)
         if numel(g_cont.points) <= 1
             g_cont.add_points(findeqs('maxtime', 10));
         end
-        if isempty(g_cont.settings.derived.frompoint) %by default the current initial conditions
+        if isempty(g_cont.settings.derived.frompoint) % by default the current initial conditions
             g_cont.settings.derived.frompoint = g_cont.add_points;
         end
         g_cont.cont;
     end
 end
+
+
+
diff --git a/sys/conteq2d.m b/sys/conteq2d.m
index d07e16571e90886e93469c640882d94db9d332c9..507415f133b994c7e983d036d82102b2fed433c9 100644
--- a/sys/conteq2d.m
+++ b/sys/conteq2d.m
@@ -16,8 +16,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('conteq2d')">commands conteq2d</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function conteq2d(varargin)
     hasengine = false;
     for i = 1:length(varargin)
diff --git a/sys/copyfig.m b/sys/copyfig.m
index f3b6ffcdd14ffc03e457b6324ff50345d96cfd29..edb3f66c2cb422ad21534245ada0041059449b97 100644
--- a/sys/copyfig.m
+++ b/sys/copyfig.m
@@ -15,43 +15,64 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('copyfig')">commands copyfig</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function copyfig(varargin)
-    %(from,to)
+    
+    % Define default values and field names for argument parsing
     fieldnams = {'from', 'h', 'original figure handle.', get(0, 'CurrentFigure'); ...
         'to', 'n', 'number of the new figure', 1000}';
+    
+    % Parse input arguments
     args = i_parseargs(fieldnams, 'if nargs==1,deffields=''to'';else,deffields=''from,to'';end;', '', varargin);
+    
+    % Add sys2 directory to the path if i_checkstr function doesn't exist
     if ~exist('i_checkstr', 'file')
         addpath([grindpath filesep 'sys2']);
     end
+    
+    % Set default 'from' value if not specified
     if ~isfield(args, 'from')
         args.from = get(0, 'CurrentFigure');
     end
+    
+    % Set default 'to' value if not specified
     if ~isfield(args, 'to')
+        % Prompt user for figure numbers if not provided
         prompt = {'Figure number to copy (gcf=current):', 'Copy to:'};
         answer = inputdlg(prompt, 'Copy figure', 1, {'', ''});
+        
+        % Set 'from' and 'to' values based on user input
         if isempty(answer{1})
             answer{1} = 'gcf';
         end
         args = i_parseargs(fieldnams, 'if nargs==1,deffields=''to'';else,deffields=''from,to'';end;', '', answer);
     end
+    
+    % Delete the new figure if it already exists
     if ishandle(args.to)
         delete(args.to);
     end
+    
+    % Create a new figure with the specified number
     h = i_figure(args.to);
+    
+    % Copy axes objects from the original figure to the new figure
     if ishandle(args.from)
-        %   ax=findobj(args.from,'type','axes');
         if strcmp(get(args.from, 'type'), 'axes')
             hax = args.from;
         else
             hax = get(args.from, 'children');
         end
+        
+        % Copy axes objects to the new figure
         copyobj(hax, h);
+        
+        % Adjust the position of the axes in the new figure
         axnew = findobj(h, 'type', 'axes');
         set(axnew, 'position', [0.1300 0.1100 0.7750 0.8150], 'Units', 'normalized');
-        
     else
+        % Display an error if the source figure doesn't exist
         error('GRIND:copyfig:UnknownFig', 'Copyfig: source figure doesn''t exist');
     end
 end
diff --git a/sys/csolver/csolver.layout b/sys/csolver/csolver.layout
index 4ff230b8505e0124868176e25284d0284c75902c..44b745783de56fd051e579949a447b4596eeee81 100644
--- a/sys/csolver/csolver.layout
+++ b/sys/csolver/csolver.layout
@@ -2,6 +2,21 @@
 <CodeBlocks_layout_file>
 	<FileVersion major="1" minor="0" />
 	<ActiveTarget name="Debug" />
+	<File name="onedimtools.cpp" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+		<Cursor>
+			<Cursor1 position="1912" topLine="52" />
+		</Cursor>
+	</File>
+	<File name="matmatrix.h" open="1" top="1" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+		<Cursor>
+			<Cursor1 position="3422" topLine="88" />
+		</Cursor>
+	</File>
+	<File name="main.cpp" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+		<Cursor>
+			<Cursor1 position="18" topLine="0" />
+		</Cursor>
+	</File>
 	<File name="csolver1.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
 		<Cursor>
 			<Cursor1 position="11507" topLine="334" />
@@ -27,19 +42,4 @@
 			<Cursor1 position="2422" topLine="0" />
 		</Cursor>
 	</File>
-	<File name="onedimtools.cpp" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
-		<Cursor>
-			<Cursor1 position="1912" topLine="52" />
-		</Cursor>
-	</File>
-	<File name="matmatrix.h" open="1" top="1" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
-		<Cursor>
-			<Cursor1 position="3422" topLine="88" />
-		</Cursor>
-	</File>
-	<File name="main.cpp" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
-		<Cursor>
-			<Cursor1 position="18" topLine="0" />
-		</Cursor>
-	</File>
 </CodeBlocks_layout_file>
diff --git a/sys/csolver/param1.tmp b/sys/csolver/param1.tmp
deleted file mode 100644
index b94ef899f47b365fda92b1eae4e4a44316439468..0000000000000000000000000000000000000000
Binary files a/sys/csolver/param1.tmp and /dev/null differ
diff --git a/sys/csolvers.m b/sys/csolvers.m
index c4024531ef5131812fea183fd768e92f70c8d633..2edc128a0a8d76d832f32a73e566ab1ba05b1c12 100644
--- a/sys/csolvers.m
+++ b/sys/csolvers.m
@@ -39,8 +39,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('csolvers')">commands csolvers</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function [ts, ys, comm] = csolvers(ode, tspan, y0, ~, varargin)
     global g_grind g_permanent; %#ok<GVMIS>
     if nargin == 0
diff --git a/sys/dde_euler.m b/sys/dde_euler.m
index 8b12062d1bfc8f33f728105eb384aa69f27a8e8f..97aec13650105545e90a0a8b70e8ed72982e71a4 100644
--- a/sys/dde_euler.m
+++ b/sys/dde_euler.m
@@ -2,7 +2,7 @@ function [tout, yout, varargout] = dde_euler(odefile, tspan, y0, options, vararg
     global g_grind; %#ok<GVMIS>
     %DDE23('F',LAGS,HISTORY,TSPAN)
     if nargin >= 4
-        nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast'));
+        nonNegative = ~isempty(odeget(options, 'NonNegative', []));
         if nonNegative
             warning('GRIND:DDE23:NonNegativeIgnored', 'DDE23 does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.');
         end
@@ -109,14 +109,14 @@ function sol = dde_euler1(odefile, lags, history, tspan, options,varargin)
         sol.history = history;
     end
     y0 = temp(:);
-    initialy = ddeget(options, 'InitialY', [], 'fast');
+    initialy = ddeget(options, 'InitialY', []);
     if ~isempty(initialy)
         y0 = initialy(:);
     end
     if nargin < 4
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(options.OutputFcn);
diff --git a/sys/ddesol.m b/sys/ddesol.m
index e2779778731045c57da0ed30d5069f70e10b22a7..7bf6eb08bc5f86366773070a7a5900b1d9804368 100644
--- a/sys/ddesol.m
+++ b/sys/ddesol.m
@@ -2,7 +2,7 @@ function [tout, yout, varargout] = ddesol(odefile, tspan, y0, options, varargin)
     global g_grind; %#ok<GVMIS>
     %DDE23('F',LAGS,HISTORY,TSPAN)
     if nargin >= 4
-        nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast'));
+        nonNegative = ~isempty(odeget(options, 'NonNegative', []));
         if nonNegative
             warning('GRIND:DDE23:NonNegativeIgnored', 'DDE23 does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.');
         end
diff --git a/sys/defextern.m b/sys/defextern.m
index 241e5d8039f7d96dd82a0425322699221dfff74c..fabdd8fa91bcc41c3fcf184cf29bc25ce34ec315 100644
--- a/sys/defextern.m
+++ b/sys/defextern.m
@@ -28,8 +28,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('defextern')">commands defextern</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function g_result = defextern(varargin)
     %(name, default, data, opt1, opt2)
     global g_grind g_Y; %#ok<GVMIS>
diff --git a/sys/definepars.m b/sys/definepars.m
index 52a89036add65402b646d7b0c571b7c05e7f8023..2fa2bd04b89ee594d1f905858a7e2c6c45582b6d 100644
--- a/sys/definepars.m
+++ b/sys/definepars.m
@@ -14,8 +14,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('definepars')">commands definepars</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function definepars(varargin)
     fieldnams = {'par', 'U1', 'define parameter par.', ''}';
     i_parseargs(fieldnams, 'par(+)', '', varargin, false, {@i_isid});
diff --git a/sys/definespace.m b/sys/definespace.m
index 2cfebcbbedc2f794d6b6be434dfca46c48fbf7fb..6f33566f920c27c06bb7830d181d4ea15ef0ec22 100644
--- a/sys/definespace.m
+++ b/sys/definespace.m
@@ -34,8 +34,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('definespace')">commands definespace</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function definespace(varargin)
     global g_grind; %#ok<GVMIS>
     fieldnams = {'gridsize', 'i>0&length(i)<=2', 'size of the grid, adapts sizes of state variables and parameters', [1 1]; ...
diff --git a/sys/defpermanent.m b/sys/defpermanent.m
index 284bc6d40af7af4d532340ecb6c0129682a75b7e..fb1a7128b7152d3895e25081f5cce99af501b4d2 100644
--- a/sys/defpermanent.m
+++ b/sys/defpermanent.m
@@ -32,8 +32,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('defpermanent')">commands defpermanent</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function res = defpermanent(varargin)
     %(avar, avalue, apar)
     global g_permanent g_grind g_t; %#ok<GVMIS>
diff --git a/sys/dirfield.m b/sys/dirfield.m
index 66154071d0a0c8588dd39fb894ff7f9fd60633c5..ef516b2cd3b6ce5c8dfb1b73ab35dff227f2711c 100644
--- a/sys/dirfield.m
+++ b/sys/dirfield.m
@@ -21,8 +21,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('dirfield')">commands dirfield</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function dirfield(varargin)
     global g_grind t; %#ok<GVMIS>
     % avar=varargin{1};
diff --git a/sys/downcells.m b/sys/downcells.m
index 6b300dd454c94c115f15edc9594b459a509f60d6..3cef1896e2141f7b53037bd2f7cc017ee6e2eab3 100644
--- a/sys/downcells.m
+++ b/sys/downcells.m
@@ -15,8 +15,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('downcells')">commands downcells</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function result = downcells(N, bordered, aValue)
     if nargin < 2
         bordered = 'neumann';
diff --git a/sys/drawuniform.m b/sys/drawuniform.m
index 581d9f1705846faa9cc07012148a71a7984e4c8a..7c34d9439de140e8bdb17b41a7da0e2fca7e1e15 100644
--- a/sys/drawuniform.m
+++ b/sys/drawuniform.m
@@ -10,8 +10,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('drawuniform')">commands drawuniform</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function A = drawuniform(dim1, dim2, minA, maxA)
     if nargin == 3
         maxA = minA;
diff --git a/sys/dwiener.m b/sys/dwiener.m
index c784d08430859462c9909293e5dd80078714c396..3c91ec1c79428c7a2f750c48205952dc24921709 100644
--- a/sys/dwiener.m
+++ b/sys/dwiener.m
@@ -45,8 +45,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('dwiener')">commands dwiener</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function res = dwiener(at, gY, dgY_dY, No, varargin)
    global g_dwiener %#ok<GVMIS>
      if ~isempty(g_dwiener)&&isequal(at,'-i')
diff --git a/sys/e2n.m b/sys/e2n.m
index 048a37e4b1526d66c070d9a4a9a1d27921434eb0..8e327fba743626734766612ebf93027f8e9acf88 100644
--- a/sys/e2n.m
+++ b/sys/e2n.m
@@ -6,8 +6,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('e2n')">commands e2n</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 %start
 function e2n(varargin)
     i_parseargs('', '', '', varargin);
diff --git a/sys/e2p.m b/sys/e2p.m
index 3fd6d39a0d3e7994cc3e2494baae94f865c4afab..7a33c008cfdbdac8bdb40d8363905c42c8c4ef98 100644
--- a/sys/e2p.m
+++ b/sys/e2p.m
@@ -6,8 +6,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('e2p')">commands e2p</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 %start
 function e2p(varargin)
     i_parseargs('', '', '', varargin);
diff --git a/sys/e2r.m b/sys/e2r.m
index 9b5370ec471c727bf63f931c2a4d64fa723e9682..b21ebb5c71e18516963f5f866e6bc2698574a472 100644
--- a/sys/e2r.m
+++ b/sys/e2r.m
@@ -6,8 +6,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('e2r')">commands e2r</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 %start
 function e2r(varargin)
     i_parseargs('', '', '', varargin);
diff --git a/sys/e3r.m b/sys/e3r.m
index 59ee0202a1d43e8cb3d669ada96f269ff7a93e20..fd0686a4405cf1b18808095b2e825e9cbc02e4e7 100644
--- a/sys/e3r.m
+++ b/sys/e3r.m
@@ -6,8 +6,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('e3r')">commands e3r</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 %start
 function e3r(varargin)
     i_parseargs('', '', '', varargin);
diff --git a/sys/eigen.m b/sys/eigen.m
index 5a20704c2d82e0bbcefb1e503ae1b2bd60259590..73e56f247afe493c9504979b84ab832190473146 100644
--- a/sys/eigen.m
+++ b/sys/eigen.m
@@ -31,8 +31,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('eigen')">commands eigen</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function Eigs = eigen(varargin)
     global g_grind g_Y t g_t; %#ok<GVMIS>
     fieldnams = {'sizedist', 'n>0', 'Size of the perturbation of perturbation', 0.00001; ...
diff --git a/sys/enterjac.m b/sys/enterjac.m
index bff2af8742fc5c8d07b6d2d92160bff5c2b49eed..5ddfe11e78a733bc1fda5206328e34d9fa045a91 100644
--- a/sys/enterjac.m
+++ b/sys/enterjac.m
@@ -46,8 +46,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('enterjac')">commands enterjac</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [res, maxdif] = enterjac(varargin)
     global g_grind; %#ok<GVMIS>
     % if ~isempty(g_grind)
diff --git a/sys/era.m b/sys/era.m
index 909ceaed8fe0180eca63f79746e3937b3b24cfda..7dafb2c85a728dae7ee45228c01d862b0439ffae 100644
--- a/sys/era.m
+++ b/sys/era.m
@@ -9,8 +9,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('era')">commands era</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function era(varargin)
     args = i_parseargs('', '', '-a', varargin);
     allfigures = any(strcmp(args.opts, '-a'));
diff --git a/sys/externvar.m b/sys/externvar.m
index 2fe4f6d46cdfd37b66645c06491f9dcde3c1c2f3..3d743133ad7803023e8b1f44a9db525044eb971b 100644
--- a/sys/externvar.m
+++ b/sys/externvar.m
@@ -18,8 +18,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('externvar')">commands externvar</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function V = externvar(varnr, default, at)
     global g_grind g_t;
     if nargin == 2
diff --git a/sys/fglobalmin.m b/sys/fglobalmin.m
index ed59ae2e8147a283fcf609624787ac3029fdaef8..28525331293eeb09d40e8cc1c594f4e772f7dfab 100644
--- a/sys/fglobalmin.m
+++ b/sys/fglobalmin.m
@@ -42,8 +42,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('fglobalmin')">commands fglobalmin</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [bestx, bestf, exitflag, output] = fglobalmin(funfcn, ax, bx, options, varargin)
     %FGLOBALMIN Scalar bounded global function minimization.
     % Using the very robust Shuffled Complex Evolution (SCE-UA) global optimization algorithm.
diff --git a/sys/figdata.m b/sys/figdata.m
index efd4589d0ebe11e33530eb33f87c9d281a34ea2a..d9cfa8664fa1b498cf988f462769c09fa53f96b6 100644
--- a/sys/figdata.m
+++ b/sys/figdata.m
@@ -22,8 +22,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('figdata')">commands figdata</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function A = figdata(varargin)
     %(serno,ax)
     fieldnams = {'serno', 'i>0', 'number of the series to copy', 1; ...
diff --git a/sys/fokkerplanck.m b/sys/fokkerplanck.m
index c5b9876174826d685ff918478cb1cd78e85f9bbd..95bfa0942f90deee53c39d82f112216450b8136b 100644
--- a/sys/fokkerplanck.m
+++ b/sys/fokkerplanck.m
@@ -34,8 +34,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('fokkerplanck')">commands fokkerplanck</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function fokkerplanck(varargin)
     evalin('base', 'global g_langevin_eq');
     global g_langevin_eq g_grind; %#ok<GVMIS>
diff --git a/sys/funcs.m b/sys/funcs.m
index dcb92aa45f5eaff3de779094f191811e8cd8cbfb..1f0e09ad0fec6585341842c878355cb1e71e5567 100644
--- a/sys/funcs.m
+++ b/sys/funcs.m
@@ -27,8 +27,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('funcs')">commands funcs</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function funcs(varargin)
     global g_grind; %#ok<GVMIS>
     eoln = sprintf('\n'); %#ok<SPRINTFN>
diff --git a/sys/funplot.m b/sys/funplot.m
index 06bbb4958f9b8b31cf81bf19b36b0bf5ae3608f2..59a4ad63c54ee2eba617e14048ac91119819d25d 100644
--- a/sys/funplot.m
+++ b/sys/funplot.m
@@ -42,8 +42,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('funplot')">commands funplot</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function l_HH = funplot(varargin)
     %function funplot(afun,g_l_avar,[exchange],[axrange, ayrange],logxy, npoints);
     %
diff --git a/sys/funplot3.m b/sys/funplot3.m
index 2da65e8bfc18d510d3362fe05dc145fd54479157..64b81207fa72c73f25db80c9f681c41f31955967 100644
--- a/sys/funplot3.m
+++ b/sys/funplot3.m
@@ -30,8 +30,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('funplot3')">commands funplot3</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function funplot3(varargin)
     %(afun, varx, vary, axrange, ayrange, npoints)
     global g_grind; %#ok<GVMIS> 
diff --git a/sys/grind.cfg b/sys/grind.cfg
index a30eed04ac1d1a0e98552e1e1e95795eb3f58c6e..1b006dd9bd21f6004a75532b6ee12e18dcbced83 100644
--- a/sys/grind.cfg
+++ b/sys/grind.cfg
@@ -1,2 +1,3 @@
-matcontdir=C:\d\alg\MAT LAB\MatCont7p4
-matcontmdir=C:\d\alg\MAT LAB\matcontm5p4
+current_coco=C:\d\alg\MAT LAB\coco_2023October26
+current_matcontm=C:\d\alg\MAT LAB\matcontm5p4
+current_matcont=C:\d\alg\MAT LAB\MatCont7p4
diff --git a/sys/grind.m b/sys/grind.m
index 2823fbb663a29651788d22250ed3a07c648ebf5e..48af68016fab8a70f593352f6103c9476ac02002 100644
Binary files a/sys/grind.m and b/sys/grind.m differ
diff --git a/sys/grindhelp.chm b/sys/grindhelp.chm
index 240b1c99d5bd84a205fe56bb1776c8ba1e72f92c..5df824b1f19e21f8657c62cac1040cd7da1c672a 100644
Binary files a/sys/grindhelp.chm and b/sys/grindhelp.chm differ
diff --git a/sys/grindpath.m b/sys/grindpath.m
index eb7879ecec3b51fd970a99154fccd6b2e0d9f37f..1451a14ec4b6aa8ac33c3de8fbbfdaa0268a1fcd 100644
--- a/sys/grindpath.m
+++ b/sys/grindpath.m
@@ -4,8 +4,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('grindpath')">commands grindpath</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function p = grindpath(sys)
     if nargin == 0
         sys = 1;
diff --git a/sys/growths.m b/sys/growths.m
index 422fdb6962f9b891493f6142214b2476d1b62152..56ec87b198d319ee40c960fe9ece965108f27de3 100644
--- a/sys/growths.m
+++ b/sys/growths.m
@@ -13,8 +13,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('growths')">commands growths</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function growths(varargin)
     %(igrid)
     global g_grind; %#ok<GVMIS> 
diff --git a/sys/gstat.m b/sys/gstat.m
index 56ebb074bed8773e43673c8f2e10df4a50c70248..9cdb865f5f8a3f238dc015c2b1f65471d780c783 100644
--- a/sys/gstat.m
+++ b/sys/gstat.m
@@ -13,8 +13,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('gstat')">commands gstat</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function gstat(varargin)
     global g_grind t g_Y g_t; %#ok<GVMIS>
     fieldnams = {'output', 's', 'full or partial output (full,modelonly,paronly)'}';
diff --git a/sys/iif.m b/sys/iif.m
index b491423b1332fc582fc921d4894aae372fce767d..db599017c0a45e9ef4e10e4222f6c3db1a7f1e6e 100644
--- a/sys/iif.m
+++ b/sys/iif.m
@@ -21,8 +21,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('iif')">commands iif</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function res = iif(cond, A1, A2)
     if nargin < 3
         error('GRIND:iif:ArgError', '"iff" needs three arguments: iif(condition,iftrue,iffalse)');
diff --git a/sys/implicitdisperse.m b/sys/implicitdisperse.m
index 24c28e76c38aaed74ac99b3f70f18e5617357da1..f2c86e5653e8bf85fe9f8b8c5f4e3c0270cc4ffe 100644
--- a/sys/implicitdisperse.m
+++ b/sys/implicitdisperse.m
@@ -14,8 +14,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('implicitdisperse')">commands implicitdisperse</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function dA = implicitdisperse(ivar, avar, D)
     %
     %i_makemodel calls:
diff --git a/sys/implicitplot.m b/sys/implicitplot.m
index 7a3746ed24c63c84f60e3574a836dd4e76910a1c..b2175219ab512361f58070653aa4f3a498118b8a 100644
--- a/sys/implicitplot.m
+++ b/sys/implicitplot.m
@@ -28,8 +28,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('implicitplot')">commands implicitplot</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function implicitplot(varargin)
     %(afun, varx, vary, axrange, ayrange, npoints, issurf)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/initgrind.m b/sys/initgrind.m
index 79b641f7afbc9400b8c04ec4aef28f58dc20f303..576b008c83281aa567eec22aa9aac26828cce6e5 100644
--- a/sys/initgrind.m
+++ b/sys/initgrind.m
@@ -8,8 +8,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('initgrind')">commands initgrind</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 %start
 global t g_Y g_t g_data g_grind g_paranal g_cont; %#ok<GVMIS>
 addpath([grindpath filesep 'sys2']);
diff --git a/sys/insim.m b/sys/insim.m
index d993b7f8d357ae34abb37a0cef24bdc09ee5a2d0..addfc445c2981ca133acc4b2a1a251e78896d8f3 100644
--- a/sys/insim.m
+++ b/sys/insim.m
@@ -21,8 +21,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('insim')">commands insim</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [outp] = insim(varargin)
     %(filename)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/itermap.m b/sys/itermap.m
index a57803ea2a4596a70968b13e1e7785ce49a2e53d..809e58328822a20ae5e3f0462df499821e18e31a 100644
--- a/sys/itermap.m
+++ b/sys/itermap.m
@@ -28,8 +28,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('itermap')">commands itermap</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function hline = itermap(varargin)
     %(n, avar, alim, hax)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/ke.m b/sys/ke.m
index 2e33e96572e49cc6118eb3990a48fd72ff64db64..bee97d0e883be0a931129c7f765ed3e51ab6f524 100644
--- a/sys/ke.m
+++ b/sys/ke.m
@@ -17,8 +17,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('ke')">commands ke</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function ke(varargin)
     global g_Y g_t g_grind; %#ok<GVMIS>
     if (nargin > 0)
diff --git a/sys/lag.m b/sys/lag.m
index f7bc69a204599bec17338d9e506f28e7bbe73c00..fdae986c0d2af8657ec0bdce273cba87454dc0e0 100644
--- a/sys/lag.m
+++ b/sys/lag.m
@@ -17,8 +17,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('lag')">commands lag</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function res = lag(var, timelag)
     global g_t;
     if ischar(var)
diff --git a/sys/leftcells.m b/sys/leftcells.m
index 355deb2d653d5b3fd987d00291ac05891598ddb5..165f8df4e81a5484f5083e7570110e599a98d16a 100644
--- a/sys/leftcells.m
+++ b/sys/leftcells.m
@@ -15,8 +15,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('leftcells')">commands leftcells</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function result = leftcells(N, bordered, aValue)
     if nargin < 2
         bordered = 'neumann';
diff --git a/sys/loaddata.m b/sys/loaddata.m
index 0427cc854697093d7bacf23cb684b2bfe8934b9c..f331a600175eb3f6be26f3cd2df37c9018ac75bb 100644
--- a/sys/loaddata.m
+++ b/sys/loaddata.m
@@ -24,8 +24,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('loaddata')">commands loaddata</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function loaddata(varargin)
     global g_grind; %#ok<GVMIS>
     if nargin == 0
diff --git a/sys/lorenzmap.m b/sys/lorenzmap.m
index 4bd2915e8b644e96425431cf0546906c237e4d3d..503131e1b4d18e4370ccf6f7f0a44adba27d187b 100644
--- a/sys/lorenzmap.m
+++ b/sys/lorenzmap.m
@@ -16,8 +16,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('lorenzmap')">commands lorenzmap</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function lorenzmap(varargin)
     %avar
     global g_Y g_t g_grind t; %#ok<GVMIS>
diff --git a/sys/lyapunov.m b/sys/lyapunov.m
index b9a6dccb1e6fad671149c8f3bd1df2ca9fdb9f56..8fb0e3a14272ef8fbb11440b8eca22bcf6e11214 100644
--- a/sys/lyapunov.m
+++ b/sys/lyapunov.m
@@ -22,8 +22,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('lyapunov')">commands lyapunov</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [res, nhoriz] = lyapunov(varargin)
     global t g_Y g_t g_grind; %#ok<GVMIS>
     defaultdisturb = 1E-8;
diff --git a/sys/makemap.m b/sys/makemap.m
index 7eff2d56bf663fabe5c4bc4cf38ab5c3dc1a62df..ea52f1d4e45fa96ded309dd0d7ea087b374d0977 100644
--- a/sys/makemap.m
+++ b/sys/makemap.m
@@ -34,8 +34,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('makemap')">commands makemap</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function makemap(varargin)
     %(maptype, p1, p2)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/manifolds.m b/sys/manifolds.m
index 81863bbe3b5bc09c29fb07cae31a8832641609fb..99bb423cd4f3687d48d5f9e675afc5533302fc6e 100644
--- a/sys/manifolds.m
+++ b/sys/manifolds.m
@@ -22,8 +22,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('manifolds')">commands manifolds</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function res1 = manifolds(varargin)
     %(stable)
     global g_grind g_Y; %#ok<GVMIS>
diff --git a/sys/marbleplot.m b/sys/marbleplot.m
index cccfa7d2fea502abe6bb9606b3a6cd63b4ddcfad..8596cfc542f46b683e84ffbdae4dd6b1edee1f67 100644
--- a/sys/marbleplot.m
+++ b/sys/marbleplot.m
@@ -40,8 +40,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('marbleplot')">commands marbleplot</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function res = marbleplot(varargin)
     % (npot, par, rangepar, statevar, rangestatevar,varzero, ...
     %    stemlength, patchheight, mincolor, maxcolor, opaqueness)
diff --git a/sys/matlabLessThan.m b/sys/matlabLessThan.m
new file mode 100644
index 0000000000000000000000000000000000000000..2a949ad016d61e8b49eb20c7c508b95a6310da89
--- /dev/null
+++ b/sys/matlabLessThan.m
@@ -0,0 +1,24 @@
+function res = matlabLessThan(verparts)
+    %matlabLessThan
+    %This function is similar as verLessThan('matlab',..), but significantly
+    %faster. It only checks the version in two levels.
+    %usage:
+    %if matlabLessThan(verparts)
+    %    ...
+    %endif
+    %verparts should be a 2 x 1 vector with version numbers
+    % for instance
+    % if matlabLessThan([8 8])
+    %
+    persistent curparts
+    if isempty(curparts)
+        %slowest part
+        curparts = sscanf(version, '%d.%d')';
+    end
+    if verparts(1) ~= curparts(1)
+        res = curparts(1) < verparts(1);
+    else
+        res = curparts(2) < verparts(2);
+    end
+end
+
diff --git a/sys/mcarlo.m b/sys/mcarlo.m
index 3ff1ceb3b65dd80f224310353e95f4cdc0d81312..0a4ff808b71c9f871aa3e17665198d27aefeaee2 100644
--- a/sys/mcarlo.m
+++ b/sys/mcarlo.m
@@ -53,8 +53,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('mcarlo')">commands mcarlo</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function res = mcarlo(varargin)
     %(atype, opt)
     evalin('base', 'global g_mcarlo;');
diff --git a/sys/model.m b/sys/model.m
index a4831210a09b66ae717cb6af4429e1b8ee7bace5..cf7ee1278652ecc8134c21283f0dab48790f4cca 100644
--- a/sys/model.m
+++ b/sys/model.m
@@ -65,8 +65,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('model')">commands model</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function model(varargin)
     global g_grind; %#ok<GVMIS>
     %if the model name has spaces it can be read as separate arguments
diff --git a/sys/neighborcells.m b/sys/neighborcells.m
index 864ff1f4f5be765576cfb7b69262f4498db1654f..77ba615255cda79d921d19048a101dfde54f56c7 100644
--- a/sys/neighborcells.m
+++ b/sys/neighborcells.m
@@ -19,8 +19,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('neighborcells')">commands neighborcells</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function Result = neighborcells(N, nneighbors, bordered, value)
     siz = size(N);
     if nargin < 2
diff --git a/sys/nextpen.m b/sys/nextpen.m
index 6c8734e186b2993feb3e027a73c468f0b4893dc2..3acec200585be0f5540a36a902ad2cf048ba7dac 100644
--- a/sys/nextpen.m
+++ b/sys/nextpen.m
@@ -20,8 +20,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('nextpen')">commands nextpen</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function pen = nextpen(varargin)
     global g_grind; %#ok<GVMIS>
     if nargin == 0
diff --git a/sys/nmaxima.m b/sys/nmaxima.m
index fb4dd361573f276fab8f7430427b0f371fb8ed89..1e8bb781c61fea9663b6379b71cd614e548e6d91 100644
--- a/sys/nmaxima.m
+++ b/sys/nmaxima.m
@@ -43,8 +43,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('nmaxima')">commands nmaxima</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function result = nmaxima(varargin)
     %(nsteps, options, par2, par3)
     %
diff --git a/sys/null3.m b/sys/null3.m
index eaa72edacd7e84f779a12128f5b1583ec1fec21f..1c46cca2eb193648b5d80fe1e090034d9130e2ec 100644
--- a/sys/null3.m
+++ b/sys/null3.m
@@ -18,8 +18,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('null3')">commands null3</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function null3(varargin)
     %(npoints, opt)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/ode78.m b/sys/ode78.m
index 07a4f827c95beb03b8920266f1b11519983057c2..63fffc0fbf5788d69c377ab3ec891c4d1a00fead 100644
--- a/sys/ode78.m
+++ b/sys/ode78.m
@@ -65,7 +65,7 @@ function [tout, xout] = ode78(odefun, tspan, x0, options, varargin)
     
     
     if nargin >= 4
-        nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast'));
+        nonNegative = ~isempty(odeget(options, 'NonNegative', []));
         if nonNegative
             warning('GRIND:ode78:NonNegativeIgnored', 'ODE78 does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.');
         end
@@ -105,7 +105,7 @@ function [tout, xout] = ode78(odefun, tspan, x0, options, varargin)
     
     % Output function checking and output parameters
     haveoutfun = 1;
-    outfun = odeget(options, 'OutputFcn', [], 'fast');
+    outfun = odeget(options, 'OutputFcn', []);
     if isempty(outfun)
         haveoutfun = 0;
     end
diff --git a/sys/ode87.m b/sys/ode87.m
index eba840285aef5ab5b109fe26ad37a0ffb519a7ce..c597b96be39fa89fc97a5e6b43795ff92e5bcf8c 100644
--- a/sys/ode87.m
+++ b/sys/ode87.m
@@ -69,7 +69,7 @@ function [tout, xout] = ode87(odefun, tspan, x0, options, varargin)
     
     pow = 1 / 8; % power for step control
     if nargin >= 4
-        nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast'));
+        nonNegative = ~isempty(odeget(options, 'NonNegative', []));
         if nonNegative
             warning('GRIND:ode87:NonNegativeIgnored', 'ODE87 does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.');
         end
@@ -105,7 +105,7 @@ function [tout, xout] = ode87(odefun, tspan, x0, options, varargin)
     
     % Output ODEction checking and output parameters
     haveoutfun = 1;
-    outfun = odeget(options, 'OutputFcn', [], 'fast');
+    outfun = odeget(options, 'OutputFcn', []);
     if isempty(outfun)
         haveoutfun = 0;
     end
diff --git a/sys/onstart.m b/sys/onstart.m
index 20602e6cb067fe927d3baef6e59a6925c64a8d78..b2284482aba0bce1996d7b0a5cb4072c09bc14c1 100644
--- a/sys/onstart.m
+++ b/sys/onstart.m
@@ -21,8 +21,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('onstart')">commands onstart</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function onstart(varargin)
     global g_grind;
     fieldnams = {'fun', 'f#s', 'function/single line of code to be run before starting each run', ''}';
diff --git a/sys/optimpars.m b/sys/optimpars.m
index e8c29b3ee6b0e081ec0dddf863e39d310b00bf33..7ca93070b40a7cd7e98ef319446d3aeb136873c6 100644
--- a/sys/optimpars.m
+++ b/sys/optimpars.m
@@ -37,8 +37,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('optimpars')">commands optimpars</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function optimpars(varargin)
     global g_data g_grind g_Y; %#ok<GVMIS>
     if ~isfield(g_data, 'options') || isempty(g_data.options)
diff --git a/sys/out.m b/sys/out.m
index 2615c04fbf399f536a4d20d28a4c8659bd3e93da..592c89baf902879daa79d1f99885a66a14dd0e8b 100644
--- a/sys/out.m
+++ b/sys/out.m
@@ -43,8 +43,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('out')">commands out</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function out(varargin)
     global g_grind; %#ok<GVMIS>
     if isempty(g_grind)
diff --git a/sys/outf.m b/sys/outf.m
index 79b06cba6a9412ba5f5429937f4d6d3fe267e068..50617f23746b2f44af31bd8d30944da866d9b98d 100644
--- a/sys/outf.m
+++ b/sys/outf.m
@@ -51,8 +51,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('outf')">commands outf</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function res = outf(varargin)
     
     global g_Y g_t g_permanent g_func g_grind; %#ok<GVMIS>
diff --git a/sys/outfun.m b/sys/outfun.m
index a79e82b1d7ca18534ee35548ca03caa575d513e5..0cdad120d595b45b5879b5728b5a9cc4b8800041 100644
--- a/sys/outfun.m
+++ b/sys/outfun.m
@@ -33,8 +33,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('outfun')">commands outfun</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function [F, ndxs] = outfun(varargin)
     %(s, opt, acatfun)
     global g_grind g_paranal g_permanent g_cont g_mcarlo g_Y g_t; %#ok<GVMIS>
diff --git a/sys/par.m b/sys/par.m
index 81b051bdd14468b40b4d97149ea5ae861d51ef1d..62b379260e5c961005e93996e813924f27f89a1b 100644
--- a/sys/par.m
+++ b/sys/par.m
@@ -34,8 +34,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('par')">commands par</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function [p, p2] = par(varargin)
     global g_grind t; %#ok<GVMIS>
     if nargin >= 1 && strcmp(varargin{1}, 'group')
diff --git a/sys/paranal.m b/sys/paranal.m
index 636275577bfed839758cfce996c00f38fab6bb1c..f08721d8b6dca769960c7e57fa7606f9fad013fc 100644
--- a/sys/paranal.m
+++ b/sys/paranal.m
@@ -36,8 +36,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('paranal')">commands paranal</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function paranal(varargin)
     global g_paranal g_grind; %#ok<GVMIS> 
     
diff --git a/sys/paranal2d.m b/sys/paranal2d.m
index 7a24e03d60dab74547fe12a4464f8286588ba4bc..b8db1c9aa47ec186d6a6e360f13e719fdc9e8ae5 100644
--- a/sys/paranal2d.m
+++ b/sys/paranal2d.m
@@ -41,8 +41,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('paranal2d')">commands paranal2d</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function paranal2d(varargin)
     %evalin('base','global g_paranal2d;');
     %implicit i_parseargs
diff --git a/sys/parlookup.m b/sys/parlookup.m
index c68763076c040620e9fb37ef5606645f65fac7ee..05001c6948e90840f500769895694285faffeef0 100644
--- a/sys/parlookup.m
+++ b/sys/parlookup.m
@@ -17,8 +17,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('parlookup')">commands parlookup</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function apar = parlookup(tabl, key1, extrapolate, NaNisZero)
     if nargin < 4
         NaNisZero = 1;
diff --git a/sys/phas.m b/sys/phas.m
index bd6150568769032186751afde350aaac0513b8b3..076ababd0567f35397dc6fca46e600fc1637398a 100644
--- a/sys/phas.m
+++ b/sys/phas.m
@@ -31,8 +31,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('phas')">commands phas</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function phas(varargin)
     global g_grind t g_Y g_t; %#ok<GVMIS>
     fieldnams = {'ndays', 'n>0', 'number of days to run', g_grind.ndays; ...
diff --git a/sys/plotdata.m b/sys/plotdata.m
index 3f545c81374468d53b7df61decfe42f222743a59..179ddf93004251d63448bf3bc192657998783e82 100644
--- a/sys/plotdata.m
+++ b/sys/plotdata.m
@@ -4,8 +4,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('plotdata')">commands plotdata</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function plotdata
     i_plotdatadlg;
 end
diff --git a/sys/plotdiff.m b/sys/plotdiff.m
index fd30f23677e2609f93f4d4cc26f891ba00577a73..9badbf1eead25c462e710b8789d879d58df4acc6 100644
--- a/sys/plotdiff.m
+++ b/sys/plotdiff.m
@@ -24,8 +24,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('plotdiff')">commands plotdiff</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function [aX, aY, hplot] = plotdiff(varargin)
     %(avar, alim, npoints, hax)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/plotreldiff.m b/sys/plotreldiff.m
index 9f26e3bd75c735334a31a327dee61e4a5242bc9c..0b301795b2caa788290a9c2b0d480ca58222fbcf 100644
--- a/sys/plotreldiff.m
+++ b/sys/plotreldiff.m
@@ -18,8 +18,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('plotreldiff')">commands plotreldiff</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function [aX, aY, hplot] = plotreldiff(varargin)
     %(avar, alim, npoints, hax)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/poincaremap.m b/sys/poincaremap.m
index a5ffd4afe2e261012b2001b9a52cfcf594878171..22bc7545123f5628fea63fcf251c7da6a4c73be7 100644
--- a/sys/poincaremap.m
+++ b/sys/poincaremap.m
@@ -25,8 +25,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('poincaremap')">commands poincaremap</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function poincaremap(varargin)
     %(avar1, aplane, increasing)
     global g_grind g_t;
diff --git a/sys/poincaresect.m b/sys/poincaresect.m
index 43a63ae75c0bcddfacdef2d95cf571fc513e9fdc..0671e0f9869887e16ad31520b101354c052acd0b 100644
--- a/sys/poincaresect.m
+++ b/sys/poincaresect.m
@@ -25,8 +25,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('poincaresect')">commands poincaresect</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function poincar2 = poincaresect(varargin)
     %(aplane, increasing)
     global g_grind g_t;
diff --git a/sys/randinit.m b/sys/randinit.m
index 3e55fb7742a233d1ba7f3fcd4dd6f85f0bcb5966..309a2261cd261127ed13613a1520dc30d5d063ee 100644
--- a/sys/randinit.m
+++ b/sys/randinit.m
@@ -12,7 +12,7 @@
 %   RANDINIT('method',@(dim1,dim2)(randi(2,dim1,dim2)-1)*2-1) - use a different distribution 
 %   for the initial conditions. The user function should have 2 arguments like the function rand(dim1, dim2)
 %   RANDINIT('argname',argvalue,...) - Valid argument <a href="matlab:commands func_args">name-value pairs</a> [with type]:
-%     'method' [uniform | uneven | findeqs or function_handle] - method to draw the initial points (uniform, uneven or user function)
+%     'method' [uniform | uneven | findeqs | simple_uneven or function_handle] - method to draw the initial points (uniform, uneven or user function)
 %     'range' [double and length(double)<=2] - range for the initial points
 %     'var' [state variable or empty] - state variable (empty=all)
 %      
@@ -22,19 +22,19 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('randinit')">commands randinit</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function res = randinit(varargin)
     %(VarName,range)
     global g_grind g_Y; %#ok<GVMIS>
     fieldnams = {'var', 'v#E', 'state variable (empty=all)', [];  ...
-        'method', 'e[uniform|uneven|findeqs]#f', 'method to draw the initial points (uniform, uneven or user function)', 'uniform';  ...
+        'method', 'e[uniform|uneven|findeqs|simple_uneven]#f', 'method to draw the initial points (uniform, uneven or user function)', 'uniform';  ...
         'range', 'd&length(d)<=2', 'range for the initial points', [0 100]}';
     if nargin == 1 && isstruct(varargin{1})
         %this is used  by findeqs for speed 
         args = varargin{1};
     else
-        args = i_parseargs(fieldnams, 'if(argtype(1,''e[uniform|uneven]'')),deffields=''method,range'';elseif(argtype(1,''d'')),deffields=''range'';else,deffields=''var,range'';end;', '', varargin);
+        args = i_parseargs(fieldnams, 'if(argtype(1,''e[uniform|uneven|findeqs|simple_uneven]'')),deffields=''method,range'';elseif(argtype(1,''d'')),deffields=''range'';else,deffields=''var,range'';end;', '', varargin);
         i_parcheck;
     end
     if ~isfield(args, 'var')
@@ -56,12 +56,15 @@ function res = randinit(varargin)
             case 'uniform'
                 args.method = @(dim1,dim2)drawuniform(dim1,dim2,args.range(1), args.range(2));
             case 'uneven'
-                args.method = @(dim1,dim2)drawuneven(dim1,dim2,args.range(1), args.range(2));
+                args.method = @(dim1,dim2)drawbetarnd(dim1,dim2,args.range(1), args.range(2));
+            case 'simple_uneven'
+                %for testing without stats toolbox
+                args.method = @(dim1,dim2)drawsimple_uneven(dim1,dim2,args.range(1), args.range(2));
             case 'findeqs'
                 args.method = @(dim1,dim2)drawfindeqs(dim1, dim2, args.range(2));
         end
     end
-    
+ 
     %args.method is used to draw the full vector allways
     N1 = args.method(g_grind.statevars.dim, 1);
     if isempty(args.var)
@@ -92,18 +95,23 @@ function N0 = drawfindeqs(dim1, dim2, scale)
     N0(f3) = -N0(f3);
 end
 
-function N0 = drawuneven(dim1, dim2, minrange, maxrange)
+
+function N0 = drawsimple_uneven(dim1, dim2, minrange, maxrange)
+    N0 = drawuniform(dim1, dim2, minrange, maxrange);
+    ndx = rand(size(N0)) < 0.2;
+    N0(ndx) = N0(ndx) .* 0.1;
+    ndx = rand(size(N0)) < 0.1;
+    N0(ndx) = N0(ndx) .* 0.01;
+end
+
+function N0 = drawbetarnd(dim1, dim2, minrange, maxrange)
     try
         N0 = betarnd(0.4, 0.4, dim1, dim2) * (maxrange - minrange) + minrange;
     catch err
         %if the statistics toolbox is not present we offer an
         %alternative
         if strcmp(err.identifier, 'MATLAB:UndefinedFunction')
-            N0 = drawuniform(dim, 1, minrange, maxrange);
-            ndx = rand(size(N0)) < 0.1;
-            N0(ndx) = N0(ndx) .* 0.1;
-            ndx = rand(size(N0)) < 0.1;
-            N0(ndx) = N0(ndx) .* 0.01;
+            N0 = drawsimple_uneven(dim1, dim2, minrange, maxrange);
         else
             rethrow(err)
         end
diff --git a/sys/rednoise.m b/sys/rednoise.m
index c2e29454780074964d1283ba12d951413954a656..70e6a52b4a50bb001b5c80ff178ef25fc0b07130 100644
--- a/sys/rednoise.m
+++ b/sys/rednoise.m
@@ -35,8 +35,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('rednoise')">commands rednoise</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function T = rednoise(tnow, T0, lambda, beta, eqnr, deltat)
     %function T = rednoise(tnow, T0, labda, beta, isets, deltat)
     global g_rednoise g_grind; %#ok<GVMIS>
diff --git a/sys/replayall.m b/sys/replayall.m
index 1ca3599f42eac91e88f2ad5e127334bc12cb2641..726f6a941a1fc542ef11d991b8a9adfc9cb0f8f9 100644
--- a/sys/replayall.m
+++ b/sys/replayall.m
@@ -43,8 +43,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('replayall')">commands replayall</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function res = replayall(varargin)
     global g_grind; %#ok<GVMIS>
     % if isempty(which('i_replayall'))
diff --git a/sys/returntime.m b/sys/returntime.m
index 3134d1f497e0e94c1e5ccf1e820c4f68da7b687d..a55d934666c3a604a60312d464b8ba4d55594f1c 100644
--- a/sys/returntime.m
+++ b/sys/returntime.m
@@ -20,8 +20,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('returntime')">commands returntime</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [rettime, YY] = returntime(varargin)
     %(err1, maxt, methodopt), methods: both,change,equil
     global g_Y t g_t g_grind; %#ok<GVMIS>
diff --git a/sys/returntime2d.m b/sys/returntime2d.m
index bab15c13f222f87d817e695b9ecbc6a3e4f43c54..6704f6711c4a79cc92141590b714848bbedfe1f7 100644
--- a/sys/returntime2d.m
+++ b/sys/returntime2d.m
@@ -20,8 +20,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('returntime2d')">commands returntime2d</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [Vect, X, Y, Vect3d] = returntime2d(varargin)
     %(err, npoints)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/rightcells.m b/sys/rightcells.m
index 1709cec8e174065f6381fbd55f069a4ec65bbd01..314ef103a6774f6635c4d51546ed8b1ea00bcef5 100644
--- a/sys/rightcells.m
+++ b/sys/rightcells.m
@@ -14,8 +14,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('rightcells')">commands rightcells</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function result = rightcells(N, bordered, aValue)
     
     if nargin < 2
diff --git a/sys/rk4.m b/sys/rk4.m
index a9293aa1bf3d71ec6222ee743fcfee69908dbb71..5bd82a73b57a7fb261579a9a5453f923a037f941 100644
--- a/sys/rk4.m
+++ b/sys/rk4.m
@@ -15,8 +15,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('rk4')">commands rk4</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [tout, yout] = rk4(odefunct, tspan, y0, options)
     global g_grind;
     if (nargin < 4)
@@ -41,7 +41,7 @@ function [tout, yout] = rk4(odefunct, tspan, y0, options)
     if nargin < 4
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(options.OutputFcn);
diff --git a/sys/rk4_old.m b/sys/rk4_old.m
index 75e6dd031a806cd126b47b11e18a381fe80185a4..931cdd23fea47b660126ea9293f689256f53da39 100644
--- a/sys/rk4_old.m
+++ b/sys/rk4_old.m
@@ -50,7 +50,7 @@ function [tout, yout] = rk4(FunFcn, tspan, y0, options)
     if nargin < 4
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(options.OutputFcn);
diff --git a/sys/ru.m b/sys/ru.m
index 3d4f3bdba2b78251b4d94c2dd26613e2e79e186e..9a6b46c53dd7fab9450bcd5d04e3cdfabfcd8351 100644
--- a/sys/ru.m
+++ b/sys/ru.m
@@ -25,8 +25,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('ru')">commands ru</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function ru(varargin)
     global t g_grind g_Y g_t;
     fieldnams = {'ndays', 'n>0', 'number of days to run', 1000}';
diff --git a/sys/rungrid.m b/sys/rungrid.m
index f1e674e1a5890b3f1ec66bdfaca0460a29ff6d71..218a21a407876dc1a91c5973818d227f869a2f23 100644
--- a/sys/rungrid.m
+++ b/sys/rungrid.m
@@ -19,8 +19,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('rungrid')">commands rungrid</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function rungrid(varargin)
     %(nx, ny, ndays, twodir)
     global g_grind;
diff --git a/sys/savemodel.m b/sys/savemodel.m
index 3027041c8021f77ff285a51ca749f27ad594e650..a5b1cf6feba85c3a43bb16ad8782e491c230f5b6 100644
--- a/sys/savemodel.m
+++ b/sys/savemodel.m
@@ -19,8 +19,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('savemodel')">commands savemodel</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function savemodel(varargin)
     %afilename, overwrite, filetype
     global g_grind;
diff --git a/sys/savepar.m b/sys/savepar.m
index 4e7e9e1778c280ec0f234229291c152df58421c3..bbd213b703154fc4709c8ffc8190c92f635d2c31 100644
--- a/sys/savepar.m
+++ b/sys/savepar.m
@@ -21,8 +21,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('savepar')">commands savepar</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function savepar(varargin)
     %(afile, overwrite, keeprand)
     global g_grind g_data; %#ok<GVMIS>
diff --git a/sys/setcolormap.m b/sys/setcolormap.m
index 6276e1ed6ffdd95fd383fc08bbafedb2a520543b..aa7d0fdf733c67ccac2f41cf58d0e9c60cc46992 100644
--- a/sys/setcolormap.m
+++ b/sys/setcolormap.m
@@ -21,8 +21,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setcolormap')">commands setcolormap</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function result = setcolormap(varargin)
     %(m, bottomcolor, topcolor)
     %hsv = 1;
diff --git a/sys/setdata.m b/sys/setdata.m
index ebd9b9a2ed9bcf1e5814c813815a02f668bb3890..4e8615cf4cbf96cbedaa9d266c32ff7bc3497438 100644
--- a/sys/setdata.m
+++ b/sys/setdata.m
@@ -28,8 +28,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setdata')">commands setdata</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function outlist = setdata(varargin)
     %(amatrix, varlist)
     global g_data g_grind;
diff --git a/sys/setdefaults.m b/sys/setdefaults.m
index 3959aaad87961e4dcb1fafc7228df56b86ccc042..0d944402cc2c4079591e2d9c57d46ed77af79658 100644
--- a/sys/setdefaults.m
+++ b/sys/setdefaults.m
@@ -12,8 +12,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setdefaults')">commands setdefaults</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function def = setdefaults(varargin)
     %(doload)
     global g_grind;
diff --git a/sys/setdimension.m b/sys/setdimension.m
index 874b61e274cef9bb8f0f0680c6928a83d80b4897..b9a9a1780c24c07d068629729d090ebbe0402fd7 100644
--- a/sys/setdimension.m
+++ b/sys/setdimension.m
@@ -36,8 +36,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setdimension')">commands setdimension</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function res = setdimension(varargin)
     %(avar, dims, createfun ,diagon)
     global g_Y g_grind;
diff --git a/sys/setevent.m b/sys/setevent.m
index 267a43df96697cc4e3bda6588a59857a3b4bca07..44cf134c5f58f064fed364fcf138191f73bf5800 100644
--- a/sys/setevent.m
+++ b/sys/setevent.m
@@ -37,8 +37,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setevent')">commands setevent</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function setevent(varargin)
     %(event, dt,varargin)
     if nargin == 0
diff --git a/sys/setmat.m b/sys/setmat.m
index ca3598db9f5bb15495f2d245e4594eea6c888118..49905774f1cf68c76c4b50aa7b348f965b0b800e 100644
--- a/sys/setmat.m
+++ b/sys/setmat.m
@@ -32,8 +32,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setmat')">commands setmat</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [A, locs] = setmat(varargin)
     %(var, loc, siz, value, num)
     global g_grind;
diff --git a/sys/setodefile.m b/sys/setodefile.m
index 5b2ef3d8deedcfce65263a2985226c02e40e9453..eacf9dfcbde36d9a2b8b3191a539c654d9e5a633 100644
--- a/sys/setodefile.m
+++ b/sys/setodefile.m
@@ -19,8 +19,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setodefile')">commands setodefile</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function ggrind = setodefile(varargin)
     %(afile, varlist,opt)
     global g_grind
diff --git a/sys/setpen.m b/sys/setpen.m
index cacae051f51d66a5e0cd410d75899ebb0a8db889..f7139872ee4fb9417b8cf710623da9d58b761a6a 100644
--- a/sys/setpen.m
+++ b/sys/setpen.m
@@ -44,8 +44,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('setpen')">commands setpen</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function thepen = setpen(varargin)
     %(acolor, linestyle, markerstyle,cycle )
     global g_grind;
diff --git a/sys/simtime.m b/sys/simtime.m
index 367cb0e926ff4771bc0c9f6f9675cd5002c21d8b..75aef0e30c6bcf5dc4f0a042aea7a2a9f30e8be1 100644
--- a/sys/simtime.m
+++ b/sys/simtime.m
@@ -22,8 +22,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('simtime')">commands simtime</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function simtime(varargin)
     global t g_grind; %#ok<GVMIS> 
     fieldnams = {'t', 'n', 'start time', 0; ...
diff --git a/sys/solver.m b/sys/solver.m
index 3ecf9784a0d5fecec87da785f35263d218c26f1c..381f9c21eeb6ba708da94d4af3b021466f1b777e 100644
--- a/sys/solver.m
+++ b/sys/solver.m
@@ -49,8 +49,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('solver')">commands solver</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [res] = solver(varargin)
     %(solv, p1, p2, p3, p4)
     global g_grind; %#ok<GVMIS>
diff --git a/sys/stabil.m b/sys/stabil.m
index 5136b93422e8288c4bc66006fa5ce73e3653d907..39da6cab61216f9368fb274ebc68b6f0ff62d126 100644
--- a/sys/stabil.m
+++ b/sys/stabil.m
@@ -19,8 +19,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('stabil')">commands stabil</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function stabil(varargin)
     global t g_grind g_Y;
     fieldnams = {'ndays', 'n>0', 'number of days to stabilize', 1000; ...
diff --git a/sys/sys2/Dx.m b/sys/sys2/Dx.m
index d31ccd082db650cd183d06c00473dad8bf4fad2b..5f1d9337c412885be5b7c3a4240f53b6efb90d23 100644
--- a/sys/sys2/Dx.m
+++ b/sys/sys2/Dx.m
@@ -15,8 +15,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('Dx')">commands Dx</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function differ = Dx(N)
     global g_grind;
     if ~isfield(g_grind, 'space') || isempty(g_grind.space)
diff --git a/sys/sys2/Dxx.m b/sys/sys2/Dxx.m
index 85f55123f189eb6d03866928021e3cb5fc620062..d88b411950820706c375ac723bac6fe037f0774f 100644
--- a/sys/sys2/Dxx.m
+++ b/sys/sys2/Dxx.m
@@ -14,8 +14,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('Dxx')">commands Dxx</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function differ = Dxx(N)
     global g_grind;
     if ~isfield(g_grind, 'space') || isempty(g_grind.space)
diff --git a/sys/sys2/Dy.m b/sys/sys2/Dy.m
index 6c28eb94aa4895fce534ce18c6659fb911bed57d..28b538158a1fe3cf5626c8aa359f8e57efcda8f5 100644
--- a/sys/sys2/Dy.m
+++ b/sys/sys2/Dy.m
@@ -15,8 +15,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('Dy')">commands Dy</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function differ = Dy(N)
     global g_grind;
     if ~isfield(g_grind, 'space') || isempty(g_grind.space)
diff --git a/sys/sys2/Dyy.m b/sys/sys2/Dyy.m
index c5bc75403919e93da9828544d96ed69b3d7ef7b1..d31f44d75b7a2236636fb8e7e32b6c3fe97bf7f0 100644
--- a/sys/sys2/Dyy.m
+++ b/sys/sys2/Dyy.m
@@ -15,8 +15,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('Dyy')">commands Dyy</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function differ = Dyy(N)
     global g_grind;
     if ~isfield(g_grind, 'space') || isempty(g_grind.space)
diff --git a/sys/sys2/autocorrs.m b/sys/sys2/autocorrs.m
index b3d0bae87c4da0b3b66377651f80e4dce8231126..60ea89e035e9af7c2806ebc31d3db78c2d71bbe7 100644
--- a/sys/sys2/autocorrs.m
+++ b/sys/sys2/autocorrs.m
@@ -16,8 +16,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('autocorrs')">commands autocorrs</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function [result, A] = autocorrs(varargin)
     %(maxlag)
     global g_Y g_t t g_grind;
diff --git a/sys/sys2/ax.m b/sys/sys2/ax.m
index fe99a4050d8cd6121b7840a4bbd6500db30606f7..90bbfd7e9af743062a463a9c505b3a86af8cdc16 100644
--- a/sys/sys2/ax.m
+++ b/sys/sys2/ax.m
@@ -37,8 +37,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('ax')">commands ax</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function ax(varargin)
     %axname, axvar, axlim, axmax)
     global g_grind g_paranal;
diff --git a/sys/sys2/back_differ.m b/sys/sys2/back_differ.m
index ce8309b60ac3635c75398f7ffb724d6f915786cd..1be5fb47cd728a04b44ab0ebb73f2c04279f10e7 100644
--- a/sys/sys2/back_differ.m
+++ b/sys/sys2/back_differ.m
@@ -17,7 +17,7 @@ function [tout, yout] = back_differ(odefunct, tspan, y0, options)
     end
 
     if nargin >= 4
-        nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast'));
+        nonNegative = ~isempty(odeget(options, 'NonNegative', []));
         if nonNegative
             warning('GRIND:back_euler:NonNegativeIgnored', 'BACK_EULER does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.');
         end
diff --git a/sys/sys2/ddesolsd.m b/sys/sys2/ddesolsd.m
index 2a219e3d8ec1829079be136ae1719653b9077fbb..5b73554ccf4f98cb72a823d9ac141a2d0eb5ef40 100644
--- a/sys/sys2/ddesolsd.m
+++ b/sys/sys2/ddesolsd.m
@@ -2,7 +2,7 @@ function [tout, yout, varargout] = ddesolsd(odefile, tspan, y0, options, varargi
     global g_grind;
     %DDEsd('F',LAGS,HISTORY,TSPAN)
     if nargin >= 4
-        nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast'));
+        nonNegative = ~isempty(odeget(options, 'NonNegative', []));
         if nonNegative
             warning('GRIND:DDESD:NonNegativeIgnored', 'DDESD does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.');
         end
diff --git a/sys/sys2/djump.m b/sys/sys2/djump.m
index cdd9dfccca75801f907d0be89186a6d96e25c85e..84efd40a68972b274bee874526bbdd092ff0e9d9 100644
--- a/sys/sys2/djump.m
+++ b/sys/sys2/djump.m
@@ -39,8 +39,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('djump')">commands djump</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $
 function args1 = djump(varargin)
     global g_grind
     fieldnams = {'timing', 's', 'equation that generates the duration of the intervals', 100; ...
diff --git a/sys/sys2/euler.m b/sys/sys2/euler.m
index 008d415f620c4547f24fd28cee479ce17a16d7d5..29ecf0da930b94426fc6785427fccb679efa9072 100644
--- a/sys/sys2/euler.m
+++ b/sys/sys2/euler.m
@@ -9,8 +9,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('euler')">commands euler</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [tout, yout] = euler(odefunct, tspan, y0, options)
 %    global g_grind;
     if (nargin < 4)
@@ -35,7 +35,7 @@ function [tout, yout] = euler(odefunct, tspan, y0, options)
     if nargin < 4
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(options.OutputFcn);
diff --git a/sys/sys2/externlag.m b/sys/sys2/externlag.m
index 7382ec943fe53244496286152f3ac1d3ddbb6e43..79b938e9c9b652e319d8498392c4ff85b23a9a76 100644
--- a/sys/sys2/externlag.m
+++ b/sys/sys2/externlag.m
@@ -18,8 +18,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('externlag')">commands externlag</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function res = externlag(var, timelag)
     global g_t;
     if ischar(var)
diff --git a/sys/sys2/fftconv.m b/sys/sys2/fftconv.m
index 0669117b0a3ab3f7ee8c3bfaaff447b8afcdbfce..689b7007dbdd56f768e836fe940f5c814724c4d5 100644
--- a/sys/sys2/fftconv.m
+++ b/sys/sys2/fftconv.m
@@ -25,8 +25,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('fftconv')">commands fftconv</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [P1] = fftconv(P, L, pars, kernell)
     global g_grind;
     if ((nargin == 4)) || ~isfield(g_grind, 'fK')
diff --git a/sys/sys2/findeq.m b/sys/sys2/findeq.m
index b7fdcacff06d6a2ec757eb08ecc2753291b43be6..2dc4921dcf5fa3f29d863c150e3ab6927227d760 100644
--- a/sys/sys2/findeq.m
+++ b/sys/sys2/findeq.m
@@ -37,8 +37,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('findeq')">commands findeq</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [N1, found] = findeq(varargin)
     global g_Y g_grind;
     if isfield(g_grind, 'solver')
diff --git a/sys/sys2/findeqs.m b/sys/sys2/findeqs.m
index 4ca2e2c8bfe331d8afc06e6c224d73f4c583b96f..9b0b3fc81446753ae2a7184182b1d7a6d5e415dd 100644
--- a/sys/sys2/findeqs.m
+++ b/sys/sys2/findeqs.m
@@ -50,8 +50,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('findeqs')">commands findeqs</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [eqlist, eqs] = findeqs(varargin)
     %(ntrial, scal)
     global g_grind;
diff --git a/sys/sys2/fixedstep_solver.m b/sys/sys2/fixedstep_solver.m
index 15c2386e041588bb5034326962ada317ace411e6..88a8f5da6e5e6de8dfdbd649ffc216a41f458655 100644
--- a/sys/sys2/fixedstep_solver.m
+++ b/sys/sys2/fixedstep_solver.m
@@ -87,7 +87,7 @@ function [tout, yout] = fixedstep_solver(solvername, odefunct, tspan, y0, option
     if nargin < 5
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     nout = 0;
     anyNonNegative = ~isempty(nonNegative);
diff --git a/sys/sys2/forward_stabil.m b/sys/sys2/forward_stabil.m
index 8e94c6468f2c0bf2de5b550741f97dfa03b7a577..bcfecc835790c4c0f966aa1d2c582e1f089a03c7 100644
--- a/sys/sys2/forward_stabil.m
+++ b/sys/sys2/forward_stabil.m
@@ -38,8 +38,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('forward_stabil')">commands forward_stabil</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function res = forward_stabil(varargin)
     global g_paranal g_grind g_Y
     fieldnams = {'parvalue', 'n', 'the values of the parameters of the point', 0; ...
diff --git a/sys/sys2/graphplot.m b/sys/sys2/graphplot.m
index 15cb98a2bc91de8187cc96a92de546633cdc80a5..c292a90fa36d4b4090f65aab0871d958b382273e 100644
--- a/sys/sys2/graphplot.m
+++ b/sys/sys2/graphplot.m
@@ -18,8 +18,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('graphplot')">commands graphplot</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function graphplot(varargin)
     global g_Y g_t t g_grind;
     % g_t = (g_t(1):g_t(2):g_t(3))';
diff --git a/sys/sys2/grind_coco.m b/sys/sys2/grind_coco.m
index db31c7a0ede2ae51868ebcfedee7b8aaca1c2f8a..c010e28463ce3d7dc0a3d0254c0d5657a7f77559 100644
--- a/sys/sys2/grind_coco.m
+++ b/sys/sys2/grind_coco.m
@@ -16,41 +16,42 @@ classdef grind_coco < grind_cont
             obj.settings.derived.engine = 'coco';
             init_engine(obj);
             init_engine(obj, true);
-            verfile = fullfile(obj.settings.derived.engine_path, 'cocoversion.txt');
-            if exist(verfile, 'file')
-                fid = fopen(verfile, 'r');
-                obj.settings.derived.version = fgetl(fid);
-                obj.settings.derived.version = obj.settings.derived.version(6:end - 4);
-                fclose(fid);
-            else
-                obj.settings.derived.version = 'unknown';
-            end
+            [~,obj.settings.derived.version]=fileparts(obj.settings.derived.engine_path);
+%             verfile = fullfile(obj.settings.derived.engine_path, 'cocoversion.txt');
+%             if exist(verfile, 'file')
+%                 fid = fopen(verfile, 'r');
+%                 obj.settings.derived.version = fgetl(fid);
+%                 obj.settings.derived.version = obj.settings.derived.version(6:end - 4);
+%                 fclose(fid);
+%             else
+%                 obj.settings.derived.version = 'unknown';
+%             end
             
             
-            crveprops = {'EP', 1, 'EP - Equilibrium points', false, 'b'; ...
-                'H', 2, 'H - Hopf bifurcation', false, 'r'; ...
-                'LC', 1, 'LC - Limit cycle', true, 'b'; ...
-                'T', 2, 'T - Transcritical bifurcation', false, 'b'; ...
+            crveprops = {'EP', 1, 'EP - Equilibrium points', false, 'b';  ...
+                'H', 2, 'H - Hopf bifurcation', false, 'r';  ...
+                'LC', 1, 'LC - Limit cycle', true, 'b';  ...
+                'T', 2, 'T - Transcritical bifurcation', false, 'b';  ...
                 'F', 2, 'F - Fold bifurcation', false, 'g'};
             
-            obj.curveprops = struct('ctype', crveprops(:, 1), 'clabel', crveprops(:, 1), 'npars', crveprops(:, 2), 'iscycle', crveprops(:, 4), ...
+            obj.curveprops = struct('ctype', crveprops(:, 1), 'clabel', crveprops(:, 1), 'npars', crveprops(:, 2), 'iscycle', crveprops(:, 4),  ...
                 'descr', crveprops(:, 3), 'color', crveprops(:, 5), 'resfun', @extract_coco_curve_eq);
             ndx = obj.getndx('curveprops', 'ctype', 'F');
             obj.curveprops(ndx).clabel = 'SN';
             ndx = obj.getndx('curveprops', 'ctype', 'T');
             obj.curveprops(ndx).clabel = 'SN';
-            pntprops = {'BT', 'Bogdanov-Takens', 2, ''; ...
-                'CP', 'Cusp', 2, ''; ...
-                'EP', 'Equilibrium', 0, 'EP'; ...
-                'F', 'Fold', 1, 'F'; ...
-                'GH', 'Generalized Hopf', 2, ''; ...
-                'H', 'Hopf', 1, 'H,LC'; ...
-                'HH', 'Double Hopf', 2, ''; ...
-                'LC', 'Limit cycle', 0, ''; ...
-                'P', 'Any initial conditions', 0, 'EP,LC'; ...
-                'T', 'Transcritical bif.', 1, 'EP,T'; ...
+            pntprops = {'BT', 'Bogdanov-Takens', 2, '';  ...
+                'CP', 'Cusp', 2, '';  ...
+                'EP', 'Equilibrium', 0, 'EP';  ...
+                'F', 'Fold', 1, 'F';  ...
+                'GH', 'Generalized Hopf', 2, '';  ...
+                'H', 'Hopf', 1, 'H,LC';  ...
+                'HH', 'Double Hopf', 2, '';  ...
+                'LC', 'Limit cycle', 0, '';  ...
+                'P', 'Any initial conditions', 0, 'EP,LC';  ...
+                'T', 'Transcritical bif.', 1, 'EP,T';  ...
                 'ZH', 'Zero-Hopf', 2, ''};
-            obj.pointprops = struct('ptype', pntprops(:, 1), 'label', pntprops(:, 1), 'descr', pntprops(:, 2), ...
+            obj.pointprops = struct('ptype', pntprops(:, 1), 'label', pntprops(:, 1), 'descr', pntprops(:, 2),  ...
                 'codim', pntprops(:, 3), 'ctypes', pntprops(:, 4));
             for i = 1:length(obj.pointprops)
                 obj.pointprops(i).ctypes = regexp(obj.pointprops(i).ctypes, '[\,]', 'split');
@@ -88,7 +89,7 @@ classdef grind_coco < grind_cont
                 %%% NOTE Here I assume that the options structure and grind_opt have the same order!!
                 if nargin == 2 && strcmp('-nondefault', varargin{1})
                     args = [descr(:, 1), allopts(:, end)];
-                    for i = size(args, 1): - 1:1
+                    for i = size(args, 1): -1:1
                         if struccmp(descr{i, 4}, args{i, end})
                             args(i, :) = [];
                         elseif strcmp(args{i, 1}, 'activepars') && (islogical(args{i, end}) && all(args{i, end}))
@@ -196,8 +197,8 @@ classdef grind_coco < grind_cont
             %                 end
             %             end
             %             pairs4={'frompoint(c#s)';'ctype(c#s)';'file(s)'};
-            ext_opts = {'frompoint', 'c#s', 'code of the point from which the continuation starts (for instance ''EP1'') (default: empty)', ''; ...
-                'ctype', 'c#s', 'type of curve for continuations (for instance EP)', ''; ...
+            ext_opts = {'frompoint', 'c#s', 'code of the point from which the continuation starts (for instance ''EP1'') (default: empty)', '';  ...
+                'ctype', 'c#s', 'type of curve for continuations (for instance EP)', '';  ...
                 'file', 's', 'open a previously saved conteq session', ''};
             args = i_parseargs([obj.corr_opt; obj.cont_opt; obj.grind_opt; ext_opts].', 'if nargs==1,deffields=''file'';else,deffields=''par1,frompoint,ctype'';end;', '-defaults,-coco,-matcont,-c,-out,-l', varargin);
             if any(strcmp(args.opts, '-defaults'))
@@ -399,69 +400,69 @@ classdef grind_coco < grind_cont
         
         function argnames = get_func_args(label, clabel)
             
-            init_functs = {'BP_BP', {'odefile', 'x', 'p', 'ap', 'bp'}; ...
-                'BPC_BPC', {'odefile', 'x', 's', 'ap', 'ntst', 'NCOL', 'bp'}; ...
-                'BP_EP', {'odefile', 'x', 'p', 's', 'amp'}; ...
-                'EP_EP', {'odefile', 'x', 'p', 'ap'}; ...
-                'H_EP', {'odefile', 'x', 'p', 'ap'}; ...
-                'LP_EP', {'odefile', 'x', 'p', 'ap', 'varargin'}; ...
-                'HTHet_Het', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'Het_Het', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'BT_Hom', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'TTolerance ', 'amplitude', 'extravec'}; ...
-                'HSN_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'HTHom_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'Hom_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'LC_Hom', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'NCH_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'HSN_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'HTHSN_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'Hom_HSN', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'LC_HSN', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'NCH_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ...
-                'HTHet_HTHet', {'odefile', 'x', 'v', 's', 'p', 'ap', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ...
-                'HTHom_HTHom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ...
-                'HTHSN_HTHSN', {'odefile', 'x', 'v', 's', 'p', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ...
-                'BT_H', {'odefile', 'x', 'p', 'ap'}; ...
-                'GH_H', {'odefile', 'x', 'p', 'ap'}; ...
-                'HH_H', {'odefile', 'x', 'p', 'ap'}; ...
-                'H_H', {'odefile', 'x', 'p', 'ap'}; ...
-                'ZH_H', {'odefile', 'x', 'p', 'ap'}; ...
-                'BPC_LC', {'odefile', 'x', 'v', 's', 'NTST', 'NCOL', 'h'}; ...
-                'H_LC', {'odefile', 'x', 'p', 'ap', 'amp', 'NTST', 'NCOL'}; ...
-                'LC_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ...
-                'LPC_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ...
-                'NS_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ...
-                'P_EP', {'odefile', 'x', 'p', 'ap', 'ndays'}; ...
-                'P_LC', {'odefile', 'x', 'p', 'ap', 'NTST', 'NCOL', 'ndays', 'cycletol'}; ...
-                'PD_LC', {'odefile', 'x', 's', 'NTST', 'NCOL', 'h'}; ...
-                'PD_LC2', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL', 'h'}; ...
-                'BP_LP', {'odefile', 'x', 'p', 'ap'}; ...
-                'BT_LP', {'odefile', 'x', 'p', 'ap'}; ...
-                'CP_LP', {'odefile', 'x', 'p', 'ap'}; ...
-                'LP_LP', {'odefile', 'x', 'p', 'ap', 'varargin'}; ...
-                'ZH_LP', {'odefile', 'x', 'p', 'ap'}; ...
-                'BPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'CPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'GH_LPC', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps', 'varargin'}; ...
-                'LPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL', 'varargin'}; ...
-                'LPNS_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'LPPD_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'R1_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'CHNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'HH_NS1', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ...
-                'HH_NS2', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ...
-                'LPNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'NS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'PDNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'R1_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'R2_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'R3_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'R4_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'ZH_NS', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ...
-                'GPD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'LPPD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'PDNS_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
-                'PD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ...
+            init_functs = {'BP_BP', {'odefile', 'x', 'p', 'ap', 'bp'};  ...
+                'BPC_BPC', {'odefile', 'x', 's', 'ap', 'ntst', 'NCOL', 'bp'};  ...
+                'BP_EP', {'odefile', 'x', 'p', 's', 'amp'};  ...
+                'EP_EP', {'odefile', 'x', 'p', 'ap'};  ...
+                'H_EP', {'odefile', 'x', 'p', 'ap'};  ...
+                'LP_EP', {'odefile', 'x', 'p', 'ap', 'varargin'};  ...
+                'HTHet_Het', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'Het_Het', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'BT_Hom', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'TTolerance ', 'amplitude', 'extravec'};  ...
+                'HSN_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'HTHom_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'Hom_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'LC_Hom', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'NCH_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'HSN_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'HTHSN_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'Hom_HSN', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'LC_HSN', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'NCH_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'};  ...
+                'HTHet_HTHet', {'odefile', 'x', 'v', 's', 'p', 'ap', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'};  ...
+                'HTHom_HTHom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'};  ...
+                'HTHSN_HTHSN', {'odefile', 'x', 'v', 's', 'p', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'};  ...
+                'BT_H', {'odefile', 'x', 'p', 'ap'};  ...
+                'GH_H', {'odefile', 'x', 'p', 'ap'};  ...
+                'HH_H', {'odefile', 'x', 'p', 'ap'};  ...
+                'H_H', {'odefile', 'x', 'p', 'ap'};  ...
+                'ZH_H', {'odefile', 'x', 'p', 'ap'};  ...
+                'BPC_LC', {'odefile', 'x', 'v', 's', 'NTST', 'NCOL', 'h'};  ...
+                'H_LC', {'odefile', 'x', 'p', 'ap', 'amp', 'NTST', 'NCOL'};  ...
+                'LC_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'};  ...
+                'LPC_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'};  ...
+                'NS_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'};  ...
+                'P_EP', {'odefile', 'x', 'p', 'ap', 'ndays'};  ...
+                'P_LC', {'odefile', 'x', 'p', 'ap', 'NTST', 'NCOL', 'ndays', 'cycletol'};  ...
+                'PD_LC', {'odefile', 'x', 's', 'NTST', 'NCOL', 'h'};  ...
+                'PD_LC2', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL', 'h'};  ...
+                'BP_LP', {'odefile', 'x', 'p', 'ap'};  ...
+                'BT_LP', {'odefile', 'x', 'p', 'ap'};  ...
+                'CP_LP', {'odefile', 'x', 'p', 'ap'};  ...
+                'LP_LP', {'odefile', 'x', 'p', 'ap', 'varargin'};  ...
+                'ZH_LP', {'odefile', 'x', 'p', 'ap'};  ...
+                'BPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'CPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'GH_LPC', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps', 'varargin'};  ...
+                'LPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL', 'varargin'};  ...
+                'LPNS_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'LPPD_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'R1_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'CHNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'HH_NS1', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'};  ...
+                'HH_NS2', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'};  ...
+                'LPNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'NS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'PDNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'R1_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'R2_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'R3_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'R4_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'ZH_NS', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'};  ...
+                'GPD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'LPPD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'PDNS_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
+                'PD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'};  ...
                 'R2_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}};
             ndx = strcmp([label '_' clabel], init_functs(:, 1));
             argnames = init_functs(ndx, 2);
@@ -469,20 +470,20 @@ classdef grind_coco < grind_cont
                 argnames = argnames{1};
             end
         end
-        function engine_path = findupdate(checkupdates, url)
+        function engine_path = findupdate(checkupdates, urls)
             function writecfg(engine_path)
                 if exist('grind.cfg', 'file')
                     fid = fopen('grind.cfg', 'r');
                     lines = textscan(fid, '%s', 'delimiter', '\n', 'whitespace', '');
                     lines = lines{1};
                     fclose(fid);
-                    ndx = ~cellfun('isempty', (strfind(lines, 'cocodir=')));
+                    ndx = ~cellfun('isempty', (strfind(lines, 'current_coco=')));
                     if ~any(ndx)
                         ndx = length(lines) + 1;
                     end
-                    lines{ndx} = sprintf('cocodir=%s', engine_path);
+                    lines{ndx} = sprintf('current_coco=%s', engine_path);
                 else
-                    lines = {sprintf('cocodir=%s', engine_path)};
+                    lines = {sprintf('current_coco=%s', engine_path)};
                 end
                 fid = fopen(fullfile(grindpath, 'grind.cfg'), 'w');
                 fprintf(fid, '%s\n', lines{:});
@@ -498,14 +499,14 @@ classdef grind_coco < grind_cont
             end
             engine_path = '';
             if nargin < 2
-                url = 'http://content.alterra.wur.nl/webdocs/internet/aew/downloads/';
+                urls = read_grindversion;
             end
             if exist('grind.cfg', 'file')
                 fid = fopen('grind.cfg', 'r');
                 lines = textscan(fid, '%s', 'delimiter', '\n', 'whitespace', '');
                 lines = lines{1};
                 fclose(fid);
-                ndx = ~cellfun('isempty', (strfind(lines, 'cocodir=')));
+                ndx = ~cellfun('isempty', (strfind(lines, 'current_coco=')));
                 if any(ndx)
                     line = lines{ndx};
                     engine_path = regexp(line, '(?<=[=]).*', 'match', 'once');
@@ -546,42 +547,44 @@ classdef grind_coco < grind_cont
             end
             
             if ~isempty(checkupdates) && checkupdates
-                [newversion, status] = urlread([url 'cocoversion.txt']);
+                %[newversion, status] = urlread([url 'cocoversion.txt']);
+                [~, newversion] = fileparts(urls.coco_url);
                 if newversion(end) + 0 == 10
                     newversion = newversion(1:end - 1);
                 end
                 
-                if status == 1
-                    if ~isempty(engine_path)
-                        verfile = fullfile(engine_path, 'cocoversion.txt');
-                        if exist(verfile, 'file')
-                            fid = fopen(verfile, 'r');
-                            oldversion = fgetl(fid);
-                            fclose(fid);
-                        else
-                            oldversion = '';
-                        end
-                        
-                        if strcmp(oldversion, newversion)
-                            disp('No newer version of COCO (Continuation Core and Toolboxes) available');
-                            return;
-                        else
-                            if ~isempty(oldversion) || strcmp(questdlg('OK to remove old version of COCO? (recommended)', ...
-                                    'Remove coco', 'Yes', 'No', 'Yes'), 'Yes')
-                                disp('Removing old version of COCO');
-                                warning('off', 'MATLAB:RMDIR:RemovedFromPath');
-                                rmdir(engine_path, 's');
-                                warning('on', 'MATLAB:RMDIR:RemovedFromPath');
-                                oldversion = 'removed';
-                            end
-                            
-                        end
-                        
+                %if status == 1
+                if ~isempty(engine_path)
+                    [~,oldversion]=fileparts(engine_path);
+%                     verfile = fullfile(engine_path, 'cocoversion.txt');
+%                     if exist(verfile, 'file')
+%                         fid = fopen(verfile, 'r');
+%                         oldversion = fgetl(fid);
+%                         fclose(fid);
+%                     else
+%                         oldversion = '';
+%                     end
+
+                    if strcmp(oldversion, newversion)
+                        fprintf('COCO version "%s", no newer version available\n',oldversion);
+                        return;
                     else
-                        oldversion = '';
+                        if ~isempty(oldversion) || strcmp(questdlg('OK to remove old version of COCO? (recommended)',  ...
+                                'Remove coco', 'Yes', 'No', 'Yes'), 'Yes')
+                            disp('Removing old version of COCO');
+                            warning('off', 'MATLAB:RMDIR:RemovedFromPath');
+                            rmdir(engine_path, 's');
+                            warning('on', 'MATLAB:RMDIR:RemovedFromPath');
+                            oldversion = 'removed';
+                        end
+
                     end
-                    
- 
+
+                    %else
+                    %    oldversion = '';
+                    %end
+                end
+
                     if isempty(engine_path)
                         engine_path = grindpath;
                         f = strfind(engine_path, 'grind');
@@ -593,35 +596,37 @@ classdef grind_coco < grind_cont
                                 engine_path = engine_path(1:f(1) + 4);
                             end
                         end
-                        
+                    
                     else
                         f = strfind(engine_path, 'coco');
                         if ~isempty(f)
                             engine_path = engine_path(1:f(1) - 2);
                         end
-                        
-                    end
                     
-                    fprintf('Downloading %s\n', newversion)
-                    unzip([url newversion], engine_path);
-                    engine_path = fullfile(engine_path, 'coco');
-                    if ~isempty(oldversion) || ~cocofound
-                        verfile = fullfile(engine_path, 'cocoversion.txt');
-                        fid = fopen(verfile, 'w');
-                        fprintf(fid, '%s\n', newversion);
-                        fclose(fid);
                     end
+                
+                    fprintf('Downloading %s\n', newversion)
+                    unzip(urls.coco_url, engine_path);
+                    % engine_path = fullfile(engine_path, n);
+                    %if ~isempty(oldversion) || ~cocofound
+                    movefile(fullfile(engine_path, 'coco'), fullfile(engine_path, newversion));
+                    engine_path = fullfile(engine_path, newversion);
+                    %                         verfile = fullfile(engine_path, 'cocoversion.txt');
+                    %                         fid = fopen(verfile, 'w');
+                    %                         fprintf(fid, '%s\n', newversion);
+                    %                         fclose(fid);
+                    % end
                     writecfg(engine_path)
                     disp('Updated Continuation Core and Toolboxes (COCO)');
-                end
-                
-            end
+           %     end
             
+            end
+        
         end %method
     end
     methods (Access = protected) %for testing public must become private
-        
-        
+
+
         function parrange = makerange(obj, parrange, freepar)
             if nargin < 3
                 freepar = obj.settings.derived.freepars(1);
@@ -698,7 +703,7 @@ classdef grind_coco < grind_cont
                     elems = allelems(g_grind.pars{i}, siz);
                     pars = [pars , transpose(elems(:))]; %#ok<AGROW>
                 end
-                
+        
             else
                 pars = g_grind.pars;
             end
@@ -710,14 +715,14 @@ classdef grind_coco < grind_cont
             obj.settings.derived.prob = [];
             obj.settings.derived.parranges = struct('par', {}, 'range', [NaN NaN]);
         end
-        
+
         function run_point(obj, frompoint, ctype, varargin)
             global g_grind;
             %              ndx=obj.getndx('curveprops','ctype',ctype);
             %             if any(strcmp(ctype,{'F','T'}))
             %                 ctype='SN';
             %             end
-            fprintf(['\nRunning <a href="https://sourceforge.net/projects/cocotools/">COCO[%s] (Continuation Core and Toolboxes)</a> ' ...
+            fprintf(['\nRunning <a href="https://sourceforge.net/projects/cocotools/">COCO[%s] (Continuation Core and Toolboxes)</a> '  ...
                 '\n(Dankowicz, H. & Schilder, F. 2013 Recipes for Continuation. \nSIAM, Philadelphia. 584 pp.)\n'], obj.settings.derived.version);
             extract_curve_files(obj)
             if obj.settings.grind.symbolic && (isempty(g_grind.syms.Jacobian) || isempty(g_grind.syms.Jacobianp))
@@ -739,7 +744,7 @@ classdef grind_coco < grind_cont
             obj.updateprob(true);
             No = length(obj.curves) + 1;
             therunid = fullfile(grindpath, 'tmp', g_grind.odefile, int2str(No));
-            
+    
             contpar1 = obj.translatepars(obj.settings.derived.allpars(obj.settings.derived.freepars(1:npars)), obj.settings.derived.allpars);
             cocopars = obj.translatepars(obj.settings.derived.allpars(obj.settings.grind.activepars), obj.settings.derived.allpars);
             %[ode_handle, jac_handle, jacp_handle]
@@ -753,7 +758,7 @@ classdef grind_coco < grind_cont
             elseif numjacp
                 disp('Jacobianp evaluated numerically');
             end
-            
+    
             parrange = obj.makerange(obj.settings.grind.parranges1);
             findingGH = false;
             % label=obj.pointprops(frompoint.propndx).label;
@@ -772,7 +777,7 @@ classdef grind_coco < grind_cont
                             hands{4} = i_getodehandle(12, obj.settings.derived.allpars, 'numonly');
                             Jacp = hands{4}(frompoint.x0, frompoint.p0(obj.settings.grind.activepars));
                         end
-                        
+                
                         if ~any(isnan(Jacp(:)))
                             x0 = zeros(size(frompoint.x0));
                             if any(isnan((hands{2}(x0, frompoint.p0(obj.settings.grind.activepars)))))
@@ -781,7 +786,7 @@ classdef grind_coco < grind_cont
                             end
                             Jacp = hands{4}(x0, frompoint.p0(obj.settings.grind.activepars));
                         end
-                        
+                
                         if any(isnan(Jacp(:)))
                             warning('grind:conteq', 'Jacp has NaN values, removed some active parameters, alternatively you can set "symbolic" false')
                             activepars = obj.settings.grind.activepars & ~any(isnan(Jacp), 1);
@@ -817,33 +822,33 @@ classdef grind_coco < grind_cont
                 if ~isvalidrange(frompoint.x0, obj.settings.grind.stateranges)
                     error('grind:conteq', 'Cannot start continuation outside the defined range for state variables');
                 end
-                
+        
                 [data, uidx] = coco_get_func_data(obj.settings.derived.prob, 'ep', 'data', 'uidx');
                 %                    minstates=obj.settings.N0ranges(:,1);%this can become adjustable mask with minimal values (0) or NAN for state variables
                 %     maxstates=obj.settings.N0ranges(:,2);
-                obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_state_boundary', @(prob, data, u)coco_state_boundary(prob, data, u, obj.settings.grind.stateranges), data.ep_eqn, ...
+                obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_state_boundary', @(prob, data, u)coco_state_boundary(prob, data, u, obj.settings.grind.stateranges), data.ep_eqn,  ...
                     'regular', 'x.min', 'uidx', uidx);
                 obj.settings.derived.prob = coco_add_event(obj.settings.derived.prob, 'EPS', 'boundary', 'x.min', 0);
             end
-            
+    
             %run continuation problem
             %             bd3 = coco(obj.prob,runid_bif, [], contpars, makerange(obj.settings.parranges{1})); % cont toolbox arguments
-            
+    
             bd1 = coco(obj.settings.derived.prob, therunid, [], 1, contpar1, parrange); % cont toolbox arguments
             i_waitbar(1);
             %save the results in the same way as in MATCONT
-            curve = struct('freepars', obj.settings.derived.freepars(1:npars), 'ctype', ctype, 'frompoint', frompoint.id, ...
+            curve = struct('freepars', obj.settings.derived.freepars(1:npars), 'ctype', ctype, 'frompoint', frompoint.id,  ...
                 'data', [], 'color', [], 'propndx', find(obj.getndx('curveprops', 'ctype', ctype)), 'results', struct('stabil', []));
             curve.color = obj.curveprops(curve.propndx).color;
             curve.data.haslyapunov = findingGH;
             curve.data.runids = {therunid};
             curve.data.settings = obj.get('-nondefault');
             curve = obj.extract_curve_data(bd1, curve, cocopars);
-            
+    
             add_curve(obj, curve);
-            
+    
         end
-        
+
         function curve = extract_curve_data(obj, bd1, curve, cocopars)
             %replace x as it may lead to confusion;
             bd1{1, strcmp(bd1(1, :), 'x')} = 'results.x';
@@ -933,7 +938,7 @@ classdef grind_coco < grind_cont
         end
         function obj = updateprob(obj, refresh)
             global g_grind;
-            
+    
             if isempty(obj.settings.derived.prob) || refresh
                 obj.settings.derived.prob = coco_prob();
                 obj.settings.derived.prob = coco_set(obj.settings.derived.prob, 'ode', 'vectorized', strcmp(g_grind.solver.opt.Vectorized, 'on'));
@@ -942,7 +947,7 @@ classdef grind_coco < grind_cont
                 obj.settings.derived.prob = coco_set(obj.settings.derived.prob, 'corr', 'LogLevel', 1); %show results in command window
                 obj.settings.derived.prob = coco_set(obj.settings.derived.prob, 'ep', 'NSA', true, 'BTP', true); %detect neutral saddle points and Bogdanov-Takens points
             end
-            
+    
             %ueer settings:
             settings1 = eval_settings(obj);
             tbs = fieldnames(settings1);
@@ -951,36 +956,36 @@ classdef grind_coco < grind_cont
                 sett = transpose([fieldnames(settings1.(tb)), struct2cell(settings1.(tb))]);
                 obj.settings.derived.prob = coco_set(obj.settings.derived.prob, tb, sett{:});
             end
-            
-            
+    
+    
             % s = sprintf('%s(:);', obj.settings.grind.activepars{:});
             % obj.settings.p0 = full(par('-v','type','doub;e'));
         end
         function findingGH = addfuncsHB(obj)
             if obj.settings.grind.HH && (obj.settings.derived.ndim >= 4)
                 [data, uidx] = coco_get_func_data(obj.settings.derived.prob, 'ep', 'data', 'uidx');
-                obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_test_HH', @coco_test_HH, data, ...
+                obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_test_HH', @coco_test_HH, data,  ...
                     'regular', 'test.HH', 'uidx', uidx);
                 obj.settings.derived.prob = coco_add_event(obj.settings.derived.prob, 'HH', 'test.HH', 0);
             end
-            
+    
             if obj.settings.grind.FH && (obj.settings.derived.ndim >= 3)
                 [data, uidx] = coco_get_func_data(obj.settings.derived.prob, 'ep', 'data', 'uidx');
-                obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_test_FH', @coco_test_FH, data, ...
+                obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_test_FH', @coco_test_FH, data,  ...
                     'regular', 'test.FH', 'uidx', uidx);
                 obj.settings.derived.prob = coco_add_event(obj.settings.derived.prob, 'FH', 'test.FH', 0);
             end
-            
+    
             if obj.settings.grind.GH
                 findingGH = true;
                 [data, uidx] = coco_get_func_data(obj.settings.derived.prob, 'ep', 'data', 'uidx');
-                obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'lyap', i_getodehandle('coco_lyap', obj.settings.derived.allpars(obj.settings.grind.activepars)), data.ep_eqn, ...
+                obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'lyap', i_getodehandle('coco_lyap', obj.settings.derived.allpars(obj.settings.grind.activepars)), data.ep_eqn,  ...
                     'regular', 'test.L1', 'uidx', uidx);
                 obj.settings.derived.prob = coco_add_event(obj.settings.derived.prob, 'GH', 'test.L1', 0);
             end
-            
+    
         end
-        
+
         function expand_curve(obj, frompoint, ctype, backward)
             function fullcurve = append_curve(oldcurve, addedcurve)
                 fullcurve = oldcurve;
@@ -1015,14 +1020,14 @@ classdef grind_coco < grind_cont
                 %do not expand if the curve is already filling the parrange
                 return;
             end
-            
+    
             obj.updateprob(true);
             No = length(obj.curves) + 1;
             therunid = fullfile(grindpath, 'tmp', g_grind.odefile, int2str(No));
-            
+    
             contpar1 = obj.translatepars(obj.settings.derived.allpars(curve.freepars), obj.settings.derived.allpars);
             cocopars = obj.translatepars(obj.settings.derived.allpars(obj.settings.grind.activepars), obj.settings.derived.allpars);
-            
+    
             findingGH = false;
             if backward
                 obj.settings.derived.prob = coco_set(obj.settings.derived.prob, 'cont', 'PtMX', [0, obj.settings.cont.PtMX]);
@@ -1041,7 +1046,7 @@ classdef grind_coco < grind_cont
                 case 'EP'
                     %remove EP
                     obj.settings.derived.prob = ode_ep2ep(obj.settings.derived.prob, '', point0.data.runid, point0.data.labnr);
-                    
+            
                 case 'H'
                     obj.settings.derived.prob = ode_HB2HB(obj.settings.derived.prob, '', point0.data.runid, point0.data.labnr);
                     findingGH = obj.addfuncsHB;
@@ -1051,7 +1056,7 @@ classdef grind_coco < grind_cont
                     return;
             end
             bd1 = coco(obj.settings.derived.prob, therunid, [], 1, contpar1, parrange); % cont toolbox arguments
-            newcurve = struct('freepars', obj.settings.derived.freepars, 'ctype', ctype, 'frompoint', frompoint.id, ...
+            newcurve = struct('freepars', obj.settings.derived.freepars, 'ctype', ctype, 'frompoint', frompoint.id,  ...
                 'data', [], 'color', curve.color, 'propndx', find(obj.getndx('curveprops', 'ctype', ctype)), 'results', struct('stabil', []));
             i_waitbar([]);
             newcurve.data = curve.data;
@@ -1064,9 +1069,9 @@ classdef grind_coco < grind_cont
                 obj.add_curve(append_curve(curve, newcurve));
             end
         end
-        
-        
-        
+
+
+
         function [tspan, y0, options] = my_init(obj)
             global g_grind;
             han = obj.handles;
@@ -1074,7 +1079,7 @@ classdef grind_coco < grind_cont
             options = odeset('Jacobian', han(3), 'JacobianP', han(4), 'Hessians', han(5), 'HessiansP', han(6), 'Vectorized', g_grind.solver.opt.Vectorized);
             tspan = [0 10];
         end
-        
+
         function settings1 = eval_settings(obj)
             relh = obj.settings.grind.relh; %#ok<NASGU>
             if isempty(obj.settings.grind.parranges1)
@@ -1083,11 +1088,11 @@ classdef grind_coco < grind_cont
                 range = obj.settings.grind.parranges1;
                 range = abs(range(2) - range(1));
             end
-            
+    
             if isnan(range) && ~isempty(obj.settings.derived.freepars)
                 range = abs(evalin('base', obj.settings.derived.allpars{obj.settings.derived.freepars(1)}));
             end
-            
+    
             if isnan(range) || range == 0
                 range = 1; %#ok<NASGU>
             end
@@ -1133,11 +1138,11 @@ classdef grind_coco < grind_cont
                     end
                 end
             end
-            
+    
         end
-        
-        
-        
+
+
+
         function add_curve(obj, curve)
             if strcmp(curve.ctype, 'EP')
                 p0 = obj.points(obj.getndx('points', 'id', curve.frompoint)).p0;
@@ -1157,8 +1162,8 @@ classdef grind_coco < grind_cont
                 obj.curves(end + 1) = curve;
             end
         end
-        
-        
+
+
         function [point, pntndx] = create_point(obj, spoint, x0, p0)
             point = struct('id', '', 'p0', p0, 'x0', x0, 'data', spoint.data, 'propndx', []);
             if isfield(spoint, 'id')
@@ -1188,11 +1193,11 @@ classdef grind_coco < grind_cont
                 %find translation for label For instance LP->F
                 if isempty(point.propndx)
                     point = [];
-                    pntndx = - 1;
+                    pntndx = -1;
                     return;
                 end
                 lab = obj.pointprops(point.propndx).ptype;
-                
+        
                 point.id = [lab int2str(length(oldndx) + 1)];
             end
             if isfield(point, 'propndx')
@@ -1208,11 +1213,11 @@ classdef grind_coco < grind_cont
                         point.id = sprintf('H%d', length(oldndx) + 1);
                     end
             end
-            
+    
         end
-        
-        
-        
+
+
+
         function init_engine(obj, remove)
             if nargin == 1
                 remove = false;
@@ -1225,11 +1230,11 @@ classdef grind_coco < grind_cont
                 obj.settings.derived.engine_path = obj.findupdate;
             end
             cocodir = obj.settings.derived.engine_path;
-            fullpath = {fullfile(cocodir, 'core', 'toolbox'), fullfile(cocodir, 'covering', 'toolbox'), ...
-                fullfile(cocodir, 'ep', 'toolbox'), fullfile(cocodir, 'coll', 'toolbox'), ...
-                fullfile(cocodir, 'po', 'toolbox'), fullfile(cocodir, 'recipes'), ...
+            fullpath = {fullfile(cocodir, 'core', 'toolbox'), fullfile(cocodir, 'covering', 'toolbox'),  ...
+                fullfile(cocodir, 'ep', 'toolbox'), fullfile(cocodir, 'coll', 'toolbox'),  ...
+                fullfile(cocodir, 'po', 'toolbox'), fullfile(cocodir, 'recipes'),  ...
                 fullfile(cocodir, 'continex', 'toolbox')};
-            
+    
             if ~remove
                 for i = 1:length(fullpath)
                     addpath(fullpath{i});
@@ -1241,7 +1246,7 @@ classdef grind_coco < grind_cont
             end
         end
     end
-    
+
     properties (Hidden = true, Access = public)
         %Options:
         %         %name,validation,description,matcont default
@@ -1251,47 +1256,47 @@ classdef grind_coco < grind_cont
         %             'engine(e[coco|cocogrind|grind])','par(s)','par1(p)','par2(p)','parranges(n)','parranges1(n)','parranges2(n)','id0(s)','p0(n)','N0(n)',...
         %             'relh(n>0)','allpars(c)','activepars(l)','symbolic(l)','silent(l)',...
         %             'posonly(l)','N0ranges(n)','GH(l)','HH(l)','FH(l)','ngrid(i>0)'};
-        
-        cont_opt = {'h_min', '', 'Minimum step size', '0.001*relh*range'; ...
-            'h0', '', 'Initial step size', '0.01*relh*range'; ...
-            'h_max', '', 'Maximum step size', 'relh*range'; ...
-            'h_fac_min', 'n>0', 'Minimum step size adaptation factor', 0.5; ...
-            'h_fac_max', 'n>0', 'Maximum step size adaptation factor', 2; ...
-            'PtMX', 'i>0', 'Maximum number of continuation steps', 300; ...
-            'NPR', 'n', 'diagnostic output every NPR steps (default 10).', 10; ...
-            'NSV', 'n', 'save solution every NSV steps, empty is the same as NPR (default []).', ''; ...
-            'NAdapt', '', 'remesh frequency, (default 0(ep) or 1(po)).', 'defaultNAdapt'; ...
+
+        cont_opt = {'h_min', '', 'Minimum step size', '0.001*relh*range';  ...
+            'h0', '', 'Initial step size', '0.01*relh*range';  ...
+            'h_max', '', 'Maximum step size', 'relh*range';  ...
+            'h_fac_min', 'n>0', 'Minimum step size adaptation factor', 0.5;  ...
+            'h_fac_max', 'n>0', 'Maximum step size adaptation factor', 2;  ...
+            'PtMX', 'i>0', 'Maximum number of continuation steps', 300;  ...
+            'NPR', 'n', 'diagnostic output every NPR steps (default 10).', 10;  ...
+            'NSV', 'n', 'save solution every NSV steps, empty is the same as NPR (default []).', '';  ...
+            'NAdapt', '', 'remesh frequency, (default 0(ep) or 1(po)).', 'defaultNAdapt';  ...
             'RMMX', 'n', 'maximum number of remesh loops (default 10)).', 10};
-        
-        corr_opt = {'ItMX', 'i>0', 'Maximum number of iterations before step is reduced', 10; ...
-            'SubItMX', 'i>0', 'number of damping steps (default 7)', 7; ...
-            'TOL', 'n>0', 'Tolerance of Newton correction', 1e-006; ...
-            'ResTOL', 'n>0', 'converge criterion of norm of the residium	(default 1.00E-06).', 1e-006; ...
-            'NTST', 'n', 'number of mesh intervals', 50; ...
-            'NCOL', 'n>0', 'number of collocation nodes', 5; ...
-            'NTSTMN', 'n', 'minimum number of mesh intervals', 'min(NTST,5)'; ...
+
+        corr_opt = {'ItMX', 'i>0', 'Maximum number of iterations before step is reduced', 10;  ...
+            'SubItMX', 'i>0', 'number of damping steps (default 7)', 7;  ...
+            'TOL', 'n>0', 'Tolerance of Newton correction', 1e-006;  ...
+            'ResTOL', 'n>0', 'converge criterion of norm of the residium	(default 1.00E-06).', 1e-006;  ...
+            'NTST', 'n', 'number of mesh intervals', 50;  ...
+            'NCOL', 'n>0', 'number of collocation nodes', 5;  ...
+            'NTSTMN', 'n', 'minimum number of mesh intervals', 'min(NTST,5)';  ...
             'NTSTMX', 'n', 'maximum number of mesh intervals', 'max(NTST,NCOL*dim)'};
 
-        grind_opt = {'relh', 'n>0', 'Step size relative to the range of the active parameter (default 0.1).', 1; ...
-            'par1', 'p', 'first free parameter (default: '''')', ''; ...
-            'parranges1', 'n&length(n)==2', 'range for the first parameter (default: [NaN NaN])', [NaN NaN]; ...
-            'par2', 'p#E', 'second free parameter (default: '''')', ''; ...
-            'parranges2', 'n&length(n)==2', 'range for the second parameter (default: [NaN NaN])', [NaN NaN]; ...
-            'par3', 'p#E', 'third free parameter (default: '''')', ''; ...
-            'mindist', 'n>0', 'minimum distance between different special points (default: 1E-5)', 1E-5; ...
-            'stateranges', 'n', 'min/max value for each of the state variables, or one row if all are the same (default: [Nan NaN])', [NaN NaN]; ...
-            'symbolic', 'l', 'if available use the symbolic toolbox for Jacobians', true; ...
-            'activepars', 'l#c', 'indices of the active parameters (default: all 1)', true; ...
-            'GH', 'l', 'detect generalized Hopf or Bautin bifurcations (default true).', true; ...
-            'HH', 'l', 'detect Hopf-Hopf bifurcations (default true)', true; ...
+        grind_opt = {'relh', 'n>0', 'Step size relative to the range of the active parameter (default 0.1).', 1;  ...
+            'par1', 'p', 'first free parameter (default: '''')', '';  ...
+            'parranges1', 'n&length(n)==2', 'range for the first parameter (default: [NaN NaN])', [NaN NaN];  ...
+            'par2', 'p#E', 'second free parameter (default: '''')', '';  ...
+            'parranges2', 'n&length(n)==2', 'range for the second parameter (default: [NaN NaN])', [NaN NaN];  ...
+            'par3', 'p#E', 'third free parameter (default: '''')', '';  ...
+            'mindist', 'n>0', 'minimum distance between different special points (default: 1E-5)', 1E-5;  ...
+            'stateranges', 'n', 'min/max value for each of the state variables, or one row if all are the same (default: [Nan NaN])', [NaN NaN];  ...
+            'symbolic', 'l', 'if available use the symbolic toolbox for Jacobians', true;  ...
+            'activepars', 'l#c', 'indices of the active parameters (default: all 1)', true;  ...
+            'GH', 'l', 'detect generalized Hopf or Bautin bifurcations (default true).', true;  ...
+            'HH', 'l', 'detect Hopf-Hopf bifurcations (default true)', true;  ...
             'FH', 'l', 'detect fold-Hopf bifurcations (default true).', true};
-        
+
         %ctype npars args handle descr
         curveprops = struct('ctype', {}, 'npars', [], 'color', [], 'handle', [], 'descr', [])
         % id descr codim ctypes
         pointprops = struct('ptype', {}, 'label', [], 'descr', [], 'codim', [], 'ctypes', []);
-        
-        
+
+
     end
 end
 
@@ -1362,7 +1367,7 @@ function ok = isvalidrange(N0, N0ranges)
             xhigh = inf;
         end
         
-        ok = min(xlow, xhigh) > - 1e-5;
+        ok = min(xlow, xhigh) > -1e-5;
     end
 
 end
diff --git a/sys/sys2/grind_matcont.m b/sys/sys2/grind_matcont.m
index b568928eb3f6cea418056ca173a901007f7b1b23..cf2ad9cd363b1758524226941712ae2eda0bb823 100644
--- a/sys/sys2/grind_matcont.m
+++ b/sys/sys2/grind_matcont.m
@@ -959,7 +959,7 @@ classdef grind_matcont < grind_cont
             cd(oldcd);
         end
  
-        function [engine_path, matcontfile] = findupdate(checkupdates, url, ismap)
+        function [engine_path, matcontfile] = findupdate(checkupdates, urls, ismap)
             %try to find the path of matcont and writes to grind.cfg for
             %future use. If matcont is not found it is downloaded from
             %url.
@@ -987,8 +987,9 @@ classdef grind_matcont < grind_cont
                 checkupdates = []; %only update if engine is not found
             end
             engine_path = '';
-            if nargin <= 1 || isempty(url)
-                url = 'http://content.alterra.wur.nl/webdocs/internet/aew/downloads/';
+            if nargin <= 1 || isempty(urls)
+                urls=read_grindversion;
+              %  url = webread('https://sparcs-center.org/grindfiles/grindfolder.txt');
             end
             if nargin <= 2 || isempty(ismap)
                 if isempty(g_grind)
@@ -1000,12 +1001,16 @@ classdef grind_matcont < grind_cont
  
             if ismap
                 matcontfile = 'matcontm.m';
-                fileitem = 'matcontmdir=';
-                statfile = 'matcontmversion.txt';
+                [~,newversion]=fileparts(urls.matcontm_url);
+                matconturl=urls.matcontm_url;
+                fileitem = 'current_matcontm=';
+               % statfile = 'matcontmversion.txt';
             else
                 matcontfile = 'matcont.m';
-                fileitem = 'matcontdir=';
-                statfile = 'matcontversion.txt';
+                [~,newversion]=fileparts(urls.matcont_url);
+                matconturl=urls.matcont_url;
+                fileitem = 'current_matcont=';
+               % statfile = 'matcontversion.txt';
             end
             % if isempty(engine_path)||~exist(engine_path,'dir')
             if exist('grind.cfg', 'file')
@@ -1037,22 +1042,22 @@ classdef grind_matcont < grind_cont
             end
  
             if ~isempty(checkupdates) && checkupdates
-                [newversion, status] = urlread([url statfile]);
-                if newversion(end) + 0 == 10
-                    newversion = newversion(1:end - 1);
-                end
- 
-                if status == 1
-                    if ~isempty(engine_path)
+%                 [newversion, status] = urlread([url statfile]);
+%                 if newversion(end) + 0 == 10
+%                     newversion = newversion(1:end - 1);
+%                 end
+%  
+%                 if status == 1
+                     if ~isempty(engine_path)
                         if strcontains(engine_path, newversion)
                             if ismap
-                                disp('No newer version of MATCONTM available');
+                                fprintf('MATCONTM version "%s", no newer version available\n',newversion);
                             else
-                                disp('No newer version of MATCONT available');
+                                fprintf('MATCONT version "%s", no newer version available\n',newversion);
                             end
                             return;
                         end
-                    end
+                     end
  
                     engine_path = grindpath;
                     f = strfind(engine_path, 'grind');
@@ -1063,9 +1068,9 @@ classdef grind_matcont < grind_cont
                             engine_path = engine_path(1:f(1) + 4);
                         end
                     end
-                    zipfile = [newversion '.zip'];
-                    fprintf('Downloading %s\n', zipfile)
-                    unzip([url zipfile], engine_path);
+                    %zipfile = [newversion '.zip'];
+                    fprintf('Downloading %s\n', matconturl)
+                    unzip(matconturl, engine_path);
                     engine_path = fullfile(engine_path, newversion);
                     writecfg(engine_path)
                     grind_matcont.repairBugs(ismap, engine_path); %I found a bug in MATCONTM that is crucial
@@ -1074,7 +1079,7 @@ classdef grind_matcont < grind_cont
                     else
                         disp('Updated MATCONT');
                     end
-                end
+               % end
  
             end
         end
@@ -1488,7 +1493,7 @@ classdef grind_matcont < grind_cont
             if DEBUG
                 fprintf('  opt=contset;\n');
                 for i = 1:length(f)
-                    if ~isempty(sett1.(f{i}))
+                    if ~isempty(sett1.(f{i}))&&isnumeric(sett1.(f{i}))
                         fprintf('  opt=contset(opt,''%s'',%s);\n', f{i}, mat2str(sett1.(f{i})));
                     end
                 end
@@ -2122,7 +2127,7 @@ function plotjac(fid, jac, separ, func)
 
 end
 function res = DEBUG
-    res = true;
+    res = false;
 end
 function curve1 = docont(obj, curve1, args, sett1)
     global cds;
diff --git a/sys/sys2/heun.m b/sys/sys2/heun.m
index de4ce8f611a0d8d469df9fd5039ce575f422ebe3..7af6db2abac64c172875bac9809eb3de78408ab7 100644
--- a/sys/sys2/heun.m
+++ b/sys/sys2/heun.m
@@ -9,8 +9,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('heun')">commands heun</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function [tout, yout] = heun(odefunct, tspan, y0, options)
     global g_grind;
     if (nargin < 4)
@@ -35,7 +35,7 @@ function [tout, yout] = heun(odefunct, tspan, y0, options)
     if nargin < 4
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(options.OutputFcn);
diff --git a/sys/sys2/heun1.m b/sys/sys2/heun1.m
index c73b3032a2b6bc653550e437a7151d79df60a572..92f674f19d6dbdc13cdf203b25807feeed062a99 100644
--- a/sys/sys2/heun1.m
+++ b/sys/sys2/heun1.m
@@ -31,7 +31,7 @@ function [tout, yout] = heun(odefunct, tspan, y0, options)
     if nargin < 4
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(options.OutputFcn);
diff --git a/sys/sys2/i_differ.m b/sys/sys2/i_differ.m
index 306e1aff46ef52c155c9968da3c08856e9e9f0a6..18bb1bbf2364b4692cbaf0dc7771285655588af4 100644
--- a/sys/sys2/i_differ.m
+++ b/sys/sys2/i_differ.m
@@ -5,7 +5,7 @@ function [T, Y] = i_differ(odefunct, TSPAN, Y0, OPTIONS)
     if (nargin < 4)
         nonNegative = [];
     else
-        nonNegative = odeget(OPTIONS, 'NonNegative', [], 'fast');
+        nonNegative = odeget(OPTIONS, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(OPTIONS.OutputFcn);
diff --git a/sys/sys2/i_discrete_events.m b/sys/sys2/i_discrete_events.m
index b845fd42c6289b3b737c0011b42e0c60a95b5866..5813d7642d5dba945a59732a76c00d826f16ae39 100644
--- a/sys/sys2/i_discrete_events.m
+++ b/sys/sys2/i_discrete_events.m
@@ -7,7 +7,7 @@ function [T, Y] = i_discrete_events(odefunct, tspan, Y0, options)
     if (nargin < 4)
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(options.OutputFcn);
diff --git a/sys/sys2/i_grindlegend.m b/sys/sys2/i_grindlegend.m
index e79354394d22e9a833ddc169522d2df1a5ed03b0..1cd1f47e0dbb639eabd121bbe90e8d1f8d250eae 100644
--- a/sys/sys2/i_grindlegend.m
+++ b/sys/sys2/i_grindlegend.m
@@ -182,7 +182,7 @@ function pout = i_grindlegend(flag, h, par2, xtrapar)
                 s = get(ser(1), 'DisplayName');
                 s1 = get(get(h, 'ylabel'), 'string');
                 if isempty(s1)
-                    ylabel(s);
+                    ylabel(h,s);
                 end
 
             end
diff --git a/sys/sys2/i_klepperen.m b/sys/sys2/i_klepperen.m
index 2873635388a30ee67e590e3be6854f120fb4ca02..e980d10e51ead628443c2789f0942ec8b7e23809 100644
--- a/sys/sys2/i_klepperen.m
+++ b/sys/sys2/i_klepperen.m
@@ -162,6 +162,8 @@ function i_klepperen(s_matrix, vlabels, plabels, dummy_matrix, atitle, dendrpars
         nlab = length(plabels2);
         if nlab < 2
             warning('GRIND:mcarlo:dendrogram1var', 'Cannot make a dendrogram if there is only one parameter/variable');
+        elseif  ~exist('pdist','file')
+            warning('GRIND:mcarlo:dendrogram1var', 'Statistics toolbox is needed for a dendrogram');
         else
             Y = pdist(s_matrix, str2func('sinedist')); % calculate distances
             if ~all(isnan(Y))
diff --git a/sys/sys2/implicitvars.m b/sys/sys2/implicitvars.m
index 3215cf0fd80bc412c8e657aec6cf5e76798fc4ff..2a44e7222979e7fc4826ecb3cc49aad6b2d32254 100644
--- a/sys/sys2/implicitvars.m
+++ b/sys/sys2/implicitvars.m
@@ -24,8 +24,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('implicitvars')">commands implicitvars</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $
 function implicitvars(varargin)
     disp('Use this function only in a definition of a model');
 end
diff --git a/sys/sys2/langevin_eq.m b/sys/sys2/langevin_eq.m
index b14ef386cb1a8877b169ca2925711ab68117d034..2c888fa0f526bed4349f524c42c9ad9ca5f9f402 100644
--- a/sys/sys2/langevin_eq.m
+++ b/sys/sys2/langevin_eq.m
@@ -58,12 +58,17 @@ classdef langevin_eq < handle
                     domain_ = obj.domain;
                     sumpdf = integral(fun, domain_(1), domain_(2));
                     res = @(x)fun(x)/sumpdf;
+                case 'uniform'
+                    uniform_pdf = makedist('Uniform', obj.domain(1), obj.domain(2));
+                    res = @(x)uniform_pdf.pdf(x);
                 case 'normal_dom'
                     res = obj.getinitfun('normalize', @(x)exp(-(x - obj.domain(2) ./ 2).^2));
                 case 'normal'
                     mean = varargin{1};
                     std = varargin{2};
-                    res = @(x)pdf('normal',x,mean,std);
+                    normal_pdf = makedist('Normal', mean, std);
+                    normal_pdf = normal_pdf.truncate(obj.domain(1), obj.domain(2));
+                    res = @(x)normal_pdf.pdf(x);
                 case 'dirichlet'
                     x0 = varargin{1};
                     if length(varargin) > 1
@@ -189,7 +194,7 @@ classdef langevin_eq < handle
             result.pdfs = u;
 
             %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-            function [c, f, s] = pdex1pde(x, ~, u, DuDx , D1, D2, DD2)
+            function [c, f, s] = pdex1pde(x, ~, u, DuDx, D1, D2, DD2)
                 %Forward Fokker Planck:
                 %diff(P,t) = - diff (D1(x)*P(x,t),x) + diff(diff(D2(x)*P(x,t),x),x)
                 %
@@ -311,24 +316,24 @@ classdef langevin_eq < handle
                         if ~exist('fittype', 'file')
                             error('langevin_eq:toolboxmissing', 'The curvefitting toolbox is required for the ''weightedspline'' option')
                         end
-                        ft = fittype( 'smoothingspline' );
+                        ft = fittype('smoothingspline');
                         if all(results.ErrorD1 == 0)
                             w1 = ones(size(results.ErrorD1));
                         else
                             w1 = 1 ./ results.ErrorD1;
                         end
-                        [xData, yData, weights1] = prepareCurveData(results.C, results.D1, w1 );
-                        opts = fitoptions( 'Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1);
-                        [d1, results.gofD1] = fit( xData, yData, ft, opts );
+                        [xData, yData, weights1] = prepareCurveData(results.C, results.D1, w1);
+                        opts = fitoptions('Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1);
+                        [d1, results.gofD1] = fit(xData, yData, ft, opts);
                         if all(results.ErrorD2 == 0)
                             w2 = ones(size(results.ErrorD1));
                         else
                             w2 = 1 ./ results.ErrorD2;
                         end
                         w2(results.D2 - results.ErrorD2 <= 0) = 0; %I assign 0 weight to the very few bins for D2 when D2<0
-                        [xData, yData, weights1] = prepareCurveData(results.C, results.D2, w2 );
-                        opts = fitoptions( 'Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1);
-                        [d2, results.gofD2] = fit( xData, yData, ft, opts );
+                        [xData, yData, weights1] = prepareCurveData(results.C, results.D2, w2);
+                        opts = fitoptions('Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1);
+                        [d2, results.gofD2] = fit(xData, yData, ft, opts);
                         if exist('chebfun', 'file') && ~any(strcmp(options, 'nocheb'))
                             l = linspace(L1, R1, 2^13);
                             D1 = chebfun(d1(l), [L1 R1], 'equi', 5000);
@@ -349,6 +354,22 @@ classdef langevin_eq < handle
                         end
                     end
                     obj.xtra.reconstr = results;
+                elseif nargin == 1 &&  isfield(varargin{1}, 'mufun') && isfield(varargin{1}, 'sigmafun')
+                    %results of euler_reconstruction or
+                    %hermite_reconstruction
+                    results=varargin{1};
+                    pars=results.estimated_par;
+                    d1=@(x)results.mufun(x,pars);
+                    d2=@(x)0.5*results.sigmafun(x,pars).^2;
+                    L=results.options.l;
+                    R=results.options.r;
+                    if isempty(L)
+                        L=results.datarange(1);
+                    end
+                    if isempty(R)
+                        R=results.datarange(2);
+                    end
+                    obj.set('D1', d1, 'D2', d2, 'domain', [L R]);
                 elseif nargin == 2 && ~ischar(varargin{1})
                     %2 default arguments D1 and D2
                     obj.set('D1', varargin{1}, 'D2', varargin{2});
@@ -490,7 +511,7 @@ classdef langevin_eq < handle
             if ~isfield(args, 'simuldata')
                 disp('Simulating');
                 sizedata = numel(data);
-                [simuldata, fcn] = obj.simulate( linspace(0, (sizedata - 1) * args.dt, sizedata)', obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative));
+                [simuldata, fcn] = obj.simulate(linspace(0, (sizedata - 1) * args.dt, sizedata)', obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative));
                 res.simuldata = fcn;
                 simuldatat = simuldata.t;
                 simuldata = simuldata.y;
@@ -599,7 +620,7 @@ classdef langevin_eq < handle
             res.mesh = linspace(args.domain(1), args.domain(2), args.nmesh);
             [res.datadistr, res.sizes] = getdistrib(data1, stepdata);
             disp('Simulating');
-            [simuldata, fcn] = obj.simulate( linspace(0, (sizedata - 1) * args.dt, sizedata)', ...
+            [simuldata, fcn] = obj.simulate(linspace(0, (sizedata - 1) * args.dt, sizedata)',  ...
                 obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative));
             res.simuldata = fcn;
             simuldata1 = simuldata.y(args.nstep + 1:end, :);
@@ -846,6 +867,7 @@ classdef langevin_eq < handle
             %     'D1'            plot the drift function
             %     'D2'            plot the diffusion function
             %     'DD2'           plot the derivative of the diffusion function
+            %     'D4'            D4 plot
             %     'equilibria'    plot the equilibria in the D1 plot
             %     'exit_distrib'  plot the probability density function of
             %                     exit times for a certain initial state
@@ -946,7 +968,12 @@ classdef langevin_eq < handle
                                 x = obj.DD2;
                             end
                         elseif strcmp(varargin{1}, 'D4')
-                            x = griddedInterpolant(obj.xtra.reconstr.C, obj.xtra.reconstr.D4, 'spline');
+                            if ~isfield(obj.xtra,'reconstr')
+                                disp('Cannot plot "D4" as the model is not from reconstructed data from LangevinReconst');
+                                return;
+                            else
+                                x = griddedInterpolant(obj.xtra.reconstr.C, obj.xtra.reconstr.D4, 'spline');
+                            end
                         end
                         %                         ploterror=true;
                         %                         ts=1;
@@ -1030,7 +1057,7 @@ classdef langevin_eq < handle
                                 hax1 = xline(obj.equilibria(unstableeqs(i)).x, 'k--');
                             catch
                                 %older versions of matlab do not have xline
-                                ylim1=get(gca,'ylim');
+                                ylim1 = get(gca, 'ylim');
                                 plot(obj.equilibria(unstableeqs(i)).x + zeros(1, 2), ylim1, 'k--')
                             end
                         end
@@ -1042,7 +1069,7 @@ classdef langevin_eq < handle
                         if ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdf')
                             obj.pdf;
                         end
-                        hax1 = obj.plot(obj.xtra.results.pdf);
+                        hax1 = obj.plot(obj.xtra.results.pdf, args{:});
                     case 'survival'
                         hold on
                         if nargin > 2 || ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'survival')
@@ -1054,9 +1081,9 @@ classdef langevin_eq < handle
                             result = args{1};
                         else
                             if nargin == 2 && ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdfs')
-                                obj.pdfs;
+                                obj.pdf;
                             end
-                            result = obj.xtra.results.pdfs;
+                            result = obj.xtra.results.pdf;
                         end
                         nt = size(result.pdfs, 1);
                         result.t = result.t(1:nt);
@@ -1114,7 +1141,11 @@ classdef langevin_eq < handle
                         end
                     case {'survival_func', 'exit_distrib'} %args1 is x0 args2 = survival results
                         hold on
-                        x0 = args{1};
+                        if isempty(args)
+                            x0=0.01;
+                        else
+                            x0 = args{1};
+                        end
                         if (length(args) < 2) || ~(isstruct(args{2}) || iscell(args{2}))
                             if isfield(obj.xtra, 'results') && isfield(obj.xtra.results, 'survival')
                                 results = obj.xtra.results.survival;
@@ -1196,6 +1227,8 @@ classdef langevin_eq < handle
                         plot(stab, zeros(size(stab)), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', 'k');
                         hold on
                         hax1 = plot(unstab, zeros(size(unstab)), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', [1 1 1]);
+                    otherwise
+                        error('plotting command "%s" not recognized, valid commands are: ''basinprob'', ''D1'', ''D2'', ''DD2'', ''D4'', ''equilibria'', ''exit_distrib'', ''exitprob'', ''mean_exit'', ''pdf'', ''potential'', ''potential_eff'', ''survival'', ''survival_func'', ''vertical_basin_boundaries''',varargin{1}); 
                 end
             else
                 result = varargin{1};
@@ -1242,24 +1275,55 @@ classdef langevin_eq < handle
                     if ~isfield(args, 'verticalbar') || args.verticalbar
                         obj.plot('vertical_basin_boundaries');
                     end
-                elseif isfield(result, 'PDF') || isfield(result, 'pdfs') %pdf    
+                elseif isfield(result, 'PDF') || isfield(result, 'pdfs') %pdf
                     if isfield(args, 't')
                         t = args.t;
                     else
                         t = result.t(end);
                     end
-                    hax1 = findobj(get(0, 'currentfigure'), 'tag', 'pdfs');
+                    hfig = get(0, 'currentfigure');
+                    hax1 = findobj(hfig, 'tag', 'pdfs');
                     if ~isempty(hax1)
                         updatefig = true;
                     else
                         updatefig = false;
                     end
-                    it = find(result.t >= t, 1);
-                    if isempty(it)
-                        it = length(result.t);
+                    if isfield(args, 'movie') && args.movie
+                        maxt = size(result.pdfs, 1);
+                        F = getframe(gca);
+                        htext = [];
+                        for i = 1:maxt
+                            hax = obj.plot(result, 'ndxt', i);
+                            if isempty(htext)
+                                htext = text(0.9, 0.9, '', 'Units', 'Normalized', 'tag', 'ttext');
+                            end
+                            set(htext, 'string', sprintf('t=%d', round(result.t(i))));
+                            F(i) = getframe(gcf);
+                        end
+                        ud = get(hfig, 'userdata');
+                        ud.frames = F;
+                        set(hfig, 'userdata', ud);
+                        h = findobj(hfig, 'tag', 'moviemenu');
+                        if isempty(h)
+                            h = uimenu(hfig, 'Text', '&Movie', 'tag', 'moviemenu');
+                            uimenu(h, 'Text', '&Replay', 'MenuSelectedFcn', @movie_callback);
+                            uimenu(h, 'Text', '&Save as mp4', 'MenuSelectedFcn', @save_movie_callback);
+                        end
+                        if isfield(args, 'mp4file')
+                            save_themovie(args.mp4file, ud.frames);
+                        end
+                        return;
+                    end
+                    if isfield(args, 'ndxt')
+                        ndxt = args.ndxt;
+                    else
+                        ndxt = find(result.t >= t, 1);
+                    end
+                    if isempty(ndxt)
+                        ndxt = length(result.t);
                     end
 
-                    if (it == length(result.t)) && isfield(result, 'PDF')
+                    if (ndxt == length(result.t)) && isfield(result, 'PDF')
                         if updatefig
                             set(hax1, 'YData', [result.PDF, 0 0]);
                         else
@@ -1267,9 +1331,9 @@ classdef langevin_eq < handle
                         end
                     else
                         if updatefig
-                            set(hax1, 'YData', [result.pdfs(it, :), 0 0]);
+                            set(hax1, 'YData', [result.pdfs(ndxt, :), 0 0]);
                         else
-                            hax1 = fill([result.x result.x(end) result.x(1)], [result.pdfs(it, :), 0 0], [0.75 0.75 1]);
+                            hax1 = fill([result.x result.x(end) result.x(1)], [result.pdfs(ndxt, :), 0 0], [0.75 0.75 1]);
                         end
                     end
                     xlim(obj.domain);
@@ -1289,7 +1353,7 @@ classdef langevin_eq < handle
                     ylabel(obj.namex);
                 elseif isfield(result, 'survival') %survival
                     [x, y] = meshgrid(result.x, result.t);
-                    colormap( [linspace(1, 0.5, 50)', linspace(1, 0.5, 50)', ones(50, 1)]);
+                    colormap([linspace(1, 0.5, 50)', linspace(1, 0.5, 50)', ones(50, 1)]);
                     [~, hax1] = contourf(x, y, result.survival, 100);
                     set(hax1, 'LineColor', 'none')
                     hold on
@@ -1602,7 +1666,7 @@ classdef langevin_eq < handle
                     LL.rbc = @(T)T;
                 end
                 %solving T
-                res.T = solvebvp(LL , -1);
+                res.T = solvebvp(LL, -1);
                 T2 = chebfun(res.T, domain2);
                 if ~isempty(PDF)
                     res.WT = sum(PDF * T2) / sum(PDF);
@@ -1618,7 +1682,7 @@ classdef langevin_eq < handle
                     LL.lbc = @(T)T;
                     LL.rbc = @(T)T;
                     % T = LL \ (-res1.P_left);
-                    [T, sol] = solvebvp(LL , -res1.P_left);
+                    [T, sol] = solvebvp(LL, -res1.P_left);
                     if sol.error > 0.001
                         xpoints = linspace(domain_(1), domain_(2), 200);
                         P_l = griddedInterpolant(xpoints, res1.P_left(xpoints));
@@ -1645,7 +1709,7 @@ classdef langevin_eq < handle
                     LL.lbc = @(T)T;
                     LL.rbc = @(T)T;
                     %T = LL \ (- res1.P_right);
-                    [T, sol] = solvebvp(LL , -res1.P_right);
+                    [T, sol] = solvebvp(LL, -res1.P_right);
                     if sol.error > 0.001
                         xpoints = linspace(domain_(1), domain_(2), 200);
                         P_l = griddedInterpolant(xpoints, res1.P_right(xpoints));
@@ -1662,9 +1726,9 @@ classdef langevin_eq < handle
 
                     T2 = chebfun(res.T_right, domain2, 'splitting', 'on');
                     if ~isempty(PDF)
-                        res.WT_right = [];
-                    else
                         res.WT_right = sum(PDF * T2) / sum(PDF);
+                    else
+                        res.WT_right = [];                        
                     end
                     res.P_right = res1.P_right;
                 end
@@ -1789,8 +1853,16 @@ classdef langevin_eq < handle
             % or a scalar number (Dirichlet delta function is then assumed).
             %
             % 
-            % options (optional) the pdepe options (see pdepe, for instance RelTol and AbsTol)
+            % options (optional) the pdepe options:
+            %(see pdepe, for instance RelTol and AbsTol)
+            %    RelTol
+            %    AbsTol
+            %    NormControl
+            %    InitialStep
+            %    MaxStep
+            %    Events
             %  + additional fields:
+            %    BC boundary conditions RR AR RA AA
             %    maxtime = duration of the simulation
             %    ntime = number of time outputs (minimal=3) (default 3)
             %    nx = number of points in x direction (default obj.nx)
@@ -1806,6 +1878,7 @@ classdef langevin_eq < handle
             if nargin < 2
                 pdf0 = [];
             end
+            %
             if nargin > 3
                 options = struct(varargin{:});
             elseif nargin == 3
@@ -1813,6 +1886,14 @@ classdef langevin_eq < handle
             else
                 options = [];
             end
+            if ~isempty(options)
+                f = fieldnames(options);
+                validoptions = {'RelTol', 'AbsTol', 'NormControl', 'InitialStep', 'MaxStep', 'Events', 'maxtime', 'ntime', 'nx', 'BC'};
+                if any(~ismember(f, validoptions))
+                    s = sprintf('''%s'' ', validoptions{:});
+                    error('langevin_eq:pdf', 'Cannot run pdf as some options are unknown\nValid options are: %s', s(1:end - 1));
+                end
+            end
             if ~isfield(options, 'maxtime')
                 options.maxtime = 4000;
             end
@@ -1949,7 +2030,7 @@ classdef langevin_eq < handle
                 case 'RR'
                     BCfun = @(~, ~ , ~, ~, ~)deal(0, 1, 0, 1);
                 otherwise
-                    error('langevin_eq:bc', 'boundary conditions "%s" undefined',eqn.BC);
+                    error('langevin_eq:bc', 'boundary conditions "%s" undefined', eqn.BC);
             end
             if ~isfield(options, 'Stats')
                 options.Stats = 'on';
@@ -2112,7 +2193,7 @@ function [tout, yout] = euler(odefunct, tspan, y0, options)
     if nargin < 4
         nonNegative = [];
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
     end
     anyNonNegative = ~isempty(nonNegative);
     haveOutputFcn = ~isempty(options.OutputFcn);
@@ -2302,5 +2383,28 @@ function res = simulate_rng(randseed, odefun, tspan, y0, options)
     [res.t, res.y] = euler(odefun, tspan, y0, options);
 end
 
+function movie_callback(h, ~, ~)
+    hfig = get(get(h, 'parent'), 'parent');
+    ud = get(hfig, 'userdata');
+    % h = findobj(hfig, 'tag', 'pdfs');
+    %drawnow;
+    movie(hfig, ud.frames);
+end
+function save_movie_callback(h, ~, ~)
+    hfig = get(get(h, 'parent'), 'parent');
+    ud = get(hfig, 'userdata');
+    [afile, apath] = uiputfile('video.mp4');
+    cd(apath);
+    save_themovie(afile, ud.frames);
+ 
+end
+
+function save_themovie(afile, frames)
+    v = VideoWriter(afile, 'MPEG-4');
+    open(v)
+    writeVideo(v, frames);
+    close(v)
+    fprintf('written to %s\n', afile)
+end
 
 % -------------------------------------------------------------------------
diff --git a/sys/sys2/langevin_eq_old.m b/sys/sys2/langevin_eq_old.m
new file mode 100644
index 0000000000000000000000000000000000000000..ff1082f7e63191feeb176768ae73c917995f09bf
--- /dev/null
+++ b/sys/sys2/langevin_eq_old.m
@@ -0,0 +1,2306 @@
+classdef langevin_eq < handle
+    %This class is used to analyze a reconstructed Langevin equation. It is
+    %especially suitable for discretized D1 and D2 functions.
+    %When you use smooth functions they are also descretized
+    %Use this class to calculate/plot the propeties of the Langevin
+    %equation:
+    %Main methods:
+    %   plot: used to plot the results
+    %   pdf: calculated the stationary pdf
+    %   mean_exit: calculates the mean exit time for all initial conditions
+    %       of a domain
+    %   survival: calculates the survival function for all initial
+    %       conditions
+    %   potential: the potential function based on D1
+    %   potential_eff: the effective potential function, includes effects of
+    %   D2
+    %
+    %Optionally, it uses chebfun: 
+    %   Driscoll, T. A., N. Hale, and L. N. Trefethen. 2014. Chebfun Guide. Pafnuty Publication, Oxford.
+    %
+    properties
+        D1 = []; %drift
+        D2 = []; %diffusion
+        DD2 = []; %derivative of diffusion
+        equilibria = struct('x', {}, 'stable', false, 'BC', '', 'domain', []); %list of equilibria
+        % x= state variable, stable = logical variable true if stable, BC boundary conditons RA AA AR or RR, 
+        % domain - the basin of attraction of stable equilibrium, outer borders are -Inf Inf
+        xtra %struct with extra information, for instance last results and reconstr information
+        nx = 100; %default number of x for Fokker-Planck equations
+        domain = [0 10]; %domain of the Langevin equation
+        namex = 'x' %name of the x coordinate for plotting
+        timeunit = ''; %time unit for plotting
+    end
+    methods
+        function res = getinitfun(obj, atype, varargin)
+            %  get an initial function for pdepe/bvp5v:
+            %  usage:
+            %  obj.getinitfun('normal_dom') - for runpde
+            %  obj.getinitfun('normal',mean,std) - for runpde
+            %  obj.getinitfun('dirichlet',x0) - for runpde
+            %  obj.getinitfun('cosine',BC) - for mean_exit
+   
+            function u0 = dirichlet_delta_ic(x0, meshx) %vectorized
+                dx = meshx(2) - meshx(1);
+                [~, ix0] = min(abs(meshx - x0));
+                u0 = zeros(size(meshx));
+                ndx = abs(meshx - x0) < dx / 2 | (abs(meshx - x0) == dx / 2 & meshx > x0);
+                u0(ndx) = 1 / dx;
+                if ix0 == 1 || ix0 == length(meshx)
+                    u0 = u0 * 2;
+                end
+            end
+            %initial sine, make sure that the BC are correct
+            %initfun = @(x)[cos(4 * x), -4 * sin(4 * x) ]   ;
+            switch atype
+                case 'normalize'
+                    fun = varargin{1};
+                    domain_ = obj.domain;
+                    sumpdf = integral(fun, domain_(1), domain_(2));
+                    res = @(x)fun(x)/sumpdf;
+                case 'normal_dom'
+                    res = obj.getinitfun('normalize', @(x)exp(-(x - obj.domain(2) ./ 2).^2));
+                case 'normal'
+                    mean = varargin{1};
+                    std = varargin{2};
+                    res = @(x)pdf('normal',x,mean,std);
+                case 'dirichlet'
+                    x0 = varargin{1};
+                    if length(varargin) > 1
+                        meshx = varargin{2};
+                    else
+                        meshx = linspace(obj.domain(1), obj.domain(2), obj.nx);
+                    end
+                    u0 = dirichlet_delta_ic(x0, meshx);
+                    interpolant = griddedInterpolant(meshx, u0);
+                    res = @(x)interpolant(x);
+                    % res = @(x)dirichlet_delta_ic(x, x0, meshx);
+                case 'cosine;sine' %for mean_exit
+                    % BC the boundary value code:
+                    %  'AA' = left and right absorbing
+                    %  'RA' = left reflecting and right absorbing
+                    %  'AR' = left absorbing and right reflecting
+                    domain_ = obj.domain;
+                    BC = varargin{1};
+                    starth = 0;
+                    endh = 2 * pi;
+                    if BC(1) == 'R'
+                        %start at pi/2 to have correct BC
+                        starth = starth + pi / 2;
+                    end
+                    if BC(2) == 'R'
+                        %start at pi/2 to have correct BC
+                        endh = endh + pi / 2;
+                    end
+                    per = (endh - starth) / (domain_(2) - domain_(1));
+                    res = @(x)[cos(per * (x-domain_(1))+starth); -per * sin(per * (x-domain_(1))+starth) ];
+            end
+        end
+
+    end
+    methods (Access = protected)
+        function result = solvepdf(obj, pdf0, varargin)
+            %solve pdfs
+            %used both by pdf and by runpdf
+            if isempty(obj.D1) || isempty(obj.D2)
+                error('langevin_eq:nomodel', 'No Langevin equation defined');
+            end
+            if nargin > 2 && ischar(pdf0)
+                varargin = [{pdf0} varargin];
+                pdf0 = [];
+            end
+            if nargin < 2 || isempty(pdf0)
+                if isa(obj.D1, 'chebfun')
+                    pdf0 = chebfun(@(x)exp(-(x - obj.domain(2) / 2)^2), obj.domain, 'vectorize');
+                    pdf0 = pdf0 / sum(pdf0);
+                else
+                    pdf0 = obj.getinitfun('normal_dom');
+                end
+            end
+            if length(varargin) > 1
+                options = struct(varargin{:});
+            elseif length(varargin) == 1
+                options = varargin{1};
+            else
+                options = [];
+            end
+            if ~isfield(options, 'maxtime')
+                options.maxtime = 1000;
+            end
+            if ~isfield(options, 'ntime')
+                options.ntime = 1000;
+            end
+            if ~isfield(options, 'nx')
+                options.nx = obj.nx;
+            end
+
+            L = min(obj.domain);
+            R = max(obj.domain);
+            m = 0;
+            result.t = linspace(0, options.maxtime, options.ntime);
+            x = linspace(L, R, options.nx);
+            % Mesh = x;
+            if isnumeric(pdf0) && length(pdf0) == 1
+                pdf0 = obj.getinitfun('dirichlet', pdf0, x);
+                if isa(obj.D1, 'chebfun')
+                    pdf0 = chebfun(pdf0, obj.domain, 'vectorize');
+                end
+            end
+            if isempty(obj.DD2)
+                DD2_ = diff_fun(obj.D2);
+            else
+                DD2_ = obj.DD2;
+            end
+            %we bind the D1 D2 and DD2 functions to this anonymous function
+            if isa(obj.D1, 'chebfun')
+                %using chebfuns is 100x slower, griddedInterpolant are really
+                %efficient
+                x1 = linspace(L, R, options.nx * 1000); %more points for precision
+                d1 = griddedInterpolant(x1, obj.D1(x1));
+                d2 = griddedInterpolant(x1, obj.D2(x1));
+                dd2 = griddedInterpolant(x1, DD2_(x1));
+                fp_equat = @(x,t,u,DuDx)pdex1pde(x, 0, u, DuDx ,d1,d2,dd2);
+            else
+                fp_equat = @(x,t,u,DuDx)pdex1pde(x, 0, u, DuDx ,obj.D1, obj.D2, DD2_);
+            end
+            if ~isfield(options, 'RelTol') || isempty(options.RelTol)
+                options.RelTol = 1E-3;
+            end
+            if ~isfield(options, 'AbsTol') || isempty(options.AbsTol)
+                options.AbsTol = 1E-4;
+            end
+            if ~isfield(options, 'BC') || isempty(options.BC)
+                options.BC = 'RR';
+            end
+            switch options.BC
+                case 'AA'
+                    pdebc = @(~, ul, ~, ur, ~)deal(ul,0,ur,0);
+                case 'AR'
+                    pdebc = @(~, ul, ~, ~, ~)deal(ul,0,0,1);
+                case 'RA'
+                    pdebc = @(~, ~, ~, ur, ~)deal(0,1,ur,0);
+                otherwise %default RR
+                    pdebc = @(varargin)deal(0,1,0,1); %border conditions; pl, ql pr qr
+            end
+            sol = pdepe(m, fp_equat, pdf0, pdebc, x, result.t, options);
+            % sol = pdepe(m,@pdex1pde,@pdex1ic,@pdex1bc,x,t);
+            u = sol(:, :, 1);
+            result.x = x;
+            result.pdfs = u;
+
+            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+            function [c, f, s] = pdex1pde(x, ~, u, DuDx , D1, D2, DD2)
+                %Forward Fokker Planck:
+                %diff(P,t) = - diff (D1(x)*P(x,t),x) + diff(diff(D2(x)*P(x,t),x),x)
+                %
+                %general form for pdepe (see Matlab help)
+                %c(x,t,u,dudx)*diff(u,t) = x^m * diff(x^m * f(x,t,u,dudx),x) + s(x,t,u,dudx)
+                %
+                %we need work out our double integral as that is not in pdepe (we define DD2= d(D2)/dx)
+                %product rule: diff(D2(x)*P(x,t),x)= DD2 * P + D2 * dPdx
+                %so our reworked equation is
+                %diff(P,t) = diff (-D1 * P + DD2 * P + D2 * dPdx,x)
+                %
+                %this means we loose some terms:
+                %m=0: c=1: s=0
+                % keeping only:
+                %diff(u,t) = diff(f,x)
+                %where
+                %f =-D1*P + DD2 * P + D2 * dPdx
+                %   
+                c = 1;
+                f = -D1(x) .* u + DD2(x) .* u + D2(x) .* DuDx;
+                s = 0;
+            end
+        end
+        function [res, isconstant] = set_Dfun(obj, Dfun, avar)
+            if nargin < 3
+                avar = '';
+            end
+            isconstant = false;
+            res = Dfun;
+            if isa(Dfun, 'chebfun')
+                obj.domain = Dfun.domain;
+                if strcmp(avar, 'g')
+                    res = 0.5 * res^2;
+                end
+            elseif ischar(Dfun)
+                val = str2double(Dfun);
+                if ~isnan(val)
+                    [res, isconstant] = obj.set_Dfun(val, avar);
+                    return;
+                else
+                    [res, isconstant] = obj.set_Dfun(evalin('base', sprintf('@(%s)%s', obj.namex, Dfun)), avar);
+                end
+            elseif isnumeric(Dfun) && numel(Dfun) == 1
+                isconstant = true;
+                if strcmp(avar, 'g')
+                    res = @(x)0.5*Dfun^2+zeros(size(x));
+                else
+                    res = @(x)Dfun+zeros(size(x));
+                end
+            elseif isa(Dfun, 'function_handle')
+                try
+                    if strcmp(avar, 'g')
+                        Dfun = @(x)0.5*Dfun(x).^2;
+                    end
+                    %test whether the function is in vector notation or
+                    %returning a constant.
+                    s1 = Dfun(1:10);
+                    if numel(s1) == 1
+                        %constant
+                        isconstant = true;
+                        res = @(x)Dfun(x)+zeros(size(x));
+                    elseif numel(s1) ~= 10
+                        %wrong size of resultr
+                        res = @(x)simulate_vector(Dfun,x);
+                    else
+                        res = Dfun;
+                    end
+                catch err
+                    %no vector notation supported, but simulate a
+                    %vector
+                    if strcmp(err.identifier, 'MATLAB:innerdim')
+                        res = @(x)simulate_vector(Dfun,x);
+                    end
+                end
+            end
+        end
+    end
+    
+    methods
+        function obj = langevin_eq(varargin)
+            %if chebfun is on the search path it will be used for the
+            %functions (except if option 'nocheb' is used)
+            %
+            %obj = langevin_eq(res,'weightedspline') - where res is
+            %the result of the function LangevinReconst, 'weightedspline'
+            %fits a spline while weighing down points that are uncertain.
+            %is the default if the curvefitting toolbox is present (else
+            %spline)
+            %obj = langevin_eq(res,'spline') - uses standard spline
+            %interpolation (not recommended)
+            %obj = langevin_eq(res,'weightedspline','nocheb') - do not use
+            %chebfun functions
+            %
+            %obj = langevin_eq('D1',@func1,'D2',@funct2,'domain',[min
+            %max]) - function handle mode of this class, give
+            %function handles for D1 and D2
+            %D2 can also be a constant (just enter a numeric value)
+            %
+            if nargin > 0
+                ndx = cellfun(@ischar, varargin);
+                options = varargin(ndx);
+                if nargin > 0 && isfield(varargin{1}, 'ErrorD2') %result of LangevinReconst
+                    %splining the D1 and D2 functions determined with the Langevin Approach
+                    %(aka Langevin Reconstruction)
+                    results = varargin{1};
+                    if ~isfield(results, 'options')
+                        results.options = options;
+                    end
+                    if isfield(results, 'bootstrap')
+                        obj.xtra.bootstrap = results.bootstrap;
+                        results = rmfield(results, 'bootstrap');
+                    end
+                    L1 = results.C(1);
+                    R1 = results.C(end);
+                    %reconstructed Langevin equation
+                    if ((nargin == 1 && exist('fittype', 'file')) || any(strcmp(options, 'weightedspline')))
+                        %weighted spline fitting  Weighing down of
+                        %uncertain points
+                        if ~exist('fittype', 'file')
+                            error('langevin_eq:toolboxmissing', 'The curvefitting toolbox is required for the ''weightedspline'' option')
+                        end
+                        ft = fittype( 'smoothingspline' );
+                        if all(results.ErrorD1 == 0)
+                            w1 = ones(size(results.ErrorD1));
+                        else
+                            w1 = 1 ./ results.ErrorD1;
+                        end
+                        [xData, yData, weights1] = prepareCurveData(results.C, results.D1, w1 );
+                        opts = fitoptions( 'Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1);
+                        [d1, results.gofD1] = fit( xData, yData, ft, opts );
+                        if all(results.ErrorD2 == 0)
+                            w2 = ones(size(results.ErrorD1));
+                        else
+                            w2 = 1 ./ results.ErrorD2;
+                        end
+                        w2(results.D2 - results.ErrorD2 <= 0) = 0; %I assign 0 weight to the very few bins for D2 when D2<0
+                        [xData, yData, weights1] = prepareCurveData(results.C, results.D2, w2 );
+                        opts = fitoptions( 'Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1);
+                        [d2, results.gofD2] = fit( xData, yData, ft, opts );
+                        if exist('chebfun', 'file') && ~any(strcmp(options, 'nocheb'))
+                            l = linspace(L1, R1, 2^13);
+                            D1 = chebfun(d1(l), [L1 R1], 'equi', 5000);
+                            D2 = chebfun(d2(l), [L1 R1], 'equi', 5000);
+                            obj.set('D1', D1, 'D2', D2);
+                        else
+                            obj.set('D1', @(x)reshape(d1(x),size(x)), 'D2', @(x)reshape(d2(x),size(x)), 'domain', [L1 R1]);
+                        end
+                    elseif nargin == 1 || any(strcmp(options, 'spline')) %default if curvefitting toolbox is missing
+                        d1 = griddedInterpolant(results.C, results.D1, 'spline');
+                        d2 = griddedInterpolant(results.C, results.D2, 'spline');
+                        if exist('chebfun', 'file') && ~any(strcmp(options, 'nocheb'))
+                            D1 = chebfun(@(x)d1(x), [L1 R1]);
+                            D2 = chebfun(@(x)d2(x), [L1 R1]);
+                            obj.set('D1', D1, 'D2', D2);
+                        else
+                            obj.set('D1', @(x)d1(x), 'D2', @(x)d2(x), 'domain', [L1 R1]);
+                        end
+                    end
+                    obj.xtra.reconstr = results;
+                elseif nargin == 2 && ~ischar(varargin{1})
+                    %2 default arguments D1 and D2
+                    obj.set('D1', varargin{1}, 'D2', varargin{2});
+                else
+                    obj.set(varargin{:});
+                end
+                if isempty(obj.equilibria)
+                    obj.equilibria = obj.find_equilibria('deterministic'); %can be changed to 'effective' if you use ueff
+                end
+            end
+        end
+        
+        function res = simple_stoch_exit(obj, data, varargin)
+            %one-step (or n-step) conditional distribution 
+            %default nstep=1
+            %
+ 
+            function res = SojournTimes(data, dt, stable_equilibrium, width)
+                repelor = stable_equilibrium.domain(~isinf(stable_equilibrium.domain));
+                if numel(repelor) > 1
+                    error('not yet implemented');
+                end
+                res.periods_in = cell(size(data, 2), 1);
+                for m = 1:size(data, 2)
+                    s = [];
+                    data1 = data(:, m);
+                    if stable_equilibrium.x < repelor
+                        T = 0;
+                        %discard the first part of the time series if we start below the
+                        %stable equilibrium
+                        Idx = find(data1 > stable_equilibrium.x - width, 1);
+                        if Idx > 1
+                            Idx = Idx - 1;
+                        end
+                        data1 = data1(Idx:end);
+                        while ~isempty(T)
+                            Idx = find(data1 < stable_equilibrium.x + width, 1);
+                            %Idx=find(data>e-width & data<e+width,1);
+                            data1 = data1(Idx:end);
+                            T = find(data1 > repelor, 1);
+                            if ~isempty(T)
+                                s = [s T];
+                                data1 = data1(T:end);
+                            end
+                        end
+                    else
+                        T = 0;
+                        %discard the first part of the time series if we start above the
+                        %stable equilibrium
+                        Idx = find(data1 < stable_equilibrium.x + width, 1);
+                        if Idx > 1
+                            Idx = Idx - 1;
+                        end
+                        data1 = data1(Idx:end);
+                        while ~isempty(T)
+                            Idx = find(data1 > stable_equilibrium.x - width, 1);
+                            %Idx=find(data>e-width & data<e+width,1);
+                            data1 = data1(Idx:end);
+                            T = find(data1 < repelor, 1);
+                            if ~isempty(T)
+                                s = [s T];
+                                data1 = data1(T:end);
+                            end
+                        end
+                    end
+                    res.periods_in{m} = s .* dt;
+                end
+                if size(data, 2) == 1
+                    res.periods_in = res.periods_in{m};
+                end
+                res.equilibrium = stable_equilibrium;
+            end
+ 
+            %             function res = direct_exit(datat, datax, domain)
+            %                 %simple way of determining exit time from data or simulations:
+            %                 % we first (optionally) apply a moving average to smooth the data set. 
+            %                 % we then determine the mean exit times based on transitions past a certain
+            %                 % threshold
+            %                 res.periods_in = [];
+            %                 res.domain = domain;
+            %                 for m = 1:size(datax, 2)
+            %                     higheq = datax(:, m) > domain(1) & datax(:, m) < domain(2);
+            %                     shiftsup = datat(diff(higheq) == 1);
+            %                     shiftsdown = datat(diff(higheq) == -1);
+            %                     period_up = nan(size(shiftsdown));
+            %                     for i = 1:length(shiftsup)
+            %                         k = find(shiftsdown > shiftsup(i), 1);
+            %                         %we get nan if none is found
+            %                         if ~isempty(k)
+            %                             period_up(i) = shiftsdown(k) - shiftsup(i);
+            %                         end
+            %                     end
+            %                     res.periods_in = [res.periods_in; period_up];
+            %                 end
+            %                 ndx = ~isnan(res.periods_in);
+            %                 res.periods_in = res.periods_in(ndx);
+            %                 % res.period_down = period_down;
+            % 
+            %             end
+
+            args = struct(varargin{:});
+            if ~isfield(args, 'windowsize')
+                args.windowsize = 1;
+            end
+            if ~isfield(args, 'dt')
+                args.dt = obj.xtra.reconstr.options.dt;
+            end
+            if ~isfield(args, 'nreplicates')
+                args.nreplicates = 100;
+            end
+            if ~isfield(args, 'width')
+                args.width = 0;
+            end
+            if ~isfield(args, 'MaxStep')
+                args.MaxStep = 0.001;
+            end
+            if ~isfield(args, 'NonNegative')
+                args.NonNegative = [];
+            end
+            if args.windowsize <= 1
+                trend = data(:);
+            else
+                trend = movmean(data(:), args.windowsize);
+            end
+            % datat = linspace(0, numel(data) * args.dt, numel(data))';
+            direct_exits = cell(1, obj.nbasin);
+            % simul_exits = cell(1, obj.nbasin);
+            stableeq = find([obj.equilibria.stable]);
+            res.equilibria = [obj.equilibria(stableeq).x];
+            for i1 = 1:length(stableeq)
+                direct_exits{i1} = SojournTimes(data, args.dt, obj.equilibria(stableeq(i1)), args.width);
+                %direct_exits{i1} = direct_exit(datat(:), trend, obj.equilibria(stableeq(i1)).domain);
+                %     simul_exits{i1} = direct_exit(simuldatat, simultrend, obj.equilibria(stableeq(i1)).domain);
+            end
+            res.dataexits = direct_exits;
+            %res.simulexits = simul_exits;
+ 
+ 
+            if ~isfield(args, 'simuldata')
+                disp('Simulating');
+                sizedata = numel(data);
+                [simuldata, fcn] = obj.simulate( linspace(0, (sizedata - 1) * args.dt, sizedata)', obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative));
+                res.simuldata = fcn;
+                simuldatat = simuldata.t;
+                simuldata = simuldata.y;
+                if args.windowsize <= 1
+                    simultrend = simuldata;
+                else
+                    simultrend = movmean(simuldata, args.windowsize);
+                end
+            end
+
+            res.options = args;
+            datat = linspace(0, numel(data) * args.dt, numel(data))';
+            direct_exits = cell(1, obj.nbasin);
+            simul_exits = cell(1, obj.nbasin);
+            stableeq = find([obj.equilibria.stable]);
+            res.equilibria = [obj.equilibria(stableeq).x];
+            for i1 = 1:length(stableeq)
+                direct_exits{i1} = SojournTimes(trend, args.dt, obj.equilibria(stableeq(i1)), args.width);
+                %direct_exits{i1} = direct_exit(datat(:), trend, obj.equilibria(stableeq(i1)).domain);
+                simul_exits{i1} = SojournTimes(simultrend, args.dt, obj.equilibria(stableeq(i1)), args.width);
+                %simul_exits{i1} = direct_exit(simuldatat, simultrend, obj.equilibria(stableeq(i1)).domain);
+            end
+            res.dataexits = direct_exits;
+            res.simulexits = simul_exits;
+            %             figure
+            %             subplot(2, 1, 1)
+            %             stairs(sort(res.simulexits{1}.periods_in), cumsum(sort(res.simulexits{1}.periods_in)) / sum(res.simulexits{1}.periods_in))
+            %             hold on
+            %             stairs(sort(res.dataexits{1}.periods_in), cumsum(sort(res.dataexits{1}.periods_in)) / sum(res.dataexits{1}.periods_in))
+            %             subplot(2, 1, 2)
+            %             stairs(sort(res.simulexits{2}.periods_in), cumsum(sort(res.simulexits{2}.periods_in)) / sum(res.simulexits{2}.periods_in))
+            %             hold on
+            %             stairs(sort(res.dataexits{2}.periods_in), cumsum(sort(res.dataexits{2}.periods_in)) / sum(res.dataexits{2}.periods_in))
+        end
+      
+
+        function res = condition_step_distr(obj, data, varargin)
+            %one-step (or n-step) conditional distribution 
+            %default nstep=1
+            %
+            function [distr, sizes] = getdistrib(thedata, stepdata, perc)
+                if nargin < 3
+                    perc = [];
+                end
+                distr = cell(args.bins, 1);
+                sizes = zeros(args.bins, 1);
+                bincenters = linspace(args.domain(1), args.domain(2), args.bins);
+                mesh = linspace(args.domain(1), args.domain(2), args.nmesh);
+                binsiz = (bincenters(2) - bincenters(1)) / 2;
+                for l = 1:args.bins
+                    F = nan(size(thedata, 2), args.nmesh);
+                    siz = nan(size(thedata, 2), 1);
+                    for j = 1:size(thedata, 2)
+                        ndx1 = thedata(:, j) > bincenters(l) - binsiz & thedata(:, j) < bincenters(l) + binsiz;
+                        data1 = stepdata(ndx1, j);
+                        siz(j) = length(data1);
+                        if ~isempty(data1)
+                            [F1, ~] = ksdensity(data1(:), mesh);
+                            F(j, :) = F1 ./ (trapz(mesh, F1));
+                        else
+                            F(j, :) = 0;
+                        end
+                    end
+                    if ~isempty(perc)
+                        distr{l} = quantile(F, perc);
+                        sizes(l) = median(siz);
+                    else
+                        sizes(l) = siz;
+                        distr{l} = F;
+                    end
+                end
+            end
+            args = struct(varargin{:});
+            if ~isfield(args, 'bins')
+                args.bins = obj.xtra.reconstr.options.bins;
+            end
+            if ~isfield(args, 'nmesh')
+                args.nmesh = obj.nx;
+            end
+            if ~isfield(args, 'dt')
+                args.dt = obj.xtra.reconstr.options.dt;
+            end
+            if ~isfield(args, 'nreplicates')
+                args.nreplicates = 100;
+            end
+            if ~isfield(args, 'MaxStep')
+                args.MaxStep = 0.001;
+            end
+            if ~isfield(args, 'NonNegative')
+                args.NonNegative = [];
+            end
+            if ~isfield(args, 'nstep')
+                args.nstep = 1;
+            end
+            if ~isfield(args, 'domain')
+                args.domain = obj.domain;
+            end
+            if ~isfield(args, 'percentiles')
+                args.percentiles = [0.275 0.5 0.975];
+            end
+            data = data(:);
+            sizedata = size(data, 1);
+            data1 = data(args.nstep + 1:end);
+            stepdata = data(1:end - args.nstep); %second row is the time lag
+            res.bincenters = linspace(args.domain(1), args.domain(2), args.bins);
+            res.mesh = linspace(args.domain(1), args.domain(2), args.nmesh);
+            [res.datadistr, res.sizes] = getdistrib(data1, stepdata);
+            disp('Simulating');
+            [simuldata, fcn] = obj.simulate( linspace(0, (sizedata - 1) * args.dt, sizedata)', ...
+                obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative));
+            res.simuldata = fcn;
+            simuldata1 = simuldata.y(args.nstep + 1:end, :);
+            stepsimuldata = simuldata.y(1:end - args.nstep, :);
+            res.simuldatadistr = getdistrib(simuldata1, stepsimuldata, args.percentiles);
+            n1 = 10;
+            if n1 > args.nreplicates
+                n1 = args.nreplicates;
+            end
+            res.exampledata = simuldata.y(:, 1:n1); %at most ten example data sets 
+            res.options = args;
+            sumdiff = 0;
+            sumsiz = sum(res.sizes);
+            for l = 1:length(res.sizes)
+                simuldist = res.simuldatadistr{l};
+                simuldist = simuldist(2, :);
+                datadist = res.datadistr{l};
+                sumdiff = sumdiff + res.sizes(l) / sumsiz * sum(abs(simuldist - datadist));
+            end
+            res.sumdiff = sumdiff;
+        end
+
+        function equilibria1 = find_equilibria(obj, mode)
+            %find the equilibria and basin of attractions
+            % can be improved as it finds sometimes bubbles
+            %if mode is 'deterministic'
+            % the equilibria are just roots of D1
+            %if mode is 'effective' (default)
+            % the effect of D2 is accounted
+            if nargin == 1
+                mode = 'effective';
+            end
+            if strncmpi(mode, 'd', 1)
+                %naively D1
+                d1 = obj.D1;
+                mode = 'deterministic';
+            else
+                %-derivative of the effective potential (chain rule on log)
+                if isa(obj.D1, 'chebfun')
+                    d1 = obj.D1 ./ obj.D2 - diff(obj.D2) ./ obj.D2;
+                else
+                    dd2 = diff_fun(obj.D2);
+                    d1 = @(x)obj.D1(x) ./ obj.D2(x) - dd2(x) ./ obj.D2(x);
+                end
+                mode = 'effective';
+            end
+            Eqs = roots_fun(d1, obj.domain);
+            DD1 = diff_fun(d1);
+            isstable = DD1(Eqs) < 0;
+            Eqms = struct('x', {}, 'stable', [], 'BC', [], 'domain', []);
+
+            for i = 1:length(Eqs)
+                Eqms(i) = struct('x', Eqs(i), 'stable', isstable(i), 'BC', '', 'domain', []);
+            end
+
+            for i = 1:length(Eqms)
+                if isstable(i)
+                    BC = 'RR';
+                    dom = [-Inf Inf];
+                    if i > 1
+                        BC(1) = 'A';
+                        dom(1) = Eqms(i - 1).x;
+                    end
+                    if i < length(Eqms)
+                        BC(2) = 'A';
+                        dom(2) = Eqms(i + 1).x;
+                    end
+                    Eqms(i).domain = dom;
+                    Eqms(i).BC = BC;
+                end
+            end
+            if nargout == 0
+                fprintf('Equilibria (%s):\n', mode)
+                for i = 1:length(Eqms)
+                    if Eqms(i).stable
+                        stab = '  stable';
+                    else
+                        stab = 'unstable';
+                    end
+                    fprintf('%s equilibrium: %g   %s  %s\n', stab, Eqms(i).x, Eqms(i).BC, mat2str(Eqms(i).domain));
+                end
+            else
+                equilibria1 = Eqms;
+            end
+        end
+
+        function res = odefun(obj, dt)
+            %creates an ode function to be used in Euler integration
+            %it can also 
+            L = obj.domain(1);
+            R = obj.domain(2);
+            Mesh = linspace(L, R, 1000);
+            %griddedInterpolant is really fast
+            d1 = griddedInterpolant(Mesh, obj.D1(Mesh), 'linear');
+            d2 = griddedInterpolant(Mesh, obj.D2(Mesh), 'linear');
+            %the noise part  is multiplied with sqrt(t) and divided by dt, 
+            %in Euler it is multiplied again with dt, so it is a correct Euler Maruyama 
+            %
+            %if x<L, x=L
+            %if x>R, x=R
+            %D1(x) + sqrt(2*dt*D2(x))*randn(1)/dt
+            res = @(t,y)d1(min(R,max(L,y)))+sqrt(2 .* dt .* d2(min(R,max(L,y)))) .* randn(size(y)) /dt;
+        end
+
+        function [res, fcn] = simulate(obj, tspan, y0, options)
+            %simulate - time integration of the Langevin equation using
+            % Euler-Maruyama
+            % 
+            % Arguments:
+            % tspan = time span of the integration or all t values
+            % y0    = the initial condition (default 0.01). y0 can be a vector, the 
+            %         model will then be integrated for each y0 (efficient
+            %         due to vector notation)
+            % options = a structure with options for the integration, used
+            %         fields: MaxStep (or StepSize) - the step size
+            %                 NonNegative - force non-negative see Matlab
+            % Outputs:
+            % res   struct with the data sets (res.t= time; res.y = data)
+            % fcn   function handle that can reproduce the data (use for
+            %       efficient storage)
+            % 
+            %     
+            if nargin < 2
+                tspan = 1:1000;
+            end
+            if nargin < 3
+                y0 = 0.01;
+            end
+            if nargin < 4
+                options = odeset([], 'AbsTol', []);
+            end
+            if isfield(options, 'MaxStep') && ~isempty(options.MaxStep)
+                dt = options.MaxStep;
+            else
+                if isfield(options, 'StepSize') && ~isempty(options.StepSize)
+                    dt = options.StepSize;
+                else
+                    dt = 0.01;
+                end
+            end
+            %the noise part is divided by dt, in Euler it is multiplied
+            %again, to it is a correct Euler Mayaruma
+            %save random seed
+            r1 = rng;
+            %some prework
+            odefun = obj.odefun(dt);
+            options = odeset(options);
+            options.MaxStep = dt;
+            fcn = @()simulate_rng(r1,odefun,tspan,y0,options);
+            %[res.t, res.y] = euler(odefun, tspan, y0, options);
+            res = fcn();
+        end
+
+
+        function res = draw_pdf(obj, siz1, siz2)
+            %draw_pdf - draw random number from the stationary pdf
+            %use this to get a stabilized initial condition
+            %
+            % res=obj.draw_pdf(siz1,siz2)
+            if ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdf')
+                thepdf = obj.pdf;
+            else
+                thepdf = obj.xtra.results.pdf;
+            end
+            %make cumulative density function
+            cdf = cumtrapz(thepdf.x, thepdf.PDF);
+            if nargin < 2
+                siz1 = 1;
+            end
+            if nargin < 3
+                siz2 = siz1;
+            end
+            %interpolate from the inverted cumulative density function 
+            res = interp1(cdf, thepdf.x, rand(siz1, siz2));
+        end
+
+
+        function n = nbasin(obj)
+            %number of basins of attraction
+            n = sum([obj.equilibria.stable]);
+        end
+
+        function adjusttimescale(obj, ts)
+            %optionnally you can adjust the time scale of the Langevin
+            %equation by multiplying D1 and D2 with a factor
+            if ~isfield(obj.xtra.reconstr, 'ts')
+                obj.D1 = obj.D1 * ts;
+                obj.D2 = obj.D2 * ts;
+                obj.xtra.reconstr.ts = ts;
+                if isfield(obj.xtra.reconstr, 'D1')
+                    obj.xtra.reconstr.D1 = obj.xtra.reconstr.D1 * ts;
+                    obj.xtra.reconstr.D2 = obj.xtra.reconstr.D2 * ts;
+                    obj.xtra.reconstr.ErrorD1 = obj.xtra.reconstr.ErrorD1 * ts;
+                    obj.xtra.reconstr.ErrorD2 = obj.xtra.reconstr.ErrorD2 * ts;
+                end
+            else
+                error('Timescale was already changed');
+            end
+        end
+
+        function result = potential(obj)
+            %calculate the potential function
+            if isempty(obj.D1) || isempty(obj.D2)
+                error('langevin_eq:nomodel', 'No Langevin equation defined');
+            end
+            if isa(obj.D1, 'chebfun')
+                result.u = -cumsum(obj.D1); % Clearly, here we do not need to care about time scale change.
+            else
+                h = integralx_fun(obj.D1, obj.domain(1), obj.domain(2));
+                result.u = @(x)-h(x);
+            end
+            result.dom = linspace(obj.domain(1), obj.domain(2), obj.nx);
+        end
+
+        function result = potential_eff(obj)
+            %calculate the effective potential. This includes the effects
+            %of diffusion on the stationary pdf
+            if isempty(obj.D1) || isempty(obj.D2)
+                error('langevin_eq:nomodel', 'No Langevin equation defined');
+            end
+            if isa(obj.D1, 'chebfun')
+                result.ueff = cumsum(-obj.D1 / obj.D2) + log(obj.D2); % Clearly, here we do not need to care about time scale change.
+            else
+                h1 = @(x)-obj.D1(x)/obj.D2(x);
+                h = integralx_fun(h1, obj.domain(1), obj.domain(2));
+                result.ueff = @(x)h(x)+log(obj.D2(x));
+            end
+            result.dom = linspace(obj.domain(1), obj.domain(2), obj.nx);
+        end
+
+        function [hax, res] = plot(obj, varargin)
+            %plot the results of the analyses, two ways of running:
+            % 1) use the output of one of the methods as input of plot:
+            %     >> obj.plot(obj.pdf) - to plot the stationary pdf
+            % 2) use text: (if necessary the analyses is done with default
+            %     parameters)
+            %     for instance:
+            %     >> figure;
+            %     >> obj.plot('D1');
+            %
+            % parameters:
+            %     'basinprob'     plot the probabilities of being in each
+            %                     attraction basin vs. time
+            %     'D1'            plot the drift function
+            %     'D2'            plot the diffusion function
+            %     'DD2'           plot the derivative of the diffusion function
+            %     'equilibria'    plot the equilibria in the D1 plot
+            %     'exit_distrib'  plot the probability density function of
+            %                     exit times for a certain initial state
+            %     'exitprob'      probability of exit from each boundary in a
+            %                     AA boundary condition
+            %     'mean_exit'     mean exit time of the basin
+            %     'pdf'           plot the stationary pdf
+            %     'potential'     potential
+            %     'potential_eff' effective potential
+            %     'survival'      plot the survival and median exit time
+            %     'survival_func' plot the survival function for an inital
+            %                     state
+            %     'vertical_basin_boundaries'  indicate the basin boundaries 
+            %                     in the current figure
+
+
+            function res = getbootresults(bootstrap)
+                C = bootstrap.results(1).reconstr.C;
+                Ts = zeros(numel(bootstrap.results), numel(C));
+                WTs = zeros(numel(bootstrap.results), numel(bootstrap.results(1).results.mean_exit));
+                for i1 = 1:numel(bootstrap.results)
+                    T = zeros(size(C));
+                    for j1 = 1:numel(bootstrap.results(i1).results.mean_exit)
+                        me = bootstrap(1).results(i1).results.mean_exit{j1};
+                        ndx = C >= me.domain(1) & C <= me.domain(2);
+                        WTs(i1, j1) = me.WT;
+                        if isa(me.T, 'chebfun')
+                            T(ndx) = me.T(C(ndx));
+                        else
+                            T(ndx) = me.T(ndx);
+                        end
+                    end
+                    Ts(i1, :) = T;
+                end
+                if ~isfield(bootstrap.options, 'bias')
+                    bias = NaN;
+                else
+                    bias = bootstrap.options.bias;
+                end
+                res = struct('C', C, 'Ts', Ts, 'WTs', WTs, 'CL_WT', quantile(WTs, [0.025, 0.975]), 'CL_Ts', quantile(Ts, [0.025, 0.975]), 'bias', bias);
+            end
+            function hax1 = plot_mean_exit(T, domain, WT, acolor, nx)
+                if isa(T, 'chebfun')
+                    l1 = linspace(min(domain), max(domain), nx);
+                    hax1 = plot(l1, T(l1), [acolor '-'], 'LineWidth', 1.5);
+                else
+                    l1 = linspace(min(domain), max(domain), numel(T));
+                    hax1 = plot(l1, T, [acolor '-'], 'LineWidth', 1.5);
+                end
+                hold on
+                if ~isempty(WT)
+                    plot([l1(1), l1(end)], [WT, WT], [acolor '--'], 'LineWidth', 1);
+                end
+            end
+            if isempty(obj.D1) || isempty(obj.D2)
+                error('langevin_eq:nomodel', 'No Langevin equation defined');
+            end
+            hax1 = [];
+            res = [];
+            if nargin == 1
+                if isfield(obj.xtra, 'results')
+                    f = fieldnames(obj.xtra.results);
+                    for i = 1:length(f)
+                        res = obj.xtra.results.(f{i});
+                        if isfield(res, 'figno')
+                            figure(res.figno)
+                        else
+                            figure;
+                        end
+                        obj.plot(res);
+                    end
+                else
+                    hax1 = obj.plot('D1');
+                end
+            elseif iscell(varargin{1})
+                for i = 1:length(varargin{1})
+                    hax1(i) = obj.plot(varargin{1}{i}, varargin{2:end});
+                end
+            elseif ischar(varargin{1})
+                args = varargin(2:end);
+                switch varargin{1}
+                    case {'D1', 'D2' , 'DD2', 'D4'}
+                        %extra options:
+                        %timescale: simply scales yaxis
+                        %npoints: number of interpolation points
+                        %ylabel: specify the y label
+                        %noboot: true/false suppress plotting of bootstrap
+                        %error: true/false suppress plotting of errors
+                        args = struct(args{:});
+                        if strcmp(varargin{1}, 'D1')
+                            x = obj.D1;
+                        elseif strcmp(varargin{1}, 'D2')
+                            x = obj.D2;
+                        elseif strcmp(varargin{1}, 'DD2')
+                            if isempty(obj.DD2)
+                                x = diff_fun(obj.D2);
+                            else
+                                x = obj.DD2;
+                            end
+                        elseif strcmp(varargin{1}, 'D4')
+                            x = griddedInterpolant(obj.xtra.reconstr.C, obj.xtra.reconstr.D4, 'spline');
+                        end
+                        %                         ploterror=true;
+                        %                         ts=1;
+                        %                         args.verticalbar=true;
+                        if ~isfield(args, 'timescale')
+                            args.timescale = 1;
+                        end
+                        if ~isfield(args, 'noboot')
+                            args.noboot = false;
+                        end
+                        if ~isfield(args, 'npoints')
+                            args.npoints = 50;
+                        end
+                        if ~isfield(args, 'ylabel')
+                            if strcmp(varargin{1}, 'D1')
+                                args.ylabel = 'Drift D1';
+                            elseif strcmp(varargin{1}, 'DD2')
+                                args.ylabel = 'd(D2)/dx';
+                            else
+                                args.ylabel = 'Diffusion D2';
+                            end
+                        end
+
+                        dom = linspace(obj.domain(1), obj.domain(2), args.npoints);
+                        
+                        if isfield(obj.xtra, 'bootstrap') && ~args.noboot
+                            results = obj.xtra.reconstr;
+                            hold on
+                            %vectorbased fast:
+                            recs = [obj.xtra.bootstrap(1).results(:).reconstr];
+                            boots = vertcat(recs.(varargin{1}));
+                            range = quantile(boots, [0.025, 0.975]);
+                            fill([results.C , fliplr(results.C)], args.timescale * [range(1, :), fliplr(range(2, :))], [1 0.8 0.8], 'EdgeColor', 'none');
+                        elseif ~(~isfield(obj.xtra, 'reconstr') || isempty(obj.xtra.reconstr)) && (~isfield(args, 'error') || args.error)
+                            hold on
+                            results = obj.xtra.reconstr;
+                            if strcmp(varargin{1}, 'D1')
+                                %hax1 = errorbar(results.C, results.D1, results.ErrorD1, '.b');
+                                fill([results.C , fliplr(results.C)], [args.timescale * results.D1 - results.ErrorD1, fliplr(args.timescale * results.D1 + results.ErrorD1)], [1 0.8 0.8], 'EdgeColor', 'none')
+                            elseif strcmp(varargin{1}, 'D2')
+                                fill([results.C , fliplr(results.C)], [args.timescale * results.D2 - results.ErrorD2, fliplr(args.timescale * results.D2 + results.ErrorD2)], [1 0.8 0.8], 'EdgeColor', 'none')
+                            end
+                        end
+                        hax1 = plot(dom, args.timescale .* x(dom), '-r', 'linewidth', 1.5, 'tag', varargin{1});
+                        xlim(obj.domain);
+                        xlabel(obj.namex);
+                        ylabel(args.ylabel)
+                        if strcmp(varargin{1}, 'D1')
+                            yline(0, 'k-');
+                        end
+                        if ~isfield(args, 'verticalbar') || args.verticalbar
+                            obj.plot('vertical_basin_boundaries');
+                        end
+                        %                     case 'D4'
+                        %                         %plot the Relative error of the Langevin
+                        %                         %reconstruction
+                        %                         if ~isfield(args, 'timescale')
+                        %                             args.timescale = 1;
+                        %                         end
+                        %                         if isfield(obj.xtra, 'bootstrap')
+                        %                             results = obj.xtra.reconstr;
+                        %                             hold on
+                        %                             %boots = zeros(numel(obj.xtra.bootstrap(1).results), numel(results.C));
+                        %                             recs = [obj.xtra.bootstrap(1).results(:).reconstr];
+                        %                             boots = vertcat(recs.D4);
+                        %                             %                             for i = 1:numel(obj.xtra.bootstrap(1).results)
+                        %                             %                                 boots(i, :) = obj.xtra.bootstrap(1).results(i).reconstr.D4;
+                        %                             %                             end
+                        %                             range = quantile(boots, [0.025, 0.975]);
+                        %                             fill([results.C , fliplr(results.C)], [range(1, :), fliplr(range(2, :))], [1 0.8 0.8], 'EdgeColor', 'none');
+                        %                         end
+                        %                         hax1 = plot(obj.xtra.reconstr.C, args.timescale .* obj.xtra.reconstr.D4, '-r');
+                        %                         hold on
+                        %                         ylabel('D_{4}')
+                        %                         xlabel(obj.namex);
+                    case 'vertical_basin_boundaries'
+                        hold on
+                        unstableeqs = find(~[obj.equilibria.stable]);
+                        for i = 1:length(unstableeqs)
+                            try
+                                hax1 = xline(obj.equilibria(unstableeqs(i)).x, 'k--');
+                            catch
+                                %older versions of matlab do not have xline
+                                ylim1=get(gca,'ylim');
+                                plot(obj.equilibria(unstableeqs(i)).x + zeros(1, 2), ylim1, 'k--')
+                            end
+                        end
+                    case 'potential_eff'
+                        hax1 = obj.plot(obj.potential_eff, args{:});
+                    case 'potential'
+                        hax1 = obj.plot(obj.potential, args{:});
+                    case 'pdf'
+                        if ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdf')
+                            obj.pdf;
+                        end
+                        hax1 = obj.plot(obj.xtra.results.pdf);
+                    case 'survival'
+                        hold on
+                        if nargin > 2 || ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'survival')
+                            obj.survival('all', args{:});
+                        end
+                        hax1 = obj.plot(obj.xtra.results.survival);
+                    case 'basinprob'
+                        if nargin > 2
+                            result = args{1};
+                        else
+                            if nargin == 2 && ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdfs')
+                                obj.pdfs;
+                            end
+                            result = obj.xtra.results.pdfs;
+                        end
+                        nt = size(result.pdfs, 1);
+                        result.t = result.t(1:nt);
+                        eqs = obj.equilibria([obj.equilibria(:).stable]);
+                        for i = 1:length(eqs)
+                            eqs(i).domain = min(result.x(end), max(result.x(1), eqs(i).domain));
+                        end
+                        Ps = zeros(nt, length(eqs));
+
+                        for j = 1:length(eqs)
+                            ran = result.x < max(eqs(j).domain) & result.x > min(eqs(j).domain);
+                            for i = 1:nt
+                                Ps(i, j) = trapz(result.x(ran), result.pdfs(i, ran));
+                            end
+                        end
+                        if ~isempty(Ps)
+                            hax1 = plot(result.t, Ps);
+                        end
+                        xlabel('Time (t)')
+                        ylabel('Probability')
+                        leg = cell(length(eqs), 1);
+                        for j = 1:length(eqs)
+                            leg{j} = sprintf('%s in [%g,%g]', obj.namex, min(eqs(j).domain), max(eqs(j).domain));
+                        end
+                        legend(leg);
+                        ylim([0, 1]);
+                        xlim([result.t(1), result.t(end)]);
+                    case 'exitprob' %args1 is mean_exit results of AA problem
+                        if nargin > 2
+                            result = args{1};
+                        else
+                            if nargin == 2 && ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'mean_exit')
+                                obj.mean_exit;
+                            end
+                            result = obj.xtra.results.mean_exit;
+                        end
+                        if isfield(result, 'T') || isfield(result, 'T_left') %mean exit time
+                            xpoints = linspace(result.domain(1), result.domain(2), length(result.P_left));
+                            if isfield(result, 'T_left')
+                                if isa(result.P_left, 'chebfun')
+                                    plot(xpoints, result.P_left(xpoints), 'b');
+                                    hold on
+                                    plot(xpoints, result.P_right(xpoints), 'm');
+                                else
+                                    plot(xpoints, result.P_left, 'b')
+                                    hold on
+                                    plot(xpoints, result.P_right, 'm');
+                                end
+                            else
+                                plot(xpoints, ones(size(xpoints)), 'b');
+                            end
+                            ylim([0 1])
+                            xlabel(obj.namex)
+                            ylabel('Probability of exit P')
+                        end
+                    case {'survival_func', 'exit_distrib'} %args1 is x0 args2 = survival results
+                        hold on
+                        x0 = args{1};
+                        if (length(args) < 2) || ~(isstruct(args{2}) || iscell(args{2}))
+                            if isfield(obj.xtra, 'results') && isfield(obj.xtra.results, 'survival')
+                                results = obj.xtra.results.survival;
+                            else
+                                results = obj.survival('all', args{2:end});
+                            end
+                        else
+                            results = args{2};
+                        end
+                        if iscell(results)
+                            for i = 1:length(results)
+                                [hax, res1] = obj.plot(varargin{1}, x0, results{i});
+                                if ~isempty(res1)
+                                    res = res1;
+                                end
+                            end
+                        else
+                            if x0 > min(results.x) && x0 < max(results.x)
+                                n = find(results.x >= x0, 1);
+                                surv = results.survival(:, n(1));
+                                res.surv = surv;
+                                res.t = results.t;
+                                if strcmp(varargin{1}, 'survival_func')
+                                    fill([results.t(:); results.t(end); results.t(1)], [surv; 0; 0], [0.75 1 0.75]);
+                                    ylim([0 1]);
+                                    ylabel('Survival')
+                                end
+                                if strcmp(varargin{1}, 'exit_distrib')
+                                    if isa(obj.D1, 'chebfun')
+                                        f = chebfun(surv, [results.t(1) results.t(end)], 'equi', 10000);
+                                        f = -diff(f);
+                                    else
+                                        f = @(x)interp1(results.t,surv,x,'spline');
+                                        f1 = diff_fun(f);
+                                        f = @(x)-f1(x);
+                                    end
+                                    res.density = f(results.t);
+                                    fill([results.t(:); results.t(end); results.t(1)], [res.density(:); 0; 0], [0.75 1 1]);
+                                    ylabel('Density')
+                                    ylim([0 Inf])
+                                end
+                                xlim([min(results.t), max(results.t)])
+                                xlabel(sprintf('Time %s', obj.timeunit))
+                            end
+                        end
+                    case 'mean_exit'
+                        hold on
+                        if isempty(args)
+                            args = {'all', obj.pdf};
+                        end
+                        if isfield(args{1}, 'PDF')
+                            args = [{'all'}, args];
+                        end
+                        if nargin > 2 || ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'mean_exit')
+                            obj.mean_exit(args{:});
+                        end
+                        if isfield(obj.xtra, 'bootstrap')
+                            %add the bootstrapped percentiles
+                            hold on
+                            res = getbootresults(obj.xtra.bootstrap(1));
+                            fill([res.C , fliplr(res.C)], [res.CL_Ts(1, :), fliplr(res.CL_Ts(2, :))], [0.75 1 1], 'EdgeColor', 'none');
+                            % range = quantile(res.WTs(:, [1 2]), [0.025 0.25 0.5 0.75 0.975]);
+                            titl = [];
+                            s = [];
+                            disp(obj.xtra.bootstrap(1).bootmethod);
+                            for i = 1:size(res.WTs, 2)
+                                titl = sprintf('%sCL Basin %d\trelrange %d\t', titl, i, i);
+                                CL = quantile(res.WTs(:, i), [0.025 0.975]);
+                                med = median(res.WTs(:, i));
+                                s = sprintf('%s[%g %g]\t%g\t', s, CL(1), CL(2), (CL(2) - CL(1)) / med);
+                            end
+                            fprintf('%s\n', titl);
+                            fprintf('%s\n', s);
+                        end
+                        hax1 = obj.plot(obj.xtra.results.mean_exit);
+                    case 'equilibria'
+                        stab = [obj.equilibria([obj.equilibria.stable]).x];
+                        unstab = [obj.equilibria(~[obj.equilibria.stable]).x];
+                        plot(stab, zeros(size(stab)), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', 'k');
+                        hold on
+                        hax1 = plot(unstab, zeros(size(unstab)), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', [1 1 1]);
+                end
+            else
+                result = varargin{1};
+                args = struct(varargin{2:end});
+                if isfield(result, 'T') || isfield(result, 'T_left') %mean exit time
+
+                    if isfield(result, 'T_left')
+                        plot_mean_exit(result.T_left, result.domain, [], 'b', obj.nx);
+                        hold on;
+                        plot_mean_exit(result.T_right, result.domain, [], 'm', obj.nx);
+                    end
+                    hax1 = plot_mean_exit(result.T, result.domain, result.WT, 'g', obj.nx);
+                    xlim(obj.domain);
+                    yl = get(gca, 'ylim');
+                    if yl(1) < 0
+                        set(gca, 'ylim', [0 yl(2)]);
+                    end
+                    xlabel(obj.namex);
+                    if isempty(obj.timeunit)
+                        ylabel('Mean exit time T')
+                    else
+                        ylabel(sprintf('Mean exit time T (%s)', obj.timeunit))
+                    end
+                    if ~isfield(args, 'verticalbar') || args.verticalbar
+                        obj.plot('vertical_basin_boundaries');
+                    end
+                elseif isfield(result, 'ueff') %effective potential
+                    U = result.ueff(result.dom);
+                    U = U - min(U) + 0.1 * (max(U) - min(U));
+                    hax1 = fill([result.dom, result.dom(end), result.dom(1)], [U, 0, 0], [0.75 0.75 1]);
+                    xlim(obj.domain);
+                    xlabel(obj.namex);
+                    ylabel('Effective potential')
+                    if ~isfield(args, 'verticalbar') || args.verticalbar
+                        obj.plot('vertical_basin_boundaries');
+                    end
+                elseif isfield(result, 'u') %potential
+                    U = result.u(result.dom);
+                    U = U - min(U) + 0.1 * (max(U) - min(U));
+                    hax1 = fill([result.dom, result.dom(end), result.dom(1)], [U, 0, 0], [0.75 0.75 1]);
+                    xlim(obj.domain);
+                    xlabel(obj.namex);
+                    ylabel('Potential')
+                    if ~isfield(args, 'verticalbar') || args.verticalbar
+                        obj.plot('vertical_basin_boundaries');
+                    end
+                elseif isfield(result, 'PDF') || isfield(result, 'pdfs') %pdf    
+                    if isfield(args, 't')
+                        t = args.t;
+                    else
+                        t = result.t(end);
+                    end
+                    hax1 = findobj(get(0, 'currentfigure'), 'tag', 'pdfs');
+                    if ~isempty(hax1)
+                        updatefig = true;
+                    else
+                        updatefig = false;
+                    end
+                    it = find(result.t >= t, 1);
+                    if isempty(it)
+                        it = length(result.t);
+                    end
+
+                    if (it == length(result.t)) && isfield(result, 'PDF')
+                        if updatefig
+                            set(hax1, 'YData', [result.PDF, 0 0]);
+                        else
+                            hax1 = fill([result.x result.x(end) result.x(1)], [result.PDF, 0 0], [0.75 0.75 1]);
+                        end
+                    else
+                        if updatefig
+                            set(hax1, 'YData', [result.pdfs(it, :), 0 0]);
+                        else
+                            hax1 = fill([result.x result.x(end) result.x(1)], [result.pdfs(it, :), 0 0], [0.75 0.75 1]);
+                        end
+                    end
+                    xlim(obj.domain);
+                    xlabel(obj.namex);
+                    if isfield(result, 'PDF') && isempty(args)
+                        ylabel('Stationary density')
+                    else
+                        ylabel('Probability density')
+                    end
+                    set(hax1, 'tag', 'pdfs');
+                    if ~isfield(args, 'verticalbar') || args.verticalbar
+                        obj.plot('vertical_basin_boundaries');
+                    end
+                elseif isfield(result, 'y') %integration            
+                    hax = plot(result.t, result.y, 'b-');
+                    xlabel('Time');
+                    ylabel(obj.namex);
+                elseif isfield(result, 'survival') %survival
+                    [x, y] = meshgrid(result.x, result.t);
+                    colormap( [linspace(1, 0.5, 50)', linspace(1, 0.5, 50)', ones(50, 1)]);
+                    [~, hax1] = contourf(x, y, result.survival, 100);
+                    set(hax1, 'LineColor', 'none')
+                    hold on
+                    [~, hax1] = contour(x, y, result.survival, [0.5 0.5]);
+                    set(hax1, 'LineColor', 'k', 'LineWidth', 2)
+                    [~, hax1] = contour(x, y, result.survival, [0.75 0.25]);
+                    set(hax1, 'LineColor', 'b', 'LineWidth', 1)
+                    % [~, hax1] = contour(x, y, result.survival, 1-[0.9:0.001:0.999]);
+                    %  set(hax1, 'LineColor', 'g', 'LineWidth', 1)
+                    xlim(obj.domain);
+                    xlabel(obj.namex);
+                    if isempty(obj.timeunit)
+                        ylabel('Survival time')
+                    else
+                        ylabel(sprintf('Survival time (%s)', obj.timeunit))
+                    end
+                    if ~isfield(args, 'verticalbar') || args.verticalbar
+                        obj.plot('vertical_basin_boundaries');
+                    end
+                elseif isfield(result, 'command')
+                    obj.plot(result.command);
+                end
+            end
+            if nargout > 0
+                hax = hax1;
+            end
+        end
+
+        function res = prob_exit(obj, domain_, BC, options)
+            % prob_exit (numerically) determines the probability to exit
+            % left or right
+            %
+            % obj.mean_exit(ibasin, PDF, options)
+            %
+            % Inputs are:
+            %
+            % domain= range of conditions
+            % BC the boundary value code:
+            %  'AA' = left and right absorbing
+            %  'RA' = left reflecting and right absorbing
+            %  'AR' = left absorbing and right reflecting
+            %
+            % options (optional) the boundary value problem options (see
+            % bvpopt) + additional fields:
+            %    nx = number of points in x direction
+            %    initfunc = function handle describing the initial guess of
+            %    the boundary value problem
+            %  can also be entered as field, value pairs (case sensitive)
+            %
+            % Outputs is a structure with fields:
+            % domain: the domain
+            % BC: boundary condition
+            % P_left:  the probability of exit from left boundary.
+            % P_right: the probability of exit from right boundary.
+            %
+            function res = getinitfun(domain_, BC)
+                %initial sine, make sure that the BC are correct
+                %initfun = @(x)[cos(4 * x), -4 * sin(4 * x) ]   ;
+                starth = 0;
+                endh = 2 * pi;
+                if BC(1) == 'R'
+                    %start at pi/2 to have correct BC
+                    starth = starth + pi / 2;
+                end
+                if BC(2) == 'R'
+                    %start at pi/2 to have correct BC
+                    endh = endh + pi / 2;
+                end
+                per = (endh - starth) / (domain_(2) - domain_(1));
+                res = @(x)[cos(per * (x-domain_(1))+starth); -per * sin(per * (x-domain_(1))+starth) ];
+            end
+            res.domain = domain_;
+            res.BC = BC;
+            if ~strcmp(BC, 'AA')
+                if BC(1) == 'R'
+                    res.P_left = 0;
+                else
+                    res.P_left = 1;
+                end
+                if BC(2) == 'R'
+                    res.P_left = 0;
+                else
+                    res.P_left = 1;
+                end
+            else
+
+                if isa(obj.D1, 'chebfun')
+                    d1 = obj.D1;
+                    d1.domain = domain_;
+                    d2 = obj.D2;
+                    d2.domain = domain_;
+                    LP = chebop(domain_); % LP is operator for the probability of exit
+                    LP.op = @(x, P) d1 .* diff(P) + d2 .* diff(P, 2);
+                    LP.lbc = @(P)P - 1;
+                    LP.rbc = @(P)P;
+                    P = LP \ (0);
+                    res.P_left = P;
+
+                    LP = chebop(domain_); % LP is operator for the probability of exit
+                    LP.op = @(x, P) d1 .* diff(P) + d2 .* diff(P, 2);
+                    LP.lbc = @(P)P;
+                    LP.rbc = @(P)P - 1;
+                    P = LP \ (0);
+                    
+                    res.P_right = P;
+                else
+                    % function handle mode
+                    %
+                    %Backward Fokker Planck equation:
+                    %D1(x0)*T'+D2(x0 )*T''=-1 
+                    %
+                    %define:
+                    %T2=T';
+                    %D1(x0)*T2+D2(x0)*T2'=-1
+                    %
+                    %yields the following 2D ODE system
+                    %T2'=-(D1(x0)*T2 + 1)/D2(x0)
+                    %T'=T2;
+                    if nargin < 4
+                        options = [];
+                    end
+                    if ~isfield(options, 'nx')
+                        options.nx = obj.nx;
+                    end
+                    if ~isfield(options, 'RelTol') || isempty(options.RelTol)
+                        options.RelTol = 1E-7;
+                    end
+                    if ~isfield(options, 'AbsTol') || isempty(options.RelTol)
+                        options.RelTol = 1E-6;
+                    end
+                    if ~isfield(options, 'initfun') || isempty(options.initfun)
+                        options.initfun = {getinitfun(domain_, 'AR'), getinitfun(domain_, 'RA')};
+                    elseif ~iscell(options.initfun)
+                        options.initfun = {options.initfun, options.initfun};
+                    end
+                    xpoints = linspace(res.domain(1), res.domain(2), options.nx);
+                    %We determine the probabilities of leaving the
+                    %left border with het BVP equation:
+                    %0 = D1(x0) * P' + D2(x0) * P'';
+                    %
+                    %define:
+                    %P2  =P';
+                    %D1(x0) *P2 + D2(x0) * P2' = 0
+                    %
+                    %yields the following 2D ODE system
+                    %P'=P2;
+                    %P2'=-(D1(x0)*P2)/D2(x0)
+                    %
+                    odefunP = @(x,P)[P(2,:);-obj.D1(x) .* P(2,:) ./ obj.D2(x) ];
+
+                    %left BC P = 1, right BC P = 0
+                    BCfunleft = @(ya,yb)[ya(1)-1; yb(1)];
+                    solinit = bvpinit(xpoints, options.initfun{1});
+                    %determine the left probabilities
+                    sol = bvp4c(odefunP, BCfunleft, solinit, options);
+                    res.P_left = deval(sol, xpoints); %only if we want to interpolate between the mesh
+                    res.P_left = res.P_left(1, :);
+                    BCfunright = @(ya,yb)[ya(1); yb(1)-1];
+                    solinit = bvpinit(xpoints, options.initfun{2});
+                    sol = bvp4c(odefunP, BCfunright, solinit);
+                    res.P_right = deval(sol, xpoints); %only if we want to interpolate between the mesh
+                    res.P_right = res.P_right(1, :);
+                end
+            end
+        end
+
+        function res = mean_exit(obj, ibasin, PDF, varargin)
+            % mean_exit (numerically) solves the backward Fokker-Planck equation
+            % and then calculates many quantities.
+            %
+            % obj.mean_exit(ibasin, PDF, options)
+            %
+            % Inputs are:
+            %
+            % ibasin = the number of the basin or 'all' or a struct with
+            % the fields "domain" and "BC"
+            % Where domain is the domain and BC the boundary value code:
+            %  'AA' = left and right absorbing
+            %  'RA' = left reflecting and right absorbing
+            %  'AR' = left absorbing and right reflecting
+            %
+            % PDF (optional) is a struct describing the stationary probability density
+            % function or empty, see output of the method "pdf"
+            %
+            % options (optional) the boundary value problem options (see
+            % bvpopt) + additional fields:
+            %    nx = number of points in x direction
+            %    initfunc = function handle describing the initial guess of
+            %    the boundary value problem
+            %  can also be entered as field, value pairs (case sensitive)
+            %
+            % Outputs is a structure with fields:
+            %
+            % T: is a (chebfun) function which tells us the average time to escape the
+            % domain (see exit curves in Figures 2,3,5 in the main text).
+            % WT: is the average time to escape the domain. It implements the calculations of Formula 4 in the main text.
+            % P: calculates the probability of exit from left or right boundaries. Note that, it only makes sense if
+            % the boundary conditions are of AAleft or AAright types (we did not use it in this paper).
+            % 
+            % use obj.plot(res) to plot the results
+            %
+           
+            if nargin < 2
+                ibasin = 'all';
+            end
+            if nargin < 3
+                PDF = [];
+            end
+            if nargin > 4
+                options = struct(varargin{:});
+            elseif nargin == 4
+                options = varargin{1};
+            else
+                options = bvpset;
+            end
+
+            if ischar(ibasin) && strcmp(ibasin, 'all')
+                res = cell(1, obj.nbasin);
+                for i = 1:length(res)
+                    res{i} = obj.mean_exit(i, PDF);
+                end
+                obj.xtra.results.mean_exit = res;
+                return;
+            end
+            if isstruct(ibasin) && length(ibasin) > 1
+                %if ibasin is a struct with equilibria
+                %remove basins without BC
+                ndx = ~cellfun('isempty', {ibasin(:).BC});
+                ibasin = ibasin(ndx);
+                res = cell(1, length(ibasin));
+                for i = 1:length(res)
+                    res{i} = obj.mean_exit(ibasin(i), PDF);
+                end
+                obj.xtra.results.mean_exit = res;
+                return;
+            end
+            if isstruct(ibasin)
+                domain2 = ibasin.domain;
+                domain2(domain2 < obj.domain(1)) = obj.domain(1);
+                domain2(domain2 > obj.domain(2)) = obj.domain(2);
+                BC = ibasin.BC;
+            else
+                nbasin1 = obj.nbasin;
+                if ibasin > nbasin1
+                    error('langevin_eq:mean_exit', 'basin number too large');
+                end
+                stableeq = find([obj.equilibria.stable]);
+                eqnr = stableeq(ibasin);
+                domain2 = obj.equilibria(eqnr).domain;
+                domain2(domain2 < obj.domain(1)) = obj.domain(1);
+                domain2(domain2 > obj.domain(2)) = obj.domain(2);
+                BC = obj.equilibria(eqnr).BC;
+            end
+
+            if ~any(strcmp(BC, {'RA', 'AR', 'AA', 'RR'}))
+                error('langevin_eq:mean_exit', 'boundary condition "%s" unknown', BC);
+            end
+            domain_ = domain2;
+            res.domain = domain_;
+            res.BC = BC;
+            if ~isfield(options, 'initfun') || isempty(options.initfun)
+                %initial sine, make sure that the BC are correct
+                %initfun = @(x)[cos(4 * x), -4 * sin(4 * x) ]   ;
+                starth = 0;
+                endh = 2 * pi;
+                if BC(1) == 'R'
+                    %start at pi/2 to have correct BC
+                    starth = starth + pi / 2;
+                end
+                if BC(2) == 'R'
+                    %start at pi/2 to have correct BC
+                    endh = endh + pi / 2;
+                end
+                per = (endh - starth) / (res.domain(2) - res.domain(1));
+                %                 if isa(obj.D1,'chebfun')
+                %                     x=chebfun('x');
+                %                     initfunT=[cos(per * (x-res.domain(1))+starth); -per * sin(per * (x-res.domain(1))+starth) ] ;
+                %                 else    
+                initfunT = @(x)[cos(per * (x - res.domain(1)) + starth); -per * sin(per * (x - res.domain(1)) + starth) ]   ;
+                %               end
+                %do not add initfun to options, as we use them also for
+                %prob_exit
+            else
+                initfunT = options.initfun;
+            end
+
+
+            if isa(obj.D1, 'chebfun')
+                if ~isempty(PDF)
+                    if ~isa(PDF, 'chebfun')
+                        PDF = chebfun(PDF.PDF', obj.domain, 'equi', 5000);
+                    end
+                    PDF.domain = domain2;
+                end
+                d1 = obj.D1;
+                d1.domain = domain_;
+                d2 = obj.D2;
+                d2.domain = domain_;
+                %setting up chebop boundary value problem
+                LL = chebop(domain_);
+                LL.op = @(x, T) d1 .* diff(T) +d2 .* diff(T, 2);
+                if BC(1) == 'R'
+                    LL.lbc = @(T)diff(T);
+                else
+                    LL.lbc = @(T)T;
+                end
+                if BC(2) == 'R'
+                    LL.rbc = @(T)diff(T);
+                else
+                    LL.rbc = @(T)T;
+                end
+                %solving T
+                res.T = solvebvp(LL , -1);
+                T2 = chebfun(res.T, domain2);
+                if ~isempty(PDF)
+                    res.WT = sum(PDF * T2) / sum(PDF);
+                else
+                    res.WT = [];
+                end
+                res.P = [];
+
+                if strcmp(BC, 'AA')
+                    res1 = obj.prob_exit(domain_, BC);
+                    LL = chebop(domain_);
+                    LL.op = @(x, T) d1 .* diff(T) + d2 .* diff(T, 2);
+                    LL.lbc = @(T)T;
+                    LL.rbc = @(T)T;
+                    % T = LL \ (-res1.P_left);
+                    [T, sol] = solvebvp(LL , -res1.P_left);
+                    if sol.error > 0.001
+                        xpoints = linspace(domain_(1), domain_(2), 200);
+                        P_l = griddedInterpolant(xpoints, res1.P_left(xpoints));
+                        odefunT = @(x,T)[T(2)+zeros(size(x));  -(obj.D1(x) .* T(2) + P_l(x)) ./ obj.D2(x)];
+                        BCfun = @(ya,yb)[ya(1) yb(1)];
+                        one = chebfun(1, domain_);
+                        v0 = [one 0 * one];
+                        T1 = bvp4c(odefunT, BCfun, v0);
+                        res.T_left = chebfun(T1(:, 1) ./ res1.P_left, 'splitting', 'on');
+                    else
+                        res.T_left = chebfun(T ./ res1.P_left, 'splitting', 'on');
+                    end
+
+                    T2 = chebfun(res.T_left, domain2, 'splitting', 'on');
+                    if ~isempty(PDF)
+                        res.WT_left = sum(PDF * T2) / sum(PDF);
+                    else
+                        res.WT_left = [];
+                    end
+                    res.P_left = res1.P_left;
+
+                    LL = chebop(domain_);
+                    LL.op = @(x, T) d1 .* diff(T) + d2 .* diff(T, 2);
+                    LL.lbc = @(T)T;
+                    LL.rbc = @(T)T;
+                    %T = LL \ (- res1.P_right);
+                    [T, sol] = solvebvp(LL , -res1.P_right);
+                    if sol.error > 0.001
+                        xpoints = linspace(domain_(1), domain_(2), 200);
+                        P_l = griddedInterpolant(xpoints, res1.P_right(xpoints));
+                        odefunT = @(x,T)[T(2)+zeros(size(x));  -(obj.D1(x) .* T(2) + P_l(x)) ./ obj.D2(x)];
+                        BCfun = @(ya,yb)[ya(1) yb(1)];
+                        one = chebfun(1, domain_);
+                        v0 = [one 0 * one];
+                        T1 = bvp4c(odefunT, BCfun, v0);
+                        res.T_right = chebfun(T1(:, 1) ./ res1.P_right, 'splitting', 'on');
+                    else
+                        res.T_right = chebfun(T ./ res1.P_right, 'splitting', 'on');
+                    end
+                    %plot(T);
+
+                    T2 = chebfun(res.T_right, domain2, 'splitting', 'on');
+                    if ~isempty(PDF)
+                        res.WT_right = [];
+                    else
+                        res.WT_right = sum(PDF * T2) / sum(PDF);
+                    end
+                    res.P_right = res1.P_right;
+                end
+            else
+                % function handle mode
+                %
+                %Backward Fokker Planck equation:
+                %D1(x0)*T'+D2(x0 )*T''=-1 
+                %
+                %define:
+                %T2=T';
+                %D1(x0)*T2+D2(x0)*T2'=-1
+                %
+                %yields the following 2D ODE system
+                %T2'=-(D1(x0)*T2 + 1)/D2(x0)
+                %T'=T2;
+                if ~isfield(options, 'nx')
+                    options.nx = obj.nx;
+                end
+                if ~isfield(options, 'RelTol') || isempty(options.RelTol)
+                    options.RelTol = 1E-7;
+                end
+                if ~isfield(options, 'AbsTol') || isempty(options.RelTol)
+                    options.RelTol = 1E-6;
+                end
+                options.Vectorized = 'on';
+                xpoints = linspace(res.domain(1), res.domain(2), options.nx);
+                %
+                %Reflecting means that T'==0
+                %Absorbing means that T==0
+                %this BCfun function should return the RESIDUAL
+                %ya is left yb is right boundary
+                switch BC
+                    case 'RA'
+                        BCfun = @(ya,yb)[ya(2) yb(1)];
+                    case 'AR'
+                        BCfun = @(ya,yb)[ya(1) yb(2)];
+                    case 'AA'
+                        BCfun = @(ya,yb)[ya(1) yb(1)];
+                    case 'RR'
+                        BCfun = @(ya,yb)[ya(2) yb(2)];
+                end
+                solinit = bvpinit(xpoints, initfunT);
+
+                %The BVP solver returns the structure 'sol'. 
+                %for exit time T(x)
+                try
+                    odefunT = @(x,y)[y(2,:);  -(obj.D1(x) .* y(2,:) + 1) ./ obj.D2(x)];
+                    sol = bvp4c(odefunT, BCfun, solinit, options);
+                    Tx = deval(sol, xpoints);
+                catch err
+                    disp(err.message);
+                    Tx = NaN;
+                end
+                res.T = Tx(1, :);
+                if ~isempty(PDF)
+                    pdf = griddedInterpolant(PDF.x, PDF.PDF);
+                    PDF = pdf(xpoints);
+                    res.WT = sum(PDF .* res.T) ./ sum(PDF);
+                else
+                    res.WT = [];
+                end
+                if strcmp(BC, 'AA')
+                    %first we need to determine the probabilities of leaving the
+                    %left border with BVP equation:
+                    res1 = obj.prob_exit(domain_, BC, options);
+                    %mean exit through left:
+                    res.P_left = res1.P_left;
+                    P_l = griddedInterpolant(xpoints, res1.P_left);
+                    odefunT = @(x,T)[T(2,:)+zeros(size(x));  -(obj.D1(x) .* T(2,:) + P_l(x)) ./ obj.D2(x)];
+
+                    sol = bvp4c(odefunT, BCfun, solinit, options);
+                    res.T_left = deval(sol, xpoints);
+                    res.T_left = res.T_left(1, :) ./ res.P_left;
+
+                    res.P_right = res1.P_right;
+                    P_r = griddedInterpolant(xpoints, res.P_right);
+                    odefunT = @(x,T)[T(2,:);  -(obj.D1(x) .* T(2,:) + P_r(x)) ./ obj.D2(x)];
+                    sol = bvp4c(odefunT, BCfun, solinit, options);
+                    res.T_right = deval(sol, xpoints);
+                    res.T_right = res.T_right(1, :) ./ res.P_right;
+                end
+            end
+            obj.xtra.results.mean_exit = res;
+        end
+
+        function result = runpdf(obj, varargin)
+            % This code (numerically) solves the Fokker-Planck equation.
+            % 
+            % obj.solvepdf(PDF0,options)
+            % Inputs are:
+            % PDF0: is the initial distribution of states (is a chebfun function or function handle 
+            % or a scalar number (Dirichlet delta function is then assumed).
+            %
+            % 
+            % options (optional) the pdepe options (see pdepe, for instance RelTol and AbsTol)
+            %  + additional fields:
+            %    maxtime = duration of the simulation
+            %    ntime = number of time outputs (minimal=3) (default 3)
+            %    nx = number of points in x direction (default obj.nx)
+            %
+            %  can also be entered as field, value pairs (case sensitive)
+            %
+            % Output is a structure with fields:
+            %   x = mesh of x values
+            %   t = time output values
+            %   pdfs = pdfs in time
+            % 
+            result = solvepdf(obj, varargin{:});
+            obj.xtra.results.pdfs = result;
+        end
+
+
+
+        function result = pdf(obj, pdf0, varargin)
+
+            % This code (numerically) solves the Fokker-Planck equation.
+            % 
+            % obj.pdf(PDF0,options)
+            % Inputs are:
+            % PDF0: is the initial distribution of states (is a chebfun function or function handle 
+            % or a scalar number (Dirichlet delta function is then assumed).
+            %
+            % 
+            % options (optional) the pdepe options (see pdepe, for instance RelTol and AbsTol)
+            %  + additional fields:
+            %    maxtime = duration of the simulation
+            %    ntime = number of time outputs (minimal=3) (default 3)
+            %    nx = number of points in x direction (default obj.nx)
+            %
+            %  can also be entered as field, value pairs (case sensitive)
+            %
+            % Output is a structure with fields:
+            %   x = mesh of x values
+            %   t = time output values
+            %   pdfs = all pdfs in time
+            %   PDF = last (stationary) pdf
+            % 
+            if nargin < 2
+                pdf0 = [];
+            end
+            if nargin > 3
+                options = struct(varargin{:});
+            elseif nargin == 3
+                options = varargin{1};
+            else
+                options = [];
+            end
+            if ~isfield(options, 'maxtime')
+                options.maxtime = 4000;
+            end
+            if ~isfield(options, 'ntime')
+                options.ntime = 3;
+            end
+            result = obj.solvepdf(pdf0, options);
+            result.PDF = result.pdfs(end, :);
+            %another way of determining the PDF using the effective
+            %potential
+            %integral D1/D2:
+            if isa(obj.D1, 'chebfun')
+                try
+                    h2 = 1 / obj.D2 * exp(cumsum(obj.D1 / obj.D2));
+                    xpoints = linspace(obj.domain(1), obj.domain(2), 4000);
+                    intg = trapz(xpoints, h2(xpoints));
+                    result.PDF_eq = 1 / obj.D2 * exp(cumsum(obj.D1 / obj.D2)) / intg;
+                catch
+                    result.PDF_eq = [];
+                end
+            else
+                h1 = @(x)obj.D1(x)./obj.D2(x);
+                h = integralx_fun(h1, obj.domain(1), obj.domain(2));
+                %
+                %1/D2 * exp(int(D1/D2,x))
+                h2 = @(x)1 ./obj.D2(x).*exp(h(x));
+
+                %normalize to surface = 1
+                xpoints = linspace(obj.domain(1), obj.domain(2), 4000);
+                intg = trapz(xpoints, h2(xpoints));
+                %normalized pdf
+                result.PDF_eq = @(x)1 ./obj.D2(x).*exp(h(x))./intg;
+            end
+            obj.xtra.results.pdf = result;
+        end
+
+
+
+
+        function res = survival(obj, ibasin, varargin)
+
+            % This code (numerically) calculates the survival function (Formula 1 in the main text) of the 'Langevin system' for all initial states.
+            % You can find full mathematical details in Appendix S3 which is from the following book
+            % Schuss, Z. Theory and applications of stochastic processes: an analytical approach. Vol. 170 (Springer Science & Business Media, 2009).
+            %
+            % Inputs are:
+            %
+            % ibasin = the number of the basin or 'all' or a struct with
+            % the fields "domain" and "BC"
+            % Where domain is the domain and BC the boundary value code:
+            %  'AA' = left and right absorbing
+            %  'RA' = left reflecting and right absorbing
+            %  'AR' = left absorbing and right reflecting
+            %
+            % options (optional) the pdepe options (RelTol and AbsTol for instance)
+            %    + additional fields:
+            %    time_range = range of time
+            %    ntime = number of points for output of time axis
+            %    nx = number of points in x direction
+            %    initfunc = function handle describing the initial
+            %    conditions (default = all 1)
+            % options can also be entered as field, value pairs (case
+            % sensitive)
+            % for instance:
+            % obj.survival('all','ntime',100,'AbsTol',1E-6)
+            %
+            %
+            %  
+            % IMPORTANT NOTE: 
+            % For a much better accuracy we recommend NOT to use a regular mesh for mesh_time. Instead, we
+            % recommend to use a chebychev mesh point which has 2^n points. For instance, 
+            % to generate a chebychev mesh point on the interval [0 300] of length 2^16
+            % simply type mesh_time=chebpts([0 300],2^15);
+            %
+            % Output is:
+            % structure with fields:
+            %    t = output points in time
+            %    x = meshpoints of x
+            %    survival = output of pdepe
+            %  you can use obj.plot(res) to plot the output structure
+            %
+            if nargin < 2
+                ibasin = 'all';
+            end
+            if nargin > 3
+                options = struct(varargin{:});
+            elseif nargin == 3
+                options = varargin{1};
+            else
+                options = [];
+            end
+            if isnumeric(options) && ~isempty(options) %alternatively you can only give the time_range
+                options = struct('time_range', options);
+            end
+            if ~isfield(options, 'time_range')
+                options.time_range = []; %empty is automatic (takes an extra run however)
+            end
+            if ~isfield(options, 'ntime')
+                options.ntime = 50;
+            end
+            if ~isfield(options, 'nx')
+                options.nx = obj.nx;
+            end
+            %nspace = obj.nx;
+            if ischar(ibasin) && strcmp(ibasin, 'all')
+                res = cell(1, obj.nbasin);
+                for i = 1:length(res)
+                    res{i} = obj.survival(i, options);
+                end
+                obj.xtra.results.survival = res;
+                return;
+            end
+            if isstruct(ibasin)
+                eqn = ibasin;
+            else
+                nbasin1 = obj.nbasin;
+                if ibasin > nbasin1
+                    error('langevin_eq:survival', 'basin number too large');
+                end
+                stableeq = find([obj.equilibria.stable]);
+                eqn = obj.equilibria(stableeq(ibasin));
+            end
+            domain_ = eqn.domain;
+            domain_(domain_ < obj.domain(1)) = obj.domain(1);
+            domain_(domain_ > obj.domain(2)) = obj.domain(2);
+            switch eqn.BC
+                    %absorbing = ul,0 (or ur,0)  reflecting = 0,1
+                case 'AA'
+                    BCfun = @(~, ul, ~, ur, ~)deal(ul, 0 , ur, 0); %"deal" deals the values to the 4 requested outputs
+                case 'RA'
+                    BCfun = @(~, ~, ~, ur, ~)deal(0, 1, ur, 0);
+                case 'AR'
+                    BCfun = @(~, ul, ~, ~, ~)deal(ul, 0, 0, 1);
+                case 'RR'
+                    BCfun = @(~, ~ , ~, ~, ~)deal(0, 1, 0, 1);
+                otherwise
+                    error('langevin_eq:bc', 'boundary conditions "%s" undefined',eqn.BC);
+            end
+            if ~isfield(options, 'Stats')
+                options.Stats = 'on';
+            end
+            if ~isfield(options, 'RelTol') || isempty(options.RelTol)
+                options.RelTol = 1E-6;
+            end
+            if ~isfield(options, 'AbsTol') || isempty(options.AbsTol)
+                options.AbsTol = 1E-7;
+            end
+            if ~isfield(options, 'initfun') || isempty(options.initfun)
+                options.initfun = @(x)1;
+            end
+            if isempty(obj.DD2)
+                DD2_ = diff_fun(obj.D2);
+            else
+                DD2_ = obj.DD2;
+            end
+            %we bind the functions D1 D2 and DD2_ in the anonymous function
+            if isa(obj.D1, 'chebfun')
+                %else this is much slower
+                x = linspace(min(domain_), max(domain_), 100 * options.nx);
+                d1 = griddedInterpolant(x, obj.D1(x));
+                d2 = griddedInterpolant(x, obj.D2(x));
+                dd2 = griddedInterpolant(x, DD2_(x));
+                surv_equat = @(x,t,u,DuDx)survpde(x, 0, u, DuDx ,d1,d2,dd2);
+            else
+                surv_equat = @(x,t,u,DuDx)survpde(x, 0, u, DuDx ,obj.D1, obj.D2, DD2_);
+            end
+            m = 0;
+            if isempty(options.time_range)
+                options.time_range = [0 50];
+                %                 %do a test run to find a reasonable range for the time
+                %                 %(without having too many zeros - does
+                %                 %not work very well
+                %                 options1=options;
+                %                 options1.time_range=[0 1000];
+                %                 options1.ntime = 1000;
+                %                 testrun=obj.survival(ibasin,options1);
+                %                 meansurv=max(testrun.survival,[],2);
+                %                 options.time_range=[0 find(meansurv<0.0001,1)+1];
+            end
+            if length(options.time_range) == 2
+                res.t = linspace(options.time_range(1), options.time_range(2), options.ntime)';
+            elseif length(options.time_range) == 1
+                res.t = linspace(0, options.time_range(1), options.ntime)';
+            else
+                res.t = linspace(0, 1000, options.ntime)';
+            end
+            %res.t = options.time_range; % t = linspace(0,T,N_t);  % IMPORTANT: here t is not the usual time we use for IVPs (initial value problems).
+            %Our problem here is IBVP (initial boundary value problem). Therefore considering only 3 mesh points for t does not work.
+            res.x = linspace(min(domain_), max(domain_), options.nx);
+
+            %  options = odeset('Stats', 'on', 'RelTol', 1e-6, 'AbsTol', 1e-7);
+            res.survival = pdepe(m, surv_equat, options.initfun, BCfun, res.x, res.t, options);
+            obj.xtra.results.survival = res;
+            %u = sol(:, :, 1);
+
+            %S = u(:, :);
+            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+            function [c, f, s] = survpde(x, ~, ~, DuDx, D1, D2, DD2)
+                %Survival PDE:
+                %diff(S,t) = D1(x) diff(S(x,t),x) + D2(x)*diff(diff(S(x,t),x),x)
+                %
+                %general form for pdepe (see Matlab help)
+                %>>> c(x,t,u,dudx)*diff(u,t) = x^m * diff(x^m * f(x,t,u,dudx),x) + s(x,t,u,dudx)
+                %simplify:
+                %m=0;c=1
+                %                
+                %assume f = D2*dSdx
+                %remember D2 can be dependent on x (multiplicative noise)!
+                %
+                %so product rule: diff(D2 * dSdx,x)=D2 * diff(dSdx,x)+DD2 * dSdx
+                %we only need D2*diff(dSdx,x) so we just subtract DD2*dSdx from the s term
+                %m=0:c=1:
+                %diff(u,t) = diff(f(x,t,u,dudx),x) + s(x,t,u,dudx)
+                %f = D2 * dSdx
+                %s = D1 * dSdx - DD2 * dSdx
+                %
+                c = 1;
+                f = D2(x) * DuDx;
+                s = (D1(x) - DD2(x)) * DuDx;
+            end
+
+        end
+
+
+        function set(obj, varargin)
+
+            if nargin > 1
+                if ~isstruct(varargin{1})
+                    args = struct(varargin{:});
+                else
+                    args = varargin{1};
+                end
+            end
+            if isfield(args, 'domain')
+                obj.domain = args.domain;
+                if isa(obj.D1, 'chebfun')
+                    obj.D1.domain = obj.domain;
+                end
+                if isa(obj.D2, 'chebfun')
+                    obj.D2.domain = obj.domain;
+                end
+            end
+            if isfield(args, 'timeunit')
+                obj.timeunit = args.timeunit;
+            end
+            if isfield(args, 'namex')
+                obj.namex = args.namex;
+            end
+            if isfield(args, 'nx')
+                obj.nx = args.nx;
+            end
+            if isfield(args, 'f')
+                obj.D1 = obj.set_Dfun(args.f);
+            end
+            if isfield(args, 'g')
+                obj.D2 = obj.set_Dfun(args.g, 'g');
+            end
+            if isfield(args, 'D1')
+                obj.D1 = obj.set_Dfun(args.D1);
+            end
+            if isfield(args, 'D2')
+                [obj.D2, isconstant] = obj.set_Dfun(args.D2);
+                if isconstant
+                    % the derivative is zero
+                    obj.DD2 = obj.set_Dfun(0);
+                end
+            end
+            if isfield(args, 'DD2')
+                obj.DD2 = obj.set_Dfun(args.DD2);
+            end
+            if isfield(args, 'equilibria')
+                obj.equilibria = args.equilibria;
+            end
+            if isfield(args, 'nx')
+                obj.nx = args.nx;
+            end
+        end
+    end
+end
+
+function [tout, yout] = euler(odefunct, tspan, y0, options)
+    %Euler integration
+    if (nargin < 4)
+        %if there are no valid options use default stepsize
+        delta = 0.01;
+        options.StepSize = 0.3;
+    else
+        %use the option StepSize as step size
+        if ~isfield(options, 'StepSize')
+            options.StepSize = options.MaxStep;
+        end
+        if isempty(options.StepSize)
+            options.StepSize = 0.1;
+        end
+        delta = options.StepSize;
+    end
+    if nargin < 4
+        nonNegative = [];
+    else
+        nonNegative = odeget(options, 'NonNegative', []);
+    end
+    anyNonNegative = ~isempty(nonNegative);
+    haveOutputFcn = ~isempty(options.OutputFcn);
+    outputFcn = options.OutputFcn;
+    if haveOutputFcn
+        feval(outputFcn, tspan, y0, 'init');
+    end
+    % Test that tspan is internally consistent.
+    tspan = tspan(:);
+    ntspan = length(tspan);
+    if ntspan == 1
+        t0 = 0;
+        next = 1;
+    else
+        t0 = tspan(1);
+        next = 2;
+    end
+    tfinal = tspan(ntspan);
+    if t0 == tfinal
+        error('euler:tpan', 'The last entry in tspan must be different from the first entry.');
+    end
+    tdir = sign(tfinal - t0);
+    if any(tdir * (tspan(2:ntspan) - tspan(1:ntspan - 1)) <= 0)
+        error('euler:tspan', 'The entries in tspan must strictly increase or decrease.');
+    end
+    t = t0;
+    y = y0(:);
+    neq = length(y);
+    %adapt delta if there should be given more output
+    step_tspan = median(diff(tspan));
+    delta = min(delta, step_tspan);
+    % Set the output flag.
+
+    outflag = ntspan > 2; % output only at tspan points
+
+    % Allocate memory if we're generating output.
+    delta = delta * tdir;
+
+    if nargout > 0
+        if outflag % output only at tspan points
+            tout = tspan;
+            outflag = delta ~= step_tspan;
+            yout = nan(ntspan, neq);
+        else
+            tout = transpose(t0:delta:tfinal);
+            if tout(end) < tfinal %if tfinal cannot divided in delta's
+                tout(end + 1) = tfinal;
+            end
+ 
+            yout = nan(size(tout, 1), neq);
+        end
+        nout = 1;
+        tout(nout) = t;
+        yout(nout, :) = transpose(y);
+    end
+    %
+    %MAIN LOOP
+    %evaluate the odefunction for the next time steps
+    %fold=[];
+    running = 1;
+    while running
+        f = feval(odefunct, t, y);
+        %  simple Euler
+        ynew = y + f .* delta;
+        if anyNonNegative
+            ynew(nonNegative) = max(ynew(nonNegative), 0);
+        end
+ 
+ 
+        tnew = t + delta;
+        if tnew >= tfinal
+            running = 0;
+        end
+ 
+        if ~outflag % computed points, no refinement only the last value
+            nout = nout + 1;
+            if ~running
+                if nout > length(tout)
+                    nout = length(tout);
+                end
+                t1 = tout(nout);
+                yout(nout, :) = transpose(y + (ynew - y) ./ (tnew - t) .* (t1 - t));
+            else
+                yout(nout, :) = transpose(ynew);
+            end
+            tnew = tout(nout);
+            if haveOutputFcn
+                if feval(outputFcn, tnew, transpose(ynew), '')
+                    ndx = ~isnan(yout(:, 1));
+                    yout = yout(ndx, :);
+                    tout = tout(ndx);
+                    running = false;
+                end
+            end
+        elseif (tdir * (tnew - tspan(next)) >= 0) % at tspan, tspan assumed to be larger than delta
+            nout = nout + 1;
+            t1 = tout(nout);
+            y1 = transpose((y + (ynew - y) ./ (tnew - t) .* (t1 - t)));
+            yout(nout, :) = y1;
+            next = next + 1;
+            if haveOutputFcn
+                if feval(outputFcn, t1, y, '')
+                    ndx = ~isnan(yout(:, 1));
+                    yout = yout(ndx, :);
+                    tout = tout(ndx);
+                    running = false;
+                end
+            end
+        end
+ 
+        y = ynew;
+        t = tnew;
+    end
+end
+
+function fun = integralx_fun(afun, ystart, xstart)
+    if isa(afun, 'chebfun')
+        fun = cumsum(afun);
+    else
+        if nargin < 2
+            ystart = 0;
+        end
+        if nargin < 3
+            xstart = 0;
+        end
+        h = @(x,t)afun(x);
+        fun = @(timespan)myode45(h,timespan,ystart,xstart);
+    end
+end
+
+function y = myode45(h, timespan, t0, x0)
+    if length(timespan) == 1
+        timespan = [t0 timespan];
+        [~, y] = ode45(h, timespan, x0);
+        y = y(end);
+    else
+        [~, y] = ode45(h, timespan(:), x0);
+        if numel(y) < numel(timespan)
+            y(end + 1:numel(timespan)) = NaN;
+        end
+        y = reshape(y, size(timespan));
+    end
+end
+
+function fun = diff_fun(afun, dt)
+    if nargin < 3
+        dt = 1E-7; %not too small for rounding errors
+    end
+    if isa(afun, 'chebfun')
+        fun = diff(afun);
+    elseif isa(afun, 'function_handle')
+        fun = @(x)(afun(x+dt/2)-afun(x-dt/2))/dt;
+    else
+        error('langevin:diff', 'type of function not supported');
+    end
+end
+
+function xout = simulate_vector(afun, x)
+    xout = zeros(size(x));
+    for i = 1:numel(x)
+        xout(i) = afun(x(i));
+    end
+end
+
+function rootsx = roots_fun(afun, dom)
+    if isa(afun, 'chebfun')
+        rootsx = roots(afun);
+    else
+        % find zeros without precision
+        x = linspace(dom(1), dom(2), 100);
+        res = afun(x);
+        ndx = diff(sign(res)) ~= 0;
+        rootsx = x(ndx);
+        %adapt with precision
+        for i = length(rootsx): -1:1
+            if isnan(res(i))
+                rootsx(i) = [];
+            else
+                rootsx(i) = fzero(afun, rootsx(i));
+            end
+        end
+    end
+end
+
+function res = simulate_rng(randseed, odefun, tspan, y0, options)
+    rng(randseed)
+    [res.t, res.y] = euler(odefun, tspan, y0, options);
+end
+
+
+% -------------------------------------------------------------------------
diff --git a/sys/sys2/loadlifecells.m b/sys/sys2/loadlifecells.m
index 76b14d677b63bb3d24387b539e1eda77becd3e7a..da4fd4c62771a3388cfef6467846d1f1c5c596b9 100644
--- a/sys/sys2/loadlifecells.m
+++ b/sys/sys2/loadlifecells.m
@@ -2,6 +2,7 @@
 % load one of a large number of patterns for Conways Game of Life, that were
 % compiled by Alan Hensel and others. Downloaded from:
 % http://www.argentum.freeserve.co.uk/lex_home.htm.
+% http://www.radicaleye.com/lifepage/lexicon.html
 %
 % (p1) = still life (period 1)
 % (p4) = period 4
diff --git a/sys/sys2/lyapspect.m b/sys/sys2/lyapspect.m
index 3fde21f8ce3c911569a1ed4884d34394f2376947..ac4264a086c2a043c0c4add021a584542a190795 100644
--- a/sys/sys2/lyapspect.m
+++ b/sys/sys2/lyapspect.m
@@ -26,8 +26,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('lyapspect')">commands lyapspect</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function [res] = lyapspect(varargin)
     %(ndays,step,stepjac)
     global g_grind t;
diff --git a/sys/sys2/makecartesian.m b/sys/sys2/makecartesian.m
index a56197951cb444dc07901f16532e8d574e3985b7..e380ad39aa498376185a4688940757e28b7ba1e4 100644
--- a/sys/sys2/makecartesian.m
+++ b/sys/sys2/makecartesian.m
@@ -32,8 +32,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('makecartesian')">commands makecartesian</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function makecartesian(varargin)
     global g_grind
     fieldnams = {'radiusvar', 'U1', 'the name of the radius variable (default ''r'')', 'r'; ...
diff --git a/sys/sys2/null.m b/sys/sys2/null.m
index 7421cf061ca39c7ccb9505f4cac50abd584493b7..c36ad960de1343ce3fafb9b8dced7841b9ad37c3 100644
--- a/sys/sys2/null.m
+++ b/sys/sys2/null.m
@@ -34,8 +34,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('null')">commands null</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function Z = null(varargin)
     %(npoints, opt, opt2)
     global g_grind ;
diff --git a/sys/sys2/open_matcont_gui.m b/sys/sys2/open_matcont_gui.m
index 36b43d701e90491dd638643d8112c626605fccb9..c0b8ba5d8fc882357eef9b93326d490614ec6c3c 100644
--- a/sys/sys2/open_matcont_gui.m
+++ b/sys/sys2/open_matcont_gui.m
@@ -20,8 +20,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('open_matcont_gui')">commands open_matcont_gui</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function open_matcont_gui(varargin)
     global g_grind;
     i_parseargs('', '', '', varargin);
diff --git a/sys/sys2/perturb.m b/sys/sys2/perturb.m
index 6a2039d34d394328a70dc44a5b4ac78bc47b3be7..789699ea0203e2f68a8980c0de992a863b129dac 100644
--- a/sys/sys2/perturb.m
+++ b/sys/sys2/perturb.m
@@ -29,8 +29,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('perturb')">commands perturb</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function [pert, x] = perturb(varargin)
     %(dir, persize,u,del)
     if (nargin > 2) || (nargout > 0) && length(which('perturb', '-all')) > 1
diff --git a/sys/sys2/potential.m b/sys/sys2/potential.m
index 2b3698f5c9bed8d390cbd000f340764e422d151e..6f4d4aad85f0a0fbc238215d768ebcccb9ce2233 100644
--- a/sys/sys2/potential.m
+++ b/sys/sys2/potential.m
@@ -35,8 +35,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('potential')">commands potential</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function [xs, pot] = potential(varargin)
     %(VRange, npoints, only2D)
     global g_grind;
diff --git a/sys/sys2/quasipot.m b/sys/sys2/quasipot.m
index 8e87946be60b153c5999e59822798a1161bfdbed..bcdfda8d70ad92a5945c8a5089831121faca87a1 100644
--- a/sys/sys2/quasipot.m
+++ b/sys/sys2/quasipot.m
@@ -49,8 +49,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('quasipot')">commands quasipot</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $
 function res = quasipot(varargin)
     global g_grind g_quasipot;
     if isempty(g_quasipot)
diff --git a/sys/sys2/read_grindversion.m b/sys/sys2/read_grindversion.m
new file mode 100644
index 0000000000000000000000000000000000000000..b298ab308c6e0714cf760353b5db33cf347beab2
--- /dev/null
+++ b/sys/sys2/read_grindversion.m
@@ -0,0 +1,56 @@
+
+function str = read_grindversion(url_or_file)
+    %reads the grind version and file locations from an url or filename
+    if nargin == 0
+        url_or_file = 'http://sparcs-center.org/grindfiles/grindversion.txt';
+    end
+    if strncmp(url_or_file, 'https:', 6) || strncmp(url_or_file, 'http:', 5)
+        s = webread(url_or_file, weboptions('contenttype', 'text'));
+        
+    else
+        s = evalc(['type ' url_or_file]);
+    end
+    s = regexp(s, '[^=\n]*', 'match');
+    str = struct(s{:});
+    f = fieldnames(str);
+    for i = 1:length(f)
+        if strcontains(f{i}, '_url')
+            % [~, name, ext] = fileparts(str.(f{i}));
+            % str.([f{i}(1:end - 4) '_file']) = [name ext];
+            %for some reason matlab removes \\ while reading url
+            str.(f{i}) = regexprep(str.(f{i}), 'http:[\/]([^\/].*)', 'http://$1');
+            str.(f{i}) = regexprep(str.(f{i}), 'https:[\/]([^\/].*)', 'https://$1');
+        end
+    end
+    str.current_grind_version = '';
+    str.current_grind_build = '';
+    str.current_matcont = [];
+    str.current_matcontm = [];
+    str.current_coco = [];
+    if exist('grind.cfg', 'file')
+        fid = fopen('grind.cfg', 'r');
+        lines = textscan(fid, '%s', 'delimiter', '\n', 'whitespace', '');
+        lines = lines{1};
+        fclose(fid);
+        lines = regexp(lines, '[^=\n]*', 'match');
+        for i = 1:length(lines)
+            if exist(lines{i}{2}, 'dir')
+                str.(lines{i}{1}) = lines{i}{2};
+            end
+        end
+    end
+    if exist('use', 'file')
+        fid = fopen('use.m', 'r');
+        while ~feof(fid)
+            line = fgetl(fid);
+            f = strfind(line, 'Revision:');
+            if ~isempty(f)
+                f1 = strfind(line, '$');
+                str.current_grind_version = strtrim(line(f + 9:f1(1) - 1));
+                f = strfind(line, 'Date:');
+                str.current_grind_build = strtrim(line(f + 5:f1(end) - 1));
+            end
+        end
+        fclose(fid);
+    end
+end
diff --git a/sys/sys2/run_parallel.m b/sys/sys2/run_parallel.m
index 26373573a5d304d30ec2e29bbd259af91d09b839..e099b2a345d936ae79225c384a7994dab15f1a52 100644
--- a/sys/sys2/run_parallel.m
+++ b/sys/sys2/run_parallel.m
@@ -28,8 +28,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('run_parallel')">commands run_parallel</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function res = run_parallel(varargin)
     function cpar = getpar(j, cpar)
         if ~isempty(args.parvalues)
diff --git a/sys/sys2/stochast_heun.m b/sys/sys2/stochast_heun.m
index c0226fd76f20a6e7081b4c2a5a2d57bad62912f7..3f5afa314e305d8e1a45e5fddd9e512b37776d44 100644
--- a/sys/sys2/stochast_heun.m
+++ b/sys/sys2/stochast_heun.m
@@ -20,8 +20,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('stochast_heun')">commands stochast_heun</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [tout, yout] = stochast_heun(funcs, tspan, y0, options)
     global g_grind;
     if ~isa(funcs, 'cell')
@@ -47,10 +47,10 @@ function [tout, yout] = stochast_heun(funcs, tspan, y0, options)
         haveOutputFcn = false;
         isIto = true;
     else
-        nonNegative = odeget(options, 'NonNegative', [], 'fast');
-        haveOutputFcn = ~isempty(odeget(options, 'OutputFcn', [], 'fast'));
-        outputFcn = odeget(options, 'OutputFcn', [], 'fast');
-        SDEmethod = odeget(options, 'SDEmethod', [], 'fast');
+        nonNegative = odeget(options, 'NonNegative', []);
+        haveOutputFcn = ~isempty(odeget(options, 'OutputFcn', []));
+        outputFcn = odeget(options, 'OutputFcn', []);
+        SDEmethod = odeget(options, 'SDEmethod', []);
         if isempty(SDEmethod)
             isIto = true;
         else
diff --git a/sys/sys2/time.m b/sys/sys2/time.m
index cd05267fc5615f955b360548c2aea467816af98c..16938d29e590faf43142c52165a7e8679087c7ac 100644
--- a/sys/sys2/time.m
+++ b/sys/sys2/time.m
@@ -31,8 +31,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('time')">commands time</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [outmat, leg] = time(varargin)
     if nargout > 0
         [outmat, leg] = i_time(varargin{:});
diff --git a/sys/sys2/val.m b/sys/sys2/val.m
index 00699d75040071ea64673666c2459636bbe15fe0..847f84bfdb6de4520041488bdbc7e6bd4fcb19ee 100644
--- a/sys/sys2/val.m
+++ b/sys/sys2/val.m
@@ -18,8 +18,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('val')">commands val</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function v = val(varargin)
     %(full, atitle)
     global g_grind g_Y;
diff --git a/sys/sys2/z1test.m b/sys/sys2/z1test.m
index 37deab988128eed4d4112d6679ff3e5958e738e8..b0b69f869760335044cd6370ab3c3d4d013952e0 100644
--- a/sys/sys2/z1test.m
+++ b/sys/sys2/z1test.m
@@ -32,8 +32,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('z1test')">commands z1test</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:40 $
 function results = z1test(x)
 
     % This function is adapted from code from Paul Matthews:
diff --git a/sys/takens.m b/sys/takens.m
index d359ea68a3b76a368483db977a29ed2055fd597e..1952bf41b928103f18299a9043d74a72a9867ac9 100644
--- a/sys/takens.m
+++ b/sys/takens.m
@@ -15,8 +15,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('takens')">commands takens</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function takens(varargin)
     global g_Y g_t t g_grind;
     fieldnams = {'timelag', 'n>0', 'time lag for the Takens plot', 1}';
diff --git a/sys/timesens.m b/sys/timesens.m
index 0007ed7b688dcf536d8d2ea282350a4c4f399793..b5fd9b5d921c72dd29cab5837f484dafe04196eb 100644
--- a/sys/timesens.m
+++ b/sys/timesens.m
@@ -42,8 +42,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('timesens')">commands timesens</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [result, vtitles, ptitles] = timesens(varargin)
     global g_Y g_t t g_grind g_sens g_paranal; %#ok<GVMIS> 
     evalin('base', 'global g_sens');
diff --git a/sys/torus.m b/sys/torus.m
index b2f77cde913dcd567a29f347d6eeca75716fbc76..ce17f9a5496af0dad8bd10bd4af41584625c487d 100644
--- a/sys/torus.m
+++ b/sys/torus.m
@@ -6,6 +6,7 @@
 %   TORUS PERIOD XSTART - create torus plot with a period of PERIOD steps. The x axis 
 %   starts at -XSTART.           
 %   TORUS('argname',argvalue,...) - Valid argument <a href="matlab:commands func_args">name-value pairs</a> [with type]:
+%     'hax' [general] - handle of the axis to write
 %     'period' [number>0] - the period of the torus.
 %     't' [number] - plot till time t, NaN=to end
 %     'xstart' [number] - the x axis starts at -XSTART
@@ -16,13 +17,14 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('torus')">commands torus</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function torus(varargin)
     %(period,increment)
     global g_t g_Y t g_grind;
     fieldnams = {'period', 'n>0', 'the period of the torus.', 365;  ...
         'xstart', 'n', 'the x axis starts at -XSTART', 1;  ...
+        'hax', '', 'handle of the axis to write', [];  ...
         't', 'n', 'plot till time t, NaN=to end', nan}';
     args = i_parseargs(fieldnams, 'period,xstart', '', varargin);
     i_parcheck;
@@ -32,7 +34,9 @@ function torus(varargin)
     if ~isfield(args, 'xstart')
         args.xstart = 1;
     end
-
+    if ~isfield(args, 'hax')
+        args.hax = [];
+    end
 
     N0 = i_initvar;
     if i_settingschanged(N0)
@@ -43,9 +47,13 @@ function torus(varargin)
     if ~iX.isvar || ~iY.isvar
         error('GRIND:torus:NoStatevars', 'Error: there are no state variables on the axes, use ax to set the first 2 axes');
     end
-    hfig = i_makefig('torus');
-
-    hld = ishold;
+    if isempty(args.hax)
+       hfig = i_makefig('torus');
+       args.hax=gca;
+    else
+        hfig=get(args.hax,'parent');
+    end
+    hld = ishold(args.hax);
     
     if isfield(args, 't')
         ft = find(g_t >= args.t);
@@ -55,17 +63,17 @@ function torus(varargin)
         ts = g_t(1:ft, :);
         Ys = g_Y(1:ft, :);
         [X1, Y1, Z1] = toruscoord(ts, Ys(:, iX.no), Ys(:, iY.no), args.period, args.xstart);
-        hh = findobj(gcf, 'tag', 'dataline');
+        hh = findobj(hfig, 'tag', 'dataline');
         if isempty(hh)
             [X2, Y2, Z2] = toruscoord(g_t, g_Y(:, iX.no), g_Y(:, iY.no), args.period, args.xstart);
             plottorus(hfig, X2, Y2, Z2, args);
         end
         set(hh, 'XData', X1, 'YData', Y1, 'ZData', Z1);
-        hh = findobj(gcf, 'tag', 'where');
+        hh = findobj(hfig, 'tag', 'where');
         
         if isempty(hh)
-            hold on
-            plot3(X1(end), Y1(end), Z1(end), 'ro', 'MarkerFaceColor', 'r', 'tag', 'where');
+            hold(args.hax,'on');
+            plot3(args.hax,X1(end), Y1(end), Z1(end), 'ro', 'MarkerFaceColor', 'r', 'tag', 'where');
         else
             set(hh, 'XData', X1(end), 'YData', Y1(end), 'ZData', Z1(end));
         end
@@ -73,38 +81,42 @@ function torus(varargin)
     end
     [X1, Y1, Z1] = toruscoord(g_t, g_Y(:, iX.no), g_Y(:, iY.no), args.period, args.xstart);
     plottorus(hfig, X1, Y1, Z1, args);
-    if ~hld
-        hold off;
-    end
     us1.period = args.period;
     us1.increment = args.xstart;
     set(hfig, 'userdata', us1);
     addreplaydata(hfig)
+    if ~hld
+        hold off;
+    end
 end
 
 function plottorus(hfig, X1, Y1, Z1, args)
     global g_grind;
-    plot3(X1, Y1, Z1, 'tag', 'dataline');
+    hax=findobj(hfig,'type','axes');
+    if isempty(hax)
+        hax=gca;
+    end
+    plot3(hax,X1, Y1, Z1, 'tag', 'dataline');
     i_plotdefaults(hfig);
     if ~isoctave && verLessThan('matlab', '8.4.0')
-        set(gca, 'drawmode', 'fast');
+        set(hax, 'drawmode', 'fast');
     else
-        set(gca, 'SortMethod', 'depth');
+        set(hax, 'SortMethod', 'depth');
     end
-
-    hold on;
-    box off;
-    lims = max(abs([get(gca, 'xlim'), get(gca, 'ylim')]));
-    zlim = get(gca, 'zlim');
-    plot3([0; 0], [0; 0], get(gca, 'zlim'), 'k')
-    plot3([0; 0], [ - lims, lims], [zlim(1), zlim(1)], 'k');
-    plot3([ -lims, lims], [0; 0], [zlim(1), zlim(1)], 'k');
-    xlabel(['sin(t)*' g_grind.xaxis.var]);
-    ylabel(['cos(t)*' g_grind.xaxis.var]);
-    zlabel(g_grind.yaxis.var);
+    hold(hax,'on');
+ %  hold on;
+    box(hax,'off');
+    lims = max(abs([get(hax, 'xlim'), get(hax, 'ylim')]));
+    zlim = get(hax, 'zlim');
+    plot3(hax,[0; 0], [0; 0], get(hax, 'zlim'), 'k')
+    plot3(hax,[0; 0], [ - lims, lims], [zlim(1), zlim(1)], 'k');
+    plot3(hax,[ -lims, lims], [0; 0], [zlim(1), zlim(1)], 'k');
+    xlabel(hax,['sin(t)*' g_grind.xaxis.var]);
+    ylabel(hax,['cos(t)*' g_grind.xaxis.var]);
+    zlabel(hax,g_grind.yaxis.var);
     t1 = 0:0.05:6.5;
-    plot3(sin(t1) * lims, cos(t1) * lims, zlim(1) * ones(1, length(t1)), 'k');
-    plot3(sin(t1) * args.xstart, cos(t1) * args.xstart, zlim(1) * ones(1, length(t1)), 'k');
+    plot3(hax,sin(t1) * lims, cos(t1) * lims, zlim(1) * ones(1, length(t1)), 'k');
+    plot3(hax,sin(t1) * args.xstart, cos(t1) * args.xstart, zlim(1) * ones(1, length(t1)), 'k');
 end
 
 function [X1, Y1, Z1] = toruscoord(ts, X, Y, period, xstart)
@@ -132,7 +144,7 @@ end
 
 function onend(hax,flag)
 global g_t;
-   torus('t',g_t(end));
+   torus('t',g_t(end),'hax',hax);
    hh = findobj(hax, 'tag', 'where');
    delete(hh);
 
@@ -154,12 +166,15 @@ function onstart(hax)
     end
 end
 function t = replaycallback(hax, avar, relt)
-    global g_grind; %#ok<GVMIS>
+   % global g_grind; %#ok<GVMIS>
     t = [];
-    if ishandle(hax) && isfield(g_grind, 'viewcells') && isempty(avar) || strcmp(avar, 't')
+    if ishandle(hax) && strcmp(avar,'t') %|| strcmp(avar, g_paranal.run.pars{1})
         ud = get(hax, 'userdata');
+        if ~isfield(ud,'replay')
+            disp('');
+        end
         t = ud.replay.settings.tlim(1) + relt * (ud.replay.settings.tlim(end) - ud.replay.settings.tlim(1));
-        torus('t',t);
+        torus('t',t,'hax',hax);
 %         ser = get(hax, 'children');
 %         if isfield(ud, 'replay')
 %             i = ud.replay.no;
diff --git a/sys/trdet.m b/sys/trdet.m
index 7ce74ed5fd175c38e76124461cc34fddd2c8daa9..1415a0378dbf1fe703c0512733b2580ef008c202 100644
--- a/sys/trdet.m
+++ b/sys/trdet.m
@@ -32,8 +32,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('trdet')">commands trdet</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [res1,htmlres] = trdet(varargin)
     %(donumerical)
     global g_grind;
diff --git a/sys/upcells.m b/sys/upcells.m
index 60facffdcef47e7bd13a45c05cb7f070b9a2257c..a8d059cd2db5997cbb24e9a52b15fb56b469b853 100644
--- a/sys/upcells.m
+++ b/sys/upcells.m
@@ -16,8 +16,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('upcells')">commands upcells</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function result = upcells(N, bordered, aValue)
     if nargin < 2
         bordered = 'neumann';
diff --git a/sys/updategrind.m b/sys/updategrind.m
index 301cac6e8ab250738c0a2500ed1bf612879bcde0..774da1b5a1b1312cb328982f7e95f8578d0329ae 100644
--- a/sys/updategrind.m
+++ b/sys/updategrind.m
@@ -10,8 +10,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('updategrind')">commands updategrind</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function updategrind
     curdir = pwd;
     try
diff --git a/sys/use.m b/sys/use.m
index 070d2f9f8f8d3f96d530063c9bcb008c3103c9e1..f33121949114e2544adb70fd80246eb68110e30e 100644
--- a/sys/use.m
+++ b/sys/use.m
@@ -16,8 +16,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('use')">commands use</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function use(varargin)
     %amodel = [];
     %if the model name has spaces it can be read as separate arguments
diff --git a/sys/varcopy.m b/sys/varcopy.m
index 09ed248c8fba5a1bed0284d052901c53151a4489..b1fc561aa879bc37942422fb793f92b008769852 100644
--- a/sys/varcopy.m
+++ b/sys/varcopy.m
@@ -14,8 +14,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('varcopy')">commands varcopy</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function varcopy(A, precision)
     if nargin == 0
         prompt = {'Enter variable:', 'Number of digits to copy:'};
diff --git a/sys/varpaste.m b/sys/varpaste.m
index 42a8e3c6cae05b74900e4fed061edceb418ab67c..1abd449ba43209dc63c5b706185cefb32b296657 100644
--- a/sys/varpaste.m
+++ b/sys/varpaste.m
@@ -34,8 +34,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('varpaste')">commands varpaste</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function A = varpaste(varargin) %forcetype, filename)
 
     fieldnams = {'class', 'e[n+umeric|ce+ll|ch+ar|string|da+taset|t+able|l+ogical|int8|uint8|int16|uint16|int32|uint32|int64|uint64|si+ngle|do+uble]#E', 'the class of the resulting variable (default=''numeric'')'; ...
diff --git a/sys/vector.m b/sys/vector.m
index 9726d8c06f754843d87361b607c7ebbf5f7413d9..b6419a97692e0dfbdf9b345e4e860d7821e1b483 100644
--- a/sys/vector.m
+++ b/sys/vector.m
@@ -20,8 +20,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('vector')">commands vector</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function [X1, Y1, Vect1] = vector(varargin)
     %(igrid, opt, opt2)
     fieldnams = {'npoints', 'i>0&length(i)<=2', 'size of the grid for the arrows', 20; ...
diff --git a/sys/vectplot.m b/sys/vectplot.m
index 4bcc3f35b171c4596ce52333b22470c88756fe20..7777c47c52bc05255cae9edd439a60575a393521 100644
--- a/sys/vectplot.m
+++ b/sys/vectplot.m
@@ -42,8 +42,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('vectplot')">commands vectplot</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function vectplot(varargin)
     %function vectplot(flag, no,xyzax, atype, varargin)
     global g_grind t g_t g_Y; %#ok<GVMIS>
diff --git a/sys/viewcells.m b/sys/viewcells.m
index d23018bc441183ac2a284675e7982461dbd81209..8ea711135fa630643ce6039bc24a1b6b28980785 100644
--- a/sys/viewcells.m
+++ b/sys/viewcells.m
@@ -35,8 +35,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('viewcells')">commands viewcells</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $
 function viewcells(varargin)
     global t g_grind g_Y g_t; %#ok<GVMIS>
     %opengl software
diff --git a/sys/vismod.m b/sys/vismod.m
index 729563abdbdc655fb48462d853346e3fb65249f2..feba471a129596dce054208d2cdbfb828494460a 100644
--- a/sys/vismod.m
+++ b/sys/vismod.m
@@ -32,8 +32,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('vismod')">commands vismod</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:40 $
 function vismod(varargin)
     global g_grind; %#ok<GVMIS> 
     if ~exist('i_use', 'file')
diff --git a/sys/where.m b/sys/where.m
index 78253be1bbddab40b8ff860dd9f710d978d95ab0..9f5050147f36ed840f7812683cd4a22ae31d1ce3 100644
--- a/sys/where.m
+++ b/sys/where.m
@@ -23,8 +23,8 @@
 %   Reference page in Help browser:
 %      <a href="matlab:commands('where')">commands where</a>
 
-%   Copyright 2023 WUR
-%   Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $
+%   Copyright 2024 WUR
+%   Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:40 $
 function h1 = where(varargin)
     %(apen, apen1)
     global g_Y g_t g_grind t; %#ok<GVMIS>