diff --git a/bfps/cpp/field.cpp b/bfps/cpp/field.cpp
index d5696d56cce92fac5d78ea80120e400677f1e38b..e64a1b95a365af3adfe3bb92aab252f83e2fa27d 100644
--- a/bfps/cpp/field.cpp
+++ b/bfps/cpp/field.cpp
@@ -612,6 +612,197 @@ 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,
+        int ny,
+        int nz)
+{
+    /* file dataset has same dimensions as field */
+    TIMEZONE("field::write_filtered");
+    // only works in Fourier representation
+    assert(!this->real_space_representation);
+    assert(hsize_t(nx) <= this->rlayout->sizes[2]);
+    assert(hsize_t(ny) <= this->rlayout->sizes[1]);
+    assert(hsize_t(nz) <= this->rlayout->sizes[0]);
+    // current algorithm only works for more than one process
+    assert(this->nprocs >= 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;
+    }
+    // these are dimensions of dataset, needed
+    // to create dataset
+    //dims[0] = nz;
+    dims[0] = ny;
+    dims[1] = nz;
+    dims[2] = nx/2+1;
+
+    /* 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);
+    }
+    /* 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++)
+    {
+        assert(dims[i] == fdims[i]);
+    }
+    /* both dset_id and fspace now have sane values */
+
+    /// set up counts and offsets
+    /// x is easy, since only positive modes are present
+    count [2] = nx/2+1;
+    offset[2] = 0;
+    memshape [2] = this->clayout->subsizes[2];
+    memoffset[2] = 0;
+
+    /// three options for y:
+    /// this->starts[0] <= ny/2
+    /// ny / 2 < this->starts[0] +this->clayout->subsizes[0] < this->sizes[0] - ny/2
+    /// this->starts[0] >= this->sizes[0] - ny/2
+    /// we don't care about saving the ny/2 mode, because of symmetry
+    hsize_t y0 = this->clayout->starts[0];
+    hsize_t y1 = this->clayout->starts[0] + this->clayout->subsizes[0];
+    memshape[0] = this->clayout->subsizes[0];
+    if (y1 <= ny/2)
+    {
+        count[0] = this->clayout->subsizes[0];
+        offset[0] = y0;
+        memoffset[0] = 0;
+    }
+    else
+    {
+        if (y0 < ny/2)
+        {
+            count[0] = ny/2 - y0;
+            offset[0] = y0;
+            memoffset[0] = 0;
+        }
+        else
+        {
+            if (y1 <= this->clayout->sizes[0] - ny/2 + 1)
+            { // y0 < y1 therefore y0 <= this->clayout->sizes[0] - ny/2
+                count[0] = 0;
+                offset[0] = ny/2;
+                memoffset[0] = 0;
+            }
+            else
+            {
+                if (y0 <= this->clayout->sizes[0] - ny/2)
+                {
+                    count[0] = y1 - (this->clayout->sizes[0] - ny/2);
+                    offset[0] = ny/2;
+                    memoffset[0] = this->clayout->subsizes[0] - count[0];
+                }
+                else
+                {
+                    count[0] = this->clayout->subsizes[0];
+                    offset[0] = y0;
+                    memoffset[0] = 0;
+                }
+            }
+        }
+    }
+    DEBUG_MSG("count[0] = %ld, offset[0] = %ld\n",
+            count[0], offset[0]);
+    /// for z, we need to take into account that there are
+    /// both positive and negative modes
+    for (int cz = 0; cz < 2; cz++)
+    {
+        count [1] = nz/2;
+        offset[1] = cz*nz/2;
+        memshape [1] = this->clayout->sizes[1];
+        memoffset[1] = cz*(this->clayout->sizes[1] - nz/2);
+        DEBUG_MSG("cz = %d, count[1] + offset[1] = %ld\n",
+                cz, count[1] + offset[1]);
+
+        //now write data
+        mspace = H5Screate_simple(ndim(fc), memshape, NULL);
+        H5Sselect_hyperslab(mspace, H5S_SELECT_SET, memoffset, NULL, count, NULL);
+        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..fe6f8975e63ad1acd766b26baa84aca20ef92cc2 100644
--- a/bfps/cpp/field.hpp
+++ b/bfps/cpp/field.hpp
@@ -103,6 +103,13 @@ 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,
+                const int ny,
+                const int nz);
 
         int io_binary(
                 const std::string fname,