diff --git a/matlab/perfect-foresight-models/construct_simulation_dseries.m b/matlab/perfect-foresight-models/construct_simulation_dseries.m
new file mode 100644
index 0000000000000000000000000000000000000000..17a62b7ad5d8cc7dfcd61c5316bb688bceea0872
--- /dev/null
+++ b/matlab/perfect-foresight-models/construct_simulation_dseries.m
@@ -0,0 +1,37 @@
+function ts = construct_simulation_dseries(oo_, M_, first_simulation_period)
+% Returns a dseries object for the perfect foresight simulation.
+% Merges it with the contents of the datafile option on the initval_file command if provided.
+% first_simulation_period may be empty, in which case some default value will be used.
+
+% Copyright © 2021-2024 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
+
+if isempty(first_simulation_period)
+    if isfield(oo_, 'initval_series') && ~isempty(oo_.initval_series)
+        first_simulation_period = oo_.initval_series.dates(1)+(M_.orig_maximum_lag-1);
+    else
+        first_simulation_period = dates(1,1);
+    end
+end
+
+ts = dseries([transpose(oo_.endo_simul(1:M_.orig_endo_nbr,:)), oo_.exo_simul], ...
+             first_simulation_period - M_.maximum_lag, [M_.endo_names(1:M_.orig_endo_nbr); M_.exo_names]);
+
+if isfield(oo_, 'initval_series') && ~isempty(oo_.initval_series)
+    names = ts.name;
+    ts = merge(oo_.initval_series{names{:}}, ts);
+end
diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver.m b/matlab/perfect-foresight-models/perfect_foresight_solver.m
index 5b5c71d2d1869ea28264ae2955d074e14f342ee6..cc4f2d60a0a5067a61b482abfed15bf1a2f2659a 100644
--- a/matlab/perfect-foresight-models/perfect_foresight_solver.m
+++ b/matlab/perfect-foresight-models/perfect_foresight_solver.m
@@ -274,19 +274,8 @@ if ~isempty(per_block_status)
     oo_.deterministic_simulation.block = per_block_status;
 end
 
-if isempty(first_simulation_period)
-    if isfield(oo_, 'initval_series') && ~isempty(oo_.initval_series)
-        first_simulation_period = oo_.initval_series.dates(1)+(M_.orig_maximum_lag-1);
-    else
-        first_simulation_period = dates(1,1);
-    end
-end
-
-ts = dseries([transpose(oo_.endo_simul(1:M_.orig_endo_nbr,:)), oo_.exo_simul], first_simulation_period - M_.maximum_lag, [M_.endo_names(1:M_.orig_endo_nbr); M_.exo_names]);
-
-if isfield(oo_, 'initval_series') && ~isempty(oo_.initval_series)
-    names = ts.name;
-    ts = merge(oo_.initval_series{names{:}}, ts);
+if nargout > 1
+    ts = construct_simulation_dseries(oo_, M_, first_simulation_period);
 end
 
 oo_.gui.ran_perfect_foresight = oo_.deterministic_simulation.status;
diff --git a/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_solver.m b/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_solver.m
index c5d9a10e39ee5d84277f69337b6d17576e3682cd..0ea7575fcc12bb2510bf787f36875123e4b97a9e 100644
--- a/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_solver.m
+++ b/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_solver.m
@@ -1,4 +1,4 @@
-function oo_=perfect_foresight_with_expectation_errors_solver(M_, options_, oo_)
+function [oo_, ts] = perfect_foresight_with_expectation_errors_solver(M_, options_, oo_)
 % INPUTS
 %   M_                  [structure] describing the model
 %   options_            [structure] describing the options
@@ -28,7 +28,7 @@ if options_.pfwee.constant_simulation_length && ~isempty(options_.simul.last_sim
     error('Options constant_simulation_length and last_simulation_period cannot be used together')
 end
 
-periods = get_simulation_periods(options_);
+[periods, first_simulation_period] = get_simulation_periods(options_);
 
 % Retrieve initial paths built by pfwee_setup
 % (the versions in oo_ will be truncated before calling perfect_foresight_solver)
@@ -114,3 +114,7 @@ end
 % Set final paths
 oo_.endo_simul = endo_simul;
 oo_.exo_simul = exo_simul;
+
+if nargout > 1
+    ts = construct_simulation_dseries(oo_, M_, first_simulation_period);
+end
diff --git a/preprocessor b/preprocessor
index a88ac75488d86a51f8febbead4692769722881c1..3d0989774b282fb2d875e9880be15e626cc69c40 160000
--- a/preprocessor
+++ b/preprocessor
@@ -1 +1 @@
-Subproject commit a88ac75488d86a51f8febbead4692769722881c1
+Subproject commit 3d0989774b282fb2d875e9880be15e626cc69c40