diff --git a/bfps/DNS.py b/bfps/DNS.py
index e6ace758a1f6efb240cfa0655cc661a83a1ab6e2..b22a309a1494ee1a953c3e19e53e6548d067d619 100644
--- a/bfps/DNS.py
+++ b/bfps/DNS.py
@@ -120,6 +120,7 @@ class DNS(_code):
         return None
     def generate_default_parameters(self):
         # these parameters are relevant for all DNS classes
+        self.parameters['fftw_planner_type'] = 'FFTW_ESTIMATE'
         self.parameters['dealias_type'] = int(1)
         self.parameters['dkx'] = float(1.0)
         self.parameters['dky'] = float(1.0)
diff --git a/bfps/PP.py b/bfps/PP.py
index 27a359287dca65f01f2a66eaaef1fe56c13862fc..867864e0b46b1b2356c8e6dc133ad4d17f88efee 100644
--- a/bfps/PP.py
+++ b/bfps/PP.py
@@ -118,6 +118,7 @@ class PP(_code):
         return None
     def generate_default_parameters(self):
         # these parameters are relevant for all PP classes
+        self.parameters['fftw_planner_type'] = 'FFTW_ESTIMATE'
         self.parameters['dealias_type'] = int(1)
         self.parameters['dkx'] = float(1.0)
         self.parameters['dky'] = float(1.0)
diff --git a/bfps/TEST.py b/bfps/TEST.py
index cd4d3e4a82874c53b9dff5134e1a1da0067a61a7..2a8b37ba81d7ea267d4590fe13c3ed5cf0a72616 100644
--- a/bfps/TEST.py
+++ b/bfps/TEST.py
@@ -119,6 +119,7 @@ class TEST(_code):
         return None
     def generate_default_parameters(self):
         # these parameters are relevant for all TEST classes
+        self.parameters['fftw_planner_type'] = 'FFTW_ESTIMATE'
         self.parameters['dealias_type'] = int(1)
         self.parameters['dkx'] = float(1.0)
         self.parameters['dky'] = float(1.0)
diff --git a/bfps/cpp/fftw_interface.hpp b/bfps/cpp/fftw_interface.hpp
index 7f5e014400c86ffe4caa594a67e1756c890c6503..0a840dd5ba3d864b36271515faa7cb81f3042c01 100644
--- a/bfps/cpp/fftw_interface.hpp
+++ b/bfps/cpp/fftw_interface.hpp
@@ -26,6 +26,8 @@
 #define FFTW_INTERFACE_HPP
 
 #include <fftw3-mpi.h>
+#include <map>
+#include <string>
 
 #ifdef USE_FFTWESTIMATE
 #define DEFAULT_FFTW_FLAG FFTW_ESTIMATE
diff --git a/bfps/cpp/fftw_tools.cpp b/bfps/cpp/fftw_tools.cpp
index 61e03d292f81aed1fa4b2dfcab880fb7105b676e..9f6e9bfd5e22fc744bcbf01a3b7d96fb862538ad 100644
--- a/bfps/cpp/fftw_tools.cpp
+++ b/bfps/cpp/fftw_tools.cpp
@@ -31,6 +31,13 @@
 
 #define NDEBUG
 
+std::map<std::string, unsigned> fftw_planner_string_to_flag = {
+    {"FFTW_ESTIMATE", FFTW_ESTIMATE},
+    {"FFTW_MEASURE", FFTW_MEASURE},
+    {"FFTW_PATIENT", FFTW_PATIENT},
+    {"parameter does not exist", DEFAULT_FFTW_FLAG},
+};
+
 template <class rnumber>
 int clip_zero_padding(
         field_descriptor<rnumber> *f,
diff --git a/bfps/cpp/fftw_tools.hpp b/bfps/cpp/fftw_tools.hpp
index d0f3dbf30df3ee95f3d7934f0dd7fca633858b44..f4480714648ead1dfa8a03272f0a00330eceba83 100644
--- a/bfps/cpp/fftw_tools.hpp
+++ b/bfps/cpp/fftw_tools.hpp
@@ -34,6 +34,8 @@
 
 extern int myrank, nprocs;
 
+extern std::map<std::string, unsigned> fftw_planner_string_to_flag;
+
 /* given two arrays of the same dimension, we do a simple resize in
  * Fourier space: either chop off high modes, or pad with zeros.
  * the arrays are assumed to use 3D mpi fftw layout.
diff --git a/bfps/cpp/full_code/NSVE.cpp b/bfps/cpp/full_code/NSVE.cpp
index d9cb72a220aaf6cb124cb37f827373f9a44b03ac..74593b3768a787a5dc2bc54001d12a826d3a54e9 100644
--- a/bfps/cpp/full_code/NSVE.cpp
+++ b/bfps/cpp/full_code/NSVE.cpp
@@ -2,6 +2,7 @@
 #include <cmath>
 #include "NSVE.hpp"
 #include "scope_timer.hpp"
+#include "fftw_tools.hpp"
 
 
 template <typename rnumber>
@@ -37,11 +38,11 @@ int NSVE<rnumber>::initialize(void)
             simname.c_str(),
             nx, ny, nz,
             dkx, dky, dkz,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
     this->tmp_vec_field = new field<rnumber, FFTW, THREE>(
             nx, ny, nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
 
 
     this->fs->checkpoints_per_file = checkpoints_per_file;
@@ -161,6 +162,7 @@ int NSVE<rnumber>::read_parameters(void)
     this->max_vorticity_estimate = hdf5_tools::read_value<double>(parameter_file, "parameters/max_vorticity_estimate");
     std::string tmp = hdf5_tools::read_string(parameter_file, "parameters/forcing_type");
     snprintf(this->forcing_type, 511, "%s", tmp.c_str());
+    this->fftw_plan_type = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_type");
     H5Fclose(parameter_file);
     return EXIT_SUCCESS;
 }
diff --git a/bfps/cpp/full_code/NSVE.hpp b/bfps/cpp/full_code/NSVE.hpp
index 062627fd1cc9513bbd29a14199e05d3a084c0851..c3ad7a0a8b9c75990712dfb0198a4824295285b2 100644
--- a/bfps/cpp/full_code/NSVE.hpp
+++ b/bfps/cpp/full_code/NSVE.hpp
@@ -53,6 +53,7 @@ class NSVE: public direct_numerical_simulation
         double max_velocity_estimate;
         double max_vorticity_estimate;
         double nu;
+        std::string fftw_plan_type;
 
         /* other stuff */
         vorticity_equation<rnumber, FFTW> *fs;
diff --git a/bfps/cpp/full_code/NSVE_field_stats.cpp b/bfps/cpp/full_code/NSVE_field_stats.cpp
index 15980a20141a563be08ad0b28a3190b3e9e1c17c..142c51e7718f5a97170958a127e353a5d213e6e4 100644
--- a/bfps/cpp/full_code/NSVE_field_stats.cpp
+++ b/bfps/cpp/full_code/NSVE_field_stats.cpp
@@ -1,6 +1,7 @@
 #include <string>
 #include <cmath>
 #include "NSVE_field_stats.hpp"
+#include "fftw_tools.hpp"
 #include "scope_timer.hpp"
 
 
@@ -12,7 +13,7 @@ int NSVE_field_stats<rnumber>::initialize(void)
     this->vorticity = new field<rnumber, FFTW, THREE>(
             nx, ny, nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
     this->vorticity->real_space_representation = false;
     hid_t parameter_file = H5Fopen(
             (this->simname + std::string(".h5")).c_str(),
@@ -43,6 +44,7 @@ int NSVE_field_stats<rnumber>::initialize(void)
                 this->vorticity->clayout->starts,
                 this->vorticity->clayout->comm);
     }
+    this->fftw_plan_type = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_type");
     H5Fclose(parameter_file);
     return EXIT_SUCCESS;
 }
diff --git a/bfps/cpp/full_code/NSVE_field_stats.hpp b/bfps/cpp/full_code/NSVE_field_stats.hpp
index d544c0c7d5f4c75559e63ea3e59bf9457d4730c5..ae519fc79bb839ddbda0bc3aa3a787ba3547c84d 100644
--- a/bfps/cpp/full_code/NSVE_field_stats.hpp
+++ b/bfps/cpp/full_code/NSVE_field_stats.hpp
@@ -42,6 +42,8 @@ class NSVE_field_stats: public postprocess
     private:
         field_binary_IO<rnumber, COMPLEX, THREE> *bin_IO;
     public:
+        std::string fftw_plan_type;
+
         field<rnumber, FFTW, THREE> *vorticity;
 
         NSVE_field_stats(
diff --git a/bfps/cpp/full_code/field_output_test.cpp b/bfps/cpp/full_code/field_output_test.cpp
index 30df4e7512bec3c08325fe156b21789f80882f54..724060992ad5bba14adbe871c98067b4e57728ab 100644
--- a/bfps/cpp/full_code/field_output_test.cpp
+++ b/bfps/cpp/full_code/field_output_test.cpp
@@ -36,7 +36,7 @@ int field_output_test<rnumber>::do_work(void)
     field<rnumber, FFTW, ONE> *scal_field = new field<rnumber, FFTW, ONE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     std::default_random_engine rgen;
     std::normal_distribution<rnumber> rdist;
     rgen.seed(1);
diff --git a/bfps/cpp/full_code/field_test.cpp b/bfps/cpp/full_code/field_test.cpp
index 1627bc4088581468ebedab585db7ca9d6519d3a3..a9d531bcaf939b8b46ae539c57c00ae9b121c0a4 100644
--- a/bfps/cpp/full_code/field_test.cpp
+++ b/bfps/cpp/full_code/field_test.cpp
@@ -44,11 +44,11 @@ int field_test<rnumber>::do_work(void)
     field<rnumber, FFTW, ONE> *scal_field = new field<rnumber, FFTW, ONE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     field<rnumber, FFTW, ONE> *scal_field_alt = new field<rnumber, FFTW, ONE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     std::default_random_engine rgen;
     std::normal_distribution<rnumber> rdist;
     rgen.seed(2);
diff --git a/bfps/cpp/full_code/filter_test.cpp b/bfps/cpp/full_code/filter_test.cpp
index 4db13843fa8f69db77f8a15cbd0563feb087dfcf..6dbd05a940ff88623cd10802376497148bda5549 100644
--- a/bfps/cpp/full_code/filter_test.cpp
+++ b/bfps/cpp/full_code/filter_test.cpp
@@ -12,7 +12,7 @@ int filter_test<rnumber>::initialize(void)
     this->scal_field = new field<rnumber, FFTW, ONE>(
             nx, ny, nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     this->kk = new kspace<FFTW, SMOOTH>(
             this->scal_field->clayout, this->dkx, this->dky, this->dkz);
 
diff --git a/bfps/cpp/full_code/joint_acc_vel_stats.cpp b/bfps/cpp/full_code/joint_acc_vel_stats.cpp
index 1c28527e5986e12a5d66151a5623194e4ffab3aa..fff2e2f5f4e83c3e89b742a18f2e3feaeb1466d1 100644
--- a/bfps/cpp/full_code/joint_acc_vel_stats.cpp
+++ b/bfps/cpp/full_code/joint_acc_vel_stats.cpp
@@ -110,7 +110,7 @@ int joint_acc_vel_stats<rnumber>::work_on_current_iteration(void)
     vel = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            this->vorticity->fftw_plan_rigor);
     invert_curl(kk, this->ve->cvorticity, vel);
     vel->ift();
 
diff --git a/bfps/cpp/full_code/native_binary_to_hdf5.cpp b/bfps/cpp/full_code/native_binary_to_hdf5.cpp
index fb5a39c2af8a88a158df679ad27ce0f08fab37f8..fe8e1c41a937e49db264aaca41c82df2503e4c99 100644
--- a/bfps/cpp/full_code/native_binary_to_hdf5.cpp
+++ b/bfps/cpp/full_code/native_binary_to_hdf5.cpp
@@ -12,7 +12,7 @@ int native_binary_to_hdf5<rnumber>::initialize(void)
     this->vec_field = new field<rnumber, FFTW, THREE>(
             nx, ny, nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     this->vec_field->real_space_representation = false;
     this->bin_IO = new field_binary_IO<rnumber, COMPLEX, THREE>(
             this->vec_field->clayout->sizes,
diff --git a/bfps/cpp/full_code/symmetrize_test.cpp b/bfps/cpp/full_code/symmetrize_test.cpp
index 821161da846a323721c07ed47a7c66d9efea78f0..45225fcb8d70324f4c5a68054ba62cb5d0123217 100644
--- a/bfps/cpp/full_code/symmetrize_test.cpp
+++ b/bfps/cpp/full_code/symmetrize_test.cpp
@@ -2,6 +2,7 @@
 #include <cmath>
 #include <random>
 #include "symmetrize_test.hpp"
+#include "fftw_tools.hpp"
 #include "scope_timer.hpp"
 
 
@@ -31,6 +32,7 @@ int symmetrize_test<rnumber>::read_parameters()
             H5P_DEFAULT);
     this->random_seed = hdf5_tools::read_value<int>(
             parameter_file, "/parameters/random_seed");
+    this->fftw_plan_type = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_type");
     H5Fclose(parameter_file);
     return EXIT_SUCCESS;
 }
@@ -44,13 +46,13 @@ int symmetrize_test<rnumber>::do_work(void)
     field<rnumber, FFTW, THREE> *test_field0 = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
     DEBUG_MSG("finished allocating field0\n");
     DEBUG_MSG("about to allocate field1\n");
     field<rnumber, FFTW, THREE> *test_field1 = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
     DEBUG_MSG("finished allocating field1\n");
     std::default_random_engine rgen;
     std::normal_distribution<rnumber> rdist;
diff --git a/bfps/cpp/full_code/symmetrize_test.hpp b/bfps/cpp/full_code/symmetrize_test.hpp
index d3fbbaeb0728959234ad53859d3940c8ef00ebd9..f674d3650666c7021259491c7635ecaed60d4e3c 100644
--- a/bfps/cpp/full_code/symmetrize_test.hpp
+++ b/bfps/cpp/full_code/symmetrize_test.hpp
@@ -42,6 +42,7 @@ template <typename rnumber>
 class symmetrize_test: public test
 {
     public:
+        std::string fftw_plan_type;
         int random_seed;
 
         symmetrize_test(
diff --git a/bfps/cpp/full_code/test_interpolation.cpp b/bfps/cpp/full_code/test_interpolation.cpp
index 5ef11de44b6f6a36ab6827facae3c637b702bc58..2acd3c27426a4cdd2af244dfaa6b1779b2871f61 100644
--- a/bfps/cpp/full_code/test_interpolation.cpp
+++ b/bfps/cpp/full_code/test_interpolation.cpp
@@ -30,18 +30,18 @@ int test_interpolation<rnumber>::initialize(void)
     this->vorticity = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     this->vorticity->real_space_representation = false;
 
     this->velocity = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
 
     this->nabla_u = new field<rnumber, FFTW, THREExTHREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
 
     this->kk = new kspace<FFTW, SMOOTH>(
             this->vorticity->clayout, this->dkx, this->dky, this->dkz);
diff --git a/bfps/cpp/hdf5_tools.cpp b/bfps/cpp/hdf5_tools.cpp
index c2ef6aaebf2538de5575627baf6403d39e749d2a..25acaf21b662501948616236ee1d441df2527ad3 100644
--- a/bfps/cpp/hdf5_tools.cpp
+++ b/bfps/cpp/hdf5_tools.cpp
@@ -208,17 +208,26 @@ std::string hdf5_tools::read_string(
         const hid_t group,
         const std::string dset_name)
 {
-    hid_t dset = H5Dopen(group, dset_name.c_str(), H5P_DEFAULT);
-    hid_t space = H5Dget_space(dset);
-    hid_t memtype = H5Dget_type(dset);
-    char *string_data = (char*)malloc(256);
-    H5Dread(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &string_data);
-    std::string std_string_data = std::string(string_data);
-    free(string_data);
-    H5Sclose(space);
-    H5Tclose(memtype);
-    H5Dclose(dset);
-    return std_string_data;
+    if (H5Lexists(group, dset_name.c_str(), H5P_DEFAULT))
+    {
+        hid_t dset = H5Dopen(group, dset_name.c_str(), H5P_DEFAULT);
+        hid_t space = H5Dget_space(dset);
+        hid_t memtype = H5Dget_type(dset);
+        char *string_data = (char*)malloc(256);
+        H5Dread(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &string_data);
+        std::string std_string_data = std::string(string_data);
+        free(string_data);
+        H5Sclose(space);
+        H5Tclose(memtype);
+        H5Dclose(dset);
+        return std_string_data;
+    }
+    else
+    {
+        DEBUG_MSG("attempted to read dataset %s which does not exist.\n",
+                dset_name.c_str());
+        return std::string("parameter does not exist");
+    }
 }
 
 template
diff --git a/setup.py b/setup.py
index 110f18d5eb16ba39decbc33cce16aa4fccef4473..afb25f70858889421c88ca53389fad3543c7fbc8 100644
--- a/setup.py
+++ b/setup.py
@@ -273,7 +273,7 @@ class CompileLibCommand(distutils.cmd.Command):
 
 def get_file_dependency_list(src_file):
     p = subprocess.Popen(
-            ['g++', '-Ibfps/cpp', '-MM', 'bfps/cpp/' + src_file + '.cpp'],
+            ['g++', '-std=c++11', '-Ibfps/cpp', '-MM', 'bfps/cpp/' + src_file + '.cpp'],
             stdout = subprocess.PIPE)
     out, err = p.communicate()
     p.terminate()