diff --git a/bfps/cpp/field.cpp b/bfps/cpp/field.cpp
index d5696d56cce92fac5d78ea80120e400677f1e38b..ba7fa5e4e2f1649ee31e776561ba1dc5c0af4889 100644
--- a/bfps/cpp/field.cpp
+++ b/bfps/cpp/field.cpp
@@ -612,6 +612,138 @@ int field<rnumber, be, fc>::write_0slice(
     return EXIT_SUCCESS;
 }
 
+template <typename rnumber,
+          field_backend be,
+          field_components fc>
+int field<rnumber, be, fc>::write_filtered(
+        const std::string fname,
+        const std::string field_name,
+        const int iteration,
+        int nx)
+{
+    /* file dataset has same dimensions as field */
+    TIMEZONE("field::write_filtered");
+    // only works in Fourier representation
+    assert(!this->real_space_representation);
+    assert(nx <= this->rlayout->sizes[2]);
+    hid_t file_id, dset_id, plist_id;
+    dset_id = H5I_BADID;
+    std::string dset_name = (
+            "/" + field_name +
+            "/complex" +
+            "/" + std::to_string(iteration));
+
+    /* open/create file */
+    plist_id = H5Pcreate(H5P_FILE_ACCESS);
+    H5Pset_fapl_mpio(plist_id, this->comm, MPI_INFO_NULL);
+    bool file_exists = false;
+    struct stat file_buffer;
+    file_exists = (stat(fname.c_str(), &file_buffer) == 0);
+    if (file_exists)
+        file_id = H5Fopen(fname.c_str(), H5F_ACC_RDWR, plist_id);
+    else
+        file_id = H5Fcreate(fname.c_str(), H5F_ACC_EXCL, H5P_DEFAULT, plist_id);
+    assert(file_id >= 0);
+    H5Pclose(plist_id);
+
+    /* generic space initialization */
+    hid_t fspace, mspace;
+    hsize_t count[ndim(fc)], offset[ndim(fc)], dims[ndim(fc)], fdims[ndim(fc)];
+    hsize_t memoffset[ndim(fc)], memshape[ndim(fc)];
+
+    // set up dimensions
+    for (unsigned int i=3; i<ndim(fc); i++)
+    {
+        count [i] = this->clayout->subsizes[i];
+        offset[i] = this->clayout->starts[i];
+        dims  [i] = this->clayout->sizes[i];
+        memshape [i] = count[i];
+        memoffset[i] = 0;
+    }
+    // set up smaller dimensions
+    unsigned int ii = 0;
+    count [ii] = this->clayout->subsizes[ii];
+    offset[ii] = this->clayout->starts[ii];
+    dims  [ii] = this->clayout->sizes[ii];
+    memshape [ii] = count[ii];
+    memoffset[ii] = 0;
+    ii = 1;
+    count [ii] = this->clayout->subsizes[ii];
+    offset[ii] = this->clayout->starts[ii];
+    dims  [ii] = this->clayout->sizes[ii];
+    memshape [ii] = count[ii];
+    memoffset[ii] = 0;
+    ii = 2;
+    count [ii] = nx/2+1;
+    offset[ii] = 0;
+    dims  [ii] = nx/2+1;
+    memshape [ii] = this->clayout->subsizes[ii];
+    memoffset[ii] = 0;
+
+    mspace = H5Screate_simple(ndim(fc), memshape, NULL);
+    H5Sselect_hyperslab(mspace, H5S_SELECT_SET, memoffset, NULL, count, NULL);
+
+    /* open/create data set */
+    if (!H5Lexists(file_id, field_name.c_str(), H5P_DEFAULT))
+    {
+        hid_t gid_tmp = H5Gcreate(
+                file_id, field_name.c_str(),
+                H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+        H5Gclose(gid_tmp);
+    }
+    if (!H5Lexists(file_id, (field_name + "/complex").c_str(), H5P_DEFAULT))
+    {
+        hid_t gid_tmp = H5Gcreate(
+                file_id, ("/" + field_name + "/complex").c_str(),
+                H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+        H5Gclose(gid_tmp);
+    }
+    if (H5Lexists(file_id, dset_name.c_str(), H5P_DEFAULT))
+    {
+        dset_id = H5Dopen(file_id, dset_name.c_str(), H5P_DEFAULT);
+        fspace = H5Dget_space(dset_id);
+    }
+    else
+    {
+        fspace = H5Screate_simple(
+                ndim(fc),
+                dims,
+                NULL);
+        /* chunking needs to go in here */
+        dset_id = H5Dcreate(
+                file_id,
+                dset_name.c_str(),
+                this->cnumber_H5T,
+                fspace,
+                H5P_DEFAULT,
+                H5P_DEFAULT,
+                H5P_DEFAULT);
+    }
+    /* both dset_id and fspace now have sane values */
+
+    /* check file space */
+    int ndims_fspace = H5Sget_simple_extent_dims(fspace, fdims, NULL);
+    assert(((unsigned int)(ndims_fspace)) == ndim(fc));
+
+    for (unsigned int i=0; i<ndim(fc); i++)
+    {
+        offset[i] = this->clayout->starts[i];
+        assert(dims[i] == fdims[i]);
+    }
+    H5Sselect_hyperslab(fspace, H5S_SELECT_SET, offset, NULL, count, NULL);
+    H5Dwrite(dset_id, this->cnumber_H5T, mspace, fspace, H5P_DEFAULT, this->data);
+    H5Sclose(mspace);
+
+
+    /* close file data space */
+    H5Sclose(fspace);
+    /* close data set */
+    H5Dclose(dset_id);
+    /* close file */
+    H5Fclose(file_id);
+    return EXIT_SUCCESS;
+}
+
 
 template <typename rnumber,
           field_backend be,
diff --git a/bfps/cpp/field.hpp b/bfps/cpp/field.hpp
index a52d2a56f2527070568e54cf971b5d072520b8a3..861246a4b66f44b9813581feaddccb04f740be51 100644
--- a/bfps/cpp/field.hpp
+++ b/bfps/cpp/field.hpp
@@ -103,6 +103,11 @@ class field
                 const hid_t group,
                 const std::string field_name,
                 const int iteration);
+        int write_filtered(
+                const std::string fname,
+                const std::string field_name,
+                const int iteration,
+                const int nx);
 
         int io_binary(
                 const std::string fname,